一、基本知识:
参考文章:
1、注解--注解处理器
5、自定义注解之编译时注解(RetentionPolicy.CLASS)系列
二、动态代理
Android 动态代理以及利用动态代理实现 ServiceHook
三、RUNTIME注解+动态代理:根据Interface动态创建对象和动态解析注解
Android开发中无处不在的设计模式——动态代理模式
四、自定义运行时注解不需要实现AbstractProcessor接口,运行的时候解析, 原理和三中一样。
1.Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (上)
2.Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (下)
五、注解在aspecjt中自定义切入点 利用Aspectj注入代码,无侵入实现各种功能,比如一个注解请求权限
注解的注解,进一步限制了注解的使用范围。这篇文章之所以没有直接按照注解来查找,
而是遍历method,再获取method的上的所有注解,是为了处理一个method上的多个注解,比如有多个事件类型(click longclick itemclick)都调用该方法,如果按照注解来查找,那click longclick itemclick
总共有3个注解,分别执行三次相同的逻辑,不太好。
基本理解:
Annotation接口:Java使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口,
java.lang.reflect.AnnotatedElement接口:接口代表程序中可以接受注解的程序元素。该接口主要有如下几个实现类:
Class:类定义
Constructor:构造器定义
Field:累的成员变量定义
Method:类的方法定义
Package:类的包定义
所以获取到某个class的这几个对象,就可以获取对应元素上的注解。
自定义注解和定义接口差不多,区别有:
1.在interface前加上@
2.接口方法可以设置默认值,如public String name() default "";
一个注解的注解处理器,以Java代码(或者编译过的字节码)作为输入,生成文件(通常是.java文件)作为输出,
单不能修改已经存在的Java类。
注解处理器是运行它自己的虚拟机JVM中。javac启动一个完整Java虚拟机来运行注解处理器。
这对你意味着什么?你可以使用任何你在其他java应用中使用的的东西。使用guava。如果你愿意,
你可以使用依赖注入工具,例如dagger或者其他你想要的类库。
注解处理器的实例只创建一次,但是process方法会多次执行,因为新生产的java文件也可能包含注解,
所以在process方法开始需要判断是否有需判断下
Set<? extends Element> activities = roundEnv.getElementsAnnotatedWith(Router.class);
if(activities.size() == 0) {
return true;//退出处理
}
打包注解处理器到.jar文件。就像其他.jar文件一样,你打包你的注解处理器到此文件中。并且,
在你的jar中,你需要打包一个特定的文件javax.annotation.processing.Processor
到META-INF/services路径下,内容是,注解处理器的合法的全名列表,每一个元素换行分割。
注解处理器最好和注解分成两个库,因为注解处理器只是编译时使用,不用最终打入到发布包中,
但是注解是会被导入到最终的包中,不管Retention是source还是class还是runtime。
使用场景:在一些重复性的工作或者有规律性的工作时,都可以考虑用注解来处理。注解不只是做标记,
要充分发挥注解参数的作用。
Java 的动态代理涉及到两个类:InvocationHandler 接口和 Proxy 类
在运行期系统中,遵循 Java 编译系统组织 .class 文件的格式和结构,生成相应的二进制数据,
然后再把这个二进制数据转换成对应的类,这样就可以在运行中动态生成一个我们想要的类了。
动态代理工作的基本模式就是将自己方法功能的实现交给 InvocationHandler 角色,外界对 Proxy
角色中每一个方法的调用,Proxy 角色都会交给 InvocationHandler 来处理,而 InvocationHandler
则调用 RealSubject 的方法。
动态代理使用场景总结:
1.Proxy类的代码量被固定下来,不会因为业务的逐渐庞大而庞大;
2.可以实现AOP编程,实际上静态代理也可以实现,总的来说,AOP可以算作是代理模式的一个典型应用;
3.解耦,通过参数就可以判断真实类,不需要事先实例化,更加灵活多变。
4.hook系统API,在方法前后添加想要的功能,或者直接替换原方法的执行
5.根据接口随意生成业务需要的代理类
6.减少重复代码量,保持代码简介。如Retrofit,结合注解,让网络请求代码很简介