反射和AOP练习笔记

练习通过反射获取注解上的参数

TestTag

  定义一个注解并设置注解参数类型为一个String[]。

package tag;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestTag {
    String[] value();
}

FirstTest

  在这个类中使用@TestTag注解,并设置几个参数。

package funImpl;
import tag.TestTag;

public class FirstTest{

    @TestTag(value = {"这是", "注解", "中", "传的参数"})
    public void tag() {
        System.out.println("tag方法");
    }
}

main

  通过反射获取FirstTest的Class对象,并将 @TestTag中的参数打印出来:

import funImpl.FirstTest;
import tag.TestTag;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class main {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //反射
        Class testClass= Class.forName(FirstTest.class.getName());
        FirstTest firstTest = (FirstTest) testClass.newInstance();
        //获取方法
        Method[] methods = testClass.getDeclaredMethods();
        //遍历方法
        Arrays.stream(methods)
                .filter(m -> m.getName().equals("tag"))//获取tag方法对象
                .forEach(m -> {//打印注解里的值
                    try {
                        m.invoke(firstTest);//调用tag方法
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                    TestTag annotation = m.getAnnotation(TestTag.class);
                    Arrays.stream(annotation.value()).forEach(System.err::println);
                });
    }
}

  结果如下。
在这里插入图片描述

练习AspectJX

package com.lyan.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
  String value();
}

  然后创建一个切面类,当执行完onCreate()方法后,修改一下界面的标题。

package com.lyan.test;

import android.support.v7.app.AppCompatActivity;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
//(@Around ProceedingJoinPoint joinPoint.proceed())
//(@Before @After JoinPoint)
@Aspect
public class TestAspect {
  /**
   * 匹配任意路径下的xxActivity的onCreate方法
   */
  @Pointcut("execution(@com.lyan.test.Test void *..*Activity.onCreate(android.os.Bundle))")
  public void cutPoint() {
  }
  /**
   * 匹配AppCompatActivity这个类型
   */
  @Pointcut("target(android.support.v7.app.AppCompatActivity)")
  public void cutTarget() {
  }

  @After("cutPoint() && cutTarget()")
  public void afterActivityOnCreate(JoinPoint joinPoint){
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Test annotation = signature.getMethod().getAnnotation(Test.class);
    ((AppCompatActivity) joinPoint.getTarget()).setTitle(annotation.value());
  }
	
}

  最后在MainActivity的onCreate()方法上添加@Test注解。

package com.lyan.test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

  @Test("改标题")
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
}

  运行效果如图
在这里插入图片描述

发布了41 篇原创文章 · 获赞 18 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/baidu_32377671/article/details/86710854
今日推荐