基础部份:

接下来讲编译JAVA时,生成自定义class

我们用 javax.annotation.processing.AbstractProcessor 来处理

public abstract class AbstractProcessor implements Processor {

    protected ProcessingEnvironment processingEnv;

    public Set<String> getSupportedOptions() {
SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);
if (so == null)
return Collections.emptySet();
else
return arrayToSet(so.value());
} public Set<String> getSupportedAnnotationTypes() {
SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class);
if (sat == null) {
//省略
return Collections.emptySet();
}
else
return arrayToSet(sat.value());
}
public SourceVersion getSupportedSourceVersion() {
SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class);
SourceVersion sv = null;
if (ssv == null) {
sv = SourceVersion.RELEASE_6;
//省略
} else
sv = ssv.value();
return sv;
}
}

继承AbstractProcessor 需要关心几个地方

1.@SupportedSourceVersion 支持java源码版本,扫描项目java文件过滤

2.@SupportedAnnotationTypes 过滤的 Annotation class

3.属性ProcessingEnvironment

  其中有个概念Element包含 class、method、field等信息

我们只关心以下几种类型:

1.TypeElement 对象包含class 信息

2.VariableElement 对象包含 field, constant, method or constructor parameter, local variable 等信息

  其中通过getEnclosingElement 能获取到目标TypeElement

实现部份:

由于 process(Set<? extends TypeElement> annotations, RoundEnvironment env) annotations参数只是 @SupportedAnnotationTypes 上绑定的anno class 没有提取到相关的处理类

可以通过env.getRootElements()获取全部的类,或内部带过滤的方法 env.getElementsAnnotatedWith

@SupportedAnnotationTypes({ "com.eyu.TestAnnotation" })
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class MyProcessor extends AbstractProcessor {
/***
* {@link ElementFilter}
*/
public static final Set<ElementKind> CONSTRUCTOR_KIND = Collections.unmodifiableSet(EnumSet.of(ElementKind.CONSTRUCTOR));
public static final Set<ElementKind> FIELD_KINDS = Collections.unmodifiableSet(EnumSet.of(ElementKind.FIELD, ElementKind.ENUM_CONSTANT));
public static final Set<ElementKind> METHOD_KIND = Collections.unmodifiableSet(EnumSet.of(ElementKind.METHOD));
public static final Set<ElementKind> PACKAGE_KIND = Collections.unmodifiableSet(EnumSet.of(ElementKind.PACKAGE));
public static final Set<ElementKind> TYPE_KINDS = Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS, ElementKind.ENUM, ElementKind.INTERFACE, ElementKind.ANNOTATION_TYPE)); @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
Set<? extends Element> elememts = env.getElementsAnnotatedWith(com.eyu.TestAnnotation.class);
Set<Class<?>> clz = new HashSet<>();
for (Element ele : elememts) {
String key = null;
if (TYPE_KINDS.contains(ele.getKind())) {
  TypeElement classElement = (TypeElement) ele;
  key = classElement.getQualifiedName().toString();
} else if (FIELD_KINDS.contains(ele.getKind()) || METHOD_KIND.contains(ele.getKind())) {
  VariableElement varELe = (VariableElement) ele;
   TypeElement enclosingElement = (TypeElement) varELe.getEnclosingElement();
  key = enclosingElement.getQualifiedName().toString();
}
if (key == null) {
  continue;
}
try {
  clz.add(Class.forName(key));
} catch (ClassNotFoundException e) {
  e.printStackTrace();
}
}
for (Class<?> key : clz) {
System.err.println(key);
}
return false;
}
}

执行部份:

执行自定义AbstractProcessor有两种方式

1.在maven项目 pom.xml 添加

     <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<annotationProcessors>
<annotationProcessor>com.eyu.MyProcessor</annotationProcessor>
</annotationProcessors>
<debug>true</debug>
<optimize>true</optimize>
<source>1.8</source>
<target>1.8</target>
<compilerArguments>
<AaddGeneratedAnnotation>true</AaddGeneratedAnnotation>
<Adebug>true</Adebug>
</compilerArguments>
</configuration>
</plugin>

2.在resource/META-INF/services 新建 javax.annotation.processing.Processor 文件

内容为自定义处理类 com.eyu.MyProcessor

然后创建maven build 配置 Goals输入install即可 在实际测试中只有删除/添加java文件才触发一次执行

细心的读者会发者,上篇没有写如何发送消息,这篇没有如何写生成class,后面会有详细介绍

