尝试一下 编译时注解的方法。
hongyang运行时注解
为什么要写这一篇博客啦?
因为我们项目中用到了EvenBus 这个框架了。 EvenBus 在3.0的时候已经采用编译时注解了,从那一点可以看出来啦
那我们就看图说话吧。
当我们android studio 编译的时候就会把注解获取到,从而进行处理。
当然啦,我们这一篇不说Eventbus。
需求:
获取对象
———– 其中的属性,以及修饰符
或者属性
————-它的所包含类的名称,以及修饰符
最后: 将这些信息存入某个地方。
例如:
-----------------Article -----------------------
@Seriable
public class Article {
private String title;
private String content;
}
-----------------UserBean -----------------------
public class UserBean {
@Seriable
private String username;
@Seriable
private String password;
private String three;
private String four;
}
效果:
-----------------Article----------------------
{class:"com.example.blogtest.Article", fields: { title:"java.lang.String", content:"java.lang.String" }
}
-------------------UserBean----------------------
{class:"com.example.blogtest.UserBean", fields: { username:"java.lang.String", password:"java.lang.String" }
}
我们需要获取到标识注解的信息。
Seriable
我们先看到这个类 这个就是我们自定义的注解名称
是这样的:
@Target({ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.CLASS)
public @interface Seriable {
}
我们其实可以理解 注解就是一个表示的作用。
BeanProcessor
作用:就是获取到被注解所有信息。进行分析记录。然后存储记录。
step1:
创建一个class类 并且 继承 AbstractProcessor。
这样:
public class BeanProcessor extends AbstractProcessor
step2:
让这个类知道 我们要分析哪一个注解类型。
// @SupportedAnnotationTypes的值为当前类支持的注解的完整类路径,支持通配符。
@SupportedAnnotationTypes("com.tlp.utils.ioc.annotation.Seriable")
public class BeanProcessor extends AbstractProcessor {
step3:
处理过程(process)
注释已经很清楚啦,就不再解释了。
// 获得被该注解声明的元素
Set<? extends Element> elements = roundEnv
.getElementsAnnotatedWith(Seriable.class);
// 声明类元素
TypeElement classElement = null;
// 声明一个存放成员变量的列表
List<VariableElement> fields = null;
// 存放二者 VariableElement== 表示一个字段、enum 常量、方法或构造方法参数、局部变量或异常参数。
Map<String, List<VariableElement>> maps = new HashMap<String, List<VariableElement>>();
// 遍历
for (Element ele : elements) {
// 判断该元素是否为类。
if (ele.getKind() == ElementKind.CLASS) {
classElement = (TypeElement) ele;
// 返回此类型元素的完全限定名称。 getQualifiedName
maps.put(classElement.getQualifiedName().toString(),
fields = new ArrayList<VariableElement>());
// 判断该元素是否成员变量
} else if (ele.getKind() == ElementKind.FIELD) {
VariableElement varEle = (VariableElement) ele;
// 获取该元素封装类型
TypeElement enclosingElement = (TypeElement) varEle
.getEnclosingElement();
// 拿到key
String key = enclosingElement.getQualifiedName().toString();
fields = maps.get(key);
if (fields == null) {
maps.put(key, fields = new ArrayList<VariableElement>());
}
fields.add(varEle);
}
}
// 获取 声明那些 只是声明key的类,其中的属性
for (String key : maps.keySet()) {
if (maps.get(key).size() == 0) {
TypeElement typeElement = elementUtils.getTypeElement(key);
// 返回类型元素的所有成员,不管是继承的还是直接声明的。
List<? extends Element> allMembers = elementUtils
.getAllMembers(typeElement);
if (allMembers.size() > 0) {
maps.get(key).addAll(ElementFilter.fieldsIn(allMembers));
}
}
}
generateCodes(maps);
return true;
step4:
配置 BeanProcessor 。
我引用一段话
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
//处理方法。
return true; //返回为true;
}
指定 获取注解类型。
@SupportedAnnotationTypes(“com.tlp.utils.ioc.annotation.Seriable”)
通过 Eclipse 打包成为 jar包—–具体可以看到
http://blog.csdn.net/lmj623565791/article/details/43452969 jar 使用方式。
Demo 下载。
Demo下载