[转]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引入了注解,当前许 ...
随机推荐
- YTU 2457: 很简单的一道题
2457: 很简单的一道题 时间限制: 1 Sec 内存限制: 128 MB 提交: 261 解决: 80 [提交][状态][讨论版] 题目描述 有一个简单的函数数学公式,如下 输入 重复输入多组 ...
- 常用文件操作模块json,pickle、shelve和XML
一.json 和 pickle模块 用于序列化的两个模块 json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 Js ...
- Linux系统中的运行级别
什么是运行级呢?简单的说,运行级就是操作系统当前正在运行的功能级别. 它让一些程序在一个级别启动,而另外一个级别的时候不启动. Linux系统的有效登录模式有0~9共十种,不过沿用UNIX系统的至多6 ...
- Fleck websocket官方事例
Fleck websocket官方事例 server: using Fleck;using System;using System.Collections.Generic;using System.L ...
- 利用百度地图API制作房产酒店地图
摘要: 想亲手制作一张酷讯.去哪儿.安居客.链接地产那样的房产.酒店地图麼?那赶快来学习吧.(以酷讯为例,如下图) 更多成功案例请点击:http://dev.baidu.com/wiki/map/in ...
- 「LuoguP4753」濑 River Jumping(贪心
Description 有一条宽度为 N 的河上,小D位于坐标为 0 的河岸上,他想到达坐标为 N 的河岸上后再回到坐标为 0 的位置.在到达坐标为 N 的河岸之前小D只能向坐标更大的位置跳跃,在到达 ...
- bzoj1783
博弈论+dp 从未做过博弈论... 思路是这样的,我们倒着考虑,分别设f[i]表示先手选了a[i]后能取得的最大值,g[i]表示先手取了a[i]后后手能获得的最大值 g[i]=f[mx],f[mx]是 ...
- F - Candy Bags
A. Candy Bags time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- UVaLive 3401 Colored Cubes (暴力)
题意:给定n个立方体,让你重新涂尽量少的面,使得所有立方体都相同. 析:暴力求出每一种姿态,然后枚举每一种立方体的姿态,求出最少值. 代码如下: #pragma comment(linker, &qu ...
- 简单聊聊ES6-Promise和Async
前言 本篇博文出至于我的github仓库:web-study,如果你觉得对你有帮助欢迎star,你们的点赞是我持续更新的动力,谢谢! 异步编程在前端开发中尤为常见,从最早的XHR,到后来的各种封装aj ...