[编织消息框架][JAVA核心技术]动态代理应用4的更多相关文章

  1. [编织消息框架][JAVA核心技术]动态代理介绍

    由于java是种强类型静态语言,在执行时无法动态生成代码,静态语言基本都有这特性 动态生成代码有几种好处,也是弱类型语言的优点 1.部份逻辑可以实现热更新 2.远程调用实现非常适合 3.能动态生成扩展 ...

  2. [编织消息框架][JAVA核心技术]动态代理应用12-总结

    动态代理这篇比较长,是框架组成的重要基础 回顾下学到的应用技术 1.异常应用 2.annotation技术 3.数值与逻辑分享 4.jdk.cglib.javassist等动态代理技术 5.懒处理.预 ...

  3. [编织消息框架][JAVA核心技术]动态代理应用8-IRpcReceive实现

    private static Map<Short, Map<Byte, Method>> RECEIVE_METHOD_INFO = new HashMap<>() ...

  4. [编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现

    根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象 public interface IRpcSend { public <T> QResult< ...

  5. [编织消息框架][JAVA核心技术]动态代理应用4-annotationProcessor

    基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...

  6. [编织消息框架][JAVA核心技术]动态代理应用2

    接下来如何实现 第一步:先把服务类,调用方法转换成数字,方便传输 第二步:提取元信息,提取又有三种方式,三种各有优点,最优方式是第一种 1.编译java时处理 2.程序启动时处理,预处理 3.调用时处 ...

  7. [编织消息框架][JAVA核心技术]动态代理应用5-javassist

    基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...

  8. [编织消息框架][JAVA核心技术]动态代理应用9-扫描class

    之前介绍的annotationProcessor能在编译时生成自定义class,但有个缺点,只能每次添加/删除java文件才会执行,那天换了个人不清楚就坑大了 还记得之前介绍的编译时处理,懒处理,还有 ...

  9. [编织消息框架][JAVA核心技术]动态代理应用10-水平扩展方案

    服务分为系统服务同用户服务两种 水平扩展是基于系统服务,而拆分方式又有几种方案,按数据跟业务情况来做决策 1.每个服务独立存储(图1):每个服务只负责一个或多个领域实体存储,A服务不能直接修改B服务的 ...

随机推荐

  1. R系列:关联分析;某电商平台的数据;做捆绑销售和商品关联推荐

    附注:不要问我为什么写这么快,是16年写的. 一.分析目的 I用户在某电商平台买了A,那么平台接下来应该给用户推荐什么,即用户在买了商品A之后接下来买什么的倾向性最大: II应该把哪些商品在一起做捆绑 ...

  2. 工具使用——MATLAB基本调试方法

    作者:桂. 时间:2017-02-28  07:06:30 链接:http://www.cnblogs.com/xingshansi/articles/6477185.html 声明:转载请注明出处, ...

  3. 业务逻辑 : 未完 : easybook.com

    Content>social media facebook, twitter, google+, instagram, pinterest (Question : How to update n ...

  4. scss 学习笔记

    由于没有办法在网络上找到适合顾客的模板,同时之前自己写css也没有很好的管理方式,最终选择了scss. Nested #main p { color: #00ff00; width: 97%; .re ...

  5. 关于adb重启的一些问题

    有时候我们在使用eclipse启动虚拟机进行程序测试的时候会提示,要我们重启adb和eclipse,这个时候,重启adb的方式就是,使用cmd定位到adb所在的文件夹,然后输入指令:adb kill- ...

  6. Java代码块详解

    Java中代码块指的是用 {} 包围的代码集合,分为4种:普通代码块,静态代码块,同步代码块,构造代码块 普通代码块: 定义:在方法.循环.判断等语句中出现的代码块 修饰:只能用标签修饰 位置:普通代 ...

  7. debian/ubuntu部署java应用小结

    近期改的Java应用即将部署,为了强强联合,需要把Java应用部署到linux,我们选择了debian系列.小结一下部署的大致过程,如下: Ubuntu已经默认安装了OpenJDK,但还是比较倾向官方 ...

  8. APP H5 混合自动化使用说明 [基于 Appium+Python 系列]

    背景 前几天接到H5开发人员那边的业务开发需求单,说想将H5接入到自动化系列中,特此记录分享一下. 环境前置准备 手机与电脑USB连接,开启USB调试模式,通过adb devices可查看到此设备. ...

  9. 1935: [Shoi2007]Tree 园丁的烦恼

    1935: [Shoi2007]Tree 园丁的烦恼 Time Limit: 15 Sec  Memory Limit: 357 MBSubmit: 648  Solved: 273[Submit][ ...

  10. Java容器源码解析之——ArrayList

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...