[转]java注解与APT技术
下面是一个简单的自定义注解的栗子:
package annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 动物名称注解
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AnimalName {
String value() default "";
}
定义了注解,并在需要的时候给相关类,类属性加上注解信息,如果没有响应的注解信息处理流程,注解可以说是没有实用价值,接下来要介绍的是java的APT(Annotation Process Tool)技术,用于处理自定义注解。
2,APT技术
APT(Annotation Process Tool),是一种在代码编译时处理注解,按照一定的规则,生成相应的java文件,多用于对自定义注解的处理,目前比较流行的Dagger2, ButterKnife, EventBus3都是采用APT技术,对运行时的性能影响很小。我们通过自定义注解的方式,来了解一下如何使用APT:
1,自定义注解:
@Target({ElementType.TYPE}) ---作用范围 Class
@Retention(RetentionPolicy.CLASS) ---生命周期:仅保留到.class文件
public @interface Route {
/** Path of route*/
String value(); ---类似于成员变量
}
2,使用方式
@Route(path = "/test/activity2")
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test2);
}
}
JVM默认只会处理@override等语言自带的注解,对于自定义的注解,需要我们自己处理,java提供了一个名为AbstractProcessor.java的抽象类,我们只要继承该类,就实现自己的注解处理器,来处理自定义的@Route注解
public class RouteProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment env){
// 主要做一些初始化操作
}
@Override
public boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) {
//具体处理注解的逻辑,控制代码的生成
processAnnotations();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
// 支持处理的注解类型, 在这里就是@Route
}
@Override
public SourceVersion getSupportedSourceVersion() {
//java版本 如:jdk1.6or jdk1.7
}
}
3,自定义Processor
@AutoService(Processor.class)
public class HelloProcessor extends AbstractProcessor {
/** 文件相关的辅助类 用于生成新的源文件、class等 */
private Filer mFiler;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
mFiler = processingEnv.getFiler();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
// 构建方法 此处使用到了square公司的javapoet库,用来辅助生成 类的代码
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("show")
.addModifiers(Modifier.PUBLIC);
methodBuilder.addStatement("String test = \"$N\" ","hello annotation world!");
/** 构建类 */
TypeSpec finderClass = TypeSpec.classBuilder("Hello$$Inject")
.addModifiers(Modifier.PUBLIC)
.addMethod(methodBuilder.build())
.build();
try {
JavaFile.builder("com.win.test",finderClass).build().writeTo(mFiler);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
// 支持的注解类型
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new LinkedHashSet<>();
types.add(Hello.class.getCanonicalName());
return types;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return super.getSupportedSourceVersion();
}
}
在AS工程中使用
@Hello("MainTest") //自定义的Hello注解
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
在项目App module的build目录下,便会生成对应的java类文件:
这个只是简单的栗子,我们可以在process()方法中,加入更多的业务逻辑,以实现特定功能。
[转]java注解与APT技术的更多相关文章
- 秒懂,Java 注解 (Annotation)你可以这样学 - CSDN博客
https://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人比较 ...
- 秒懂,Java 注解 (Annotation)你可以这样学
转自: https://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我 ...
- Java 注解 (Annotation)
Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.Java 注解是从 Java5 开始添加到 Java 的. 注解语法 ...
- Java 注解(Annotation)秒懂,你可以这样学,
文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人比较尊敬老罗的.至于为什么放这张图,自然是为本篇博文服务,接下来我自会说明.好了,可以开始今天的博文了. Anno ...
- (转)秒懂,Java 注解 (Annotation)你可以这样学
转自:秒懂,Java 注解 (Annotation)你可以这样学 注解如同标签 回到博文开始的地方,之前某新闻客户端的评论有盖楼的习惯,于是 “乔布斯重新定义了手机.罗永浩重新定义了傻X” 就经常极为 ...
- Java注解Annotation的用法 - 自定义Annotation实现
Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据. Java语言中的类.方法.变量.参数和包等都可以被标注.和Javadoc不同,Java标注可以通过反射获取标 ...
- (转)秒懂,Java 注解 (Annotation)你可以这样学 ---- 重要 注解定义与反射解析
转:http://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人 ...
- attilax.java 注解的本质and 使用最佳实践(3)O7
attilax.java 注解的本质and 使用最佳实践(3)O7 1. 定义pojo 1 2. 建立注解By eclipse tps 1 3. 注解参数的可支持数据类型: 2 4. 注解处理器 2 ...
- Java注解教程及自定义注解
Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容.在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解. Java1.5引入了注解,当前许 ...
随机推荐
- golang---信号signal
golang中os/signal包的使用 chenbaoke · 2015-06-17 20:03:59 · 2748 次点击 · 预计阅读时间 1 分钟 · 不到1分钟之前 开始浏览 这是一个创建于 ...
- POJ2251 Dungeon Master —— BFS
题目链接:http://poj.org/problem?id=2251 Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total S ...
- codeforces 451C. Predict Outcome of the Game 解题报告
题目链接:http://codeforces.com/problemset/problem/451/C 题目意思:有3支球队(假设编号为1.2.3),总共要打 n 场比赛,已知已经错过这n场比赛中的 ...
- ss连接不上
突然ss就连接不上了,而vps的ip能ping通,ssh也能登录. 折腾了半天都没解决. 后来解决了,关键点有两个 (1)更改ss的服务端口,原本是9000,随便改为其他的: (2)在switch里设 ...
- Django中的Ajax详解
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当 ...
- iOS开发检测是否开启定位、是否允许消息推送等权限
1.iOS开发检测是否开启定位: 需要导入: #import <CoreLocation/CoreLocation.h> 代码如下: + (void)openLocationService ...
- bzoj 4903: [Ctsc2017]吉夫特【lucas+状压dp】
首先根据lucas, \[ C_n^m\%2=C_{n\%2}^{m\%2}*C_{n/2}^{m/2} \] 让这个式子的结果为计数的情况只有n&m==m,因为m的每一个为1的二进制位都需要 ...
- bzoj 4240: 有趣的家庭菜园【树状数组+贪心】
以为是逆序对数-- 实际上,原数组移动若干次后我们会得到一个新的下标序列,需要的移动次数是这个新下标序列的逆序对数 然后我们要让这个最小,考虑贪心先按h把下标排一遍序,然后每次询问到一种值的时候,对每 ...
- 第一篇 .NET高级技术之索引器
基础知识补充 索引 器 没有名字 ,索引器的内部本质 (ILSpy的IL模式下看)类型 this[参数]{get;set;} 可以是只读或者只写(在get或者set前加上private) 字符串是只读 ...
- Docker镜像文件操作
1什么是Docker镜像 Docker镜像是由文件系统叠加而成(是一种文件的存储形式).最底端是一个文件引导系统,即bootfs,这很像典型的Linux/Unix的引导文件系统.Docker用户几乎永 ...