深入解析APT技术&IOC核心思想
APT(Annotation Process Tool),是一种在代码编译时处理注解,按照一定的规则,生成相应的java文件,多用于对自定义注解的处理,目前比较流行的Dagger2, ButterKnife, EventBus3都是采用APT技术,对运行时的性能影响很小。我们通过自定义注解的方式,
例如:
我们要生成如下代码
1:创建一个注解
2:使用注解
3:创建 动态生成代码的类
==============================
需要依赖 :
// 3.4 +
// annotationProcessor "com.google.auto.service:auto-service:1.0-rc4"
annotationProcessor'com.google.auto.service:auto-service:1.0-rc4'
compileOnly'com.google.auto.service:auto-service:1.0-rc3'
// 3.4 -
// implementation 'com.google.auto.service:auto-service:1.0-rc3'
implementation'com.squareup:javapoet:1.13.0'
/**
* 处理注解中的类 会在代码中 找到 专门标记activity 的注解 得到标记的类 成成activityutils 的 类
*/
@AutoService(Processor.class)// 注册为 注解解析类
//使用生明 这个注解处理器 要找是那个注解
//@SupportedAnnotationTypes({"com.example.annotation.BindPath"})
public class AnnotationCompilserextends AbstractProcessor {
@AutoService(Processor.class)// 注册为 注解解析类
//@SupportedAnnotationTypes({"com.example.annotation.BindPath"}) //使用生明 这个注解处理器 要找是那个注解
public class AnnotationCompilserextends AbstractProcessor {
/**
* 处理注解中的类 会在代码中 找到 专门标记activity 的注解 得到标记的类 成成activityutils 的 类
*/
@AutoService(Processor.class)// 注册为 注解解析类
//@SupportedAnnotationTypes({"com.example.annotation.BindPath"}) //使用生明 这个注解处理器 要找是那个注解
public class AnnotationCompilserextends AbstractProcessor {
private Filerfiler; // 生成java 的 工具
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
filer = processingEnv.getFiler();
}
/**
* 支持java的版本
*
* @return
*/
@Override
public SourceVersiongetSupportedSourceVersion() {
return processingEnv.getSourceVersion();
}
/**
* 生明 这个注解处理器 要找是那个注解
*
* @return
*/
@Override
public SetgetSupportedAnnotationTypes() {
Set types =new HashSet<>();
types.add(BindPath.class.getCanonicalName());
return types;
}
/**
* 这个是 核心方法 去程序中 找标记了 的内容
*
* @param annotations
* @param roundEnv
* @return
*/
@Override
public boolean process(Set annotations, RoundEnvironment roundEnv) {
// 获取类 节点的集合 类名 方法名 变量名
Set elementsAnnotatedWith = roundEnv.getElementsAnnotatedWith(BindPath.class);
Map map =new HashMap<>();
System.out.println("----------------------66666" );
for (Element element : elementsAnnotatedWith) {
// TypeElement 类节点
// ExecutableElement 方法节点
// VariableElement 变量节点
// PackageElement 包节点
// 获取类节点
TypeElement element1 = (TypeElement) element;
// 获取注解value
String key = element1.getAnnotation(BindPath.class).value();
// 获取包名和类名
String activitynae = element1.getQualifiedName().toString();
map.put(key, activitynae +".class");
}
// 生成文件
if (map.size() >0) {
// 生成我们的工具
createClass(map);
}else{
System.out.println("----------------------66666" );
// com.example.router.Arouter.gerInstance().addactivity("main/main",MemberActivity.class);
map.put("66/66","MemberActivity.class");
}
return false;
}
private void createClass(Map map) {
try {
// 创建我们需要的方法
MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder("putActity").
addModifiers(Modifier.PUBLIC).
returns(void.class);
// 创建方法里面 需要 执行的 代码
Iterator iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next(); // key = 类上 的注解的
String activityName = map.get(key);
System.out.println("aaaaaa "+"=====");
methodSpecBuilder.addStatement("com.example.router.Arouter.gerInstance().addactivity(\"" + key +"\"," + activityName +")");
}
MethodSpec methodSpec = methodSpecBuilder.build();
// 创建类
ClassName iRouter = ClassName.get("com.example.router", "IRouter");
// 创建工具
TypeSpec typeSpec = TypeSpec.classBuilder("ActivityUtils" + System.currentTimeMillis())
.addModifiers(Modifier.PUBLIC).
addSuperinterface(iRouter).
addMethod(methodSpec).build();
// 构建目录
JavaFile javaFile = JavaFile.builder("com.lww.utils", typeSpec).build();
javaFile.writeTo(filer);
}catch (IOException e) {
System.out.println("----------------------"+e.toString());
}
}
}
==============================