[编织消息框架][JAVA核心技术]动态代理应用4
基础部份:
接下来讲编译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的更多相关文章
- [编织消息框架][JAVA核心技术]动态代理介绍
由于java是种强类型静态语言,在执行时无法动态生成代码,静态语言基本都有这特性 动态生成代码有几种好处,也是弱类型语言的优点 1.部份逻辑可以实现热更新 2.远程调用实现非常适合 3.能动态生成扩展 ...
- [编织消息框架][JAVA核心技术]动态代理应用12-总结
动态代理这篇比较长,是框架组成的重要基础 回顾下学到的应用技术 1.异常应用 2.annotation技术 3.数值与逻辑分享 4.jdk.cglib.javassist等动态代理技术 5.懒处理.预 ...
- [编织消息框架][JAVA核心技术]动态代理应用8-IRpcReceive实现
private static Map<Short, Map<Byte, Method>> RECEIVE_METHOD_INFO = new HashMap<>() ...
- [编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现
根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象 public interface IRpcSend { public <T> QResult< ...
- [编织消息框架][JAVA核心技术]动态代理应用4-annotationProcessor
基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...
- [编织消息框架][JAVA核心技术]动态代理应用2
接下来如何实现 第一步:先把服务类,调用方法转换成数字,方便传输 第二步:提取元信息,提取又有三种方式,三种各有优点,最优方式是第一种 1.编译java时处理 2.程序启动时处理,预处理 3.调用时处 ...
- [编织消息框架][JAVA核心技术]动态代理应用5-javassist
基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...
- [编织消息框架][JAVA核心技术]动态代理应用9-扫描class
之前介绍的annotationProcessor能在编译时生成自定义class,但有个缺点,只能每次添加/删除java文件才会执行,那天换了个人不清楚就坑大了 还记得之前介绍的编译时处理,懒处理,还有 ...
- [编织消息框架][JAVA核心技术]动态代理应用10-水平扩展方案
服务分为系统服务同用户服务两种 水平扩展是基于系统服务,而拆分方式又有几种方案,按数据跟业务情况来做决策 1.每个服务独立存储(图1):每个服务只负责一个或多个领域实体存储,A服务不能直接修改B服务的 ...
随机推荐
- 杭电2000——ASCII码排序
/* ASCII码排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- [NOI2007]货币兑换Cash(DP+动态凸包)
第一次打动态凸包维护dp,感觉学到了超级多的东西. 首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k 不过就是重载运算符和一些细节方面有些恶心,90行解决 后 ...
- SaberRD之瞬态分析
瞬态分析(Transient Analysis)也叫做暂态分析,一般用于分析含有储能器件的电路在换路后发生的过渡状态,比如分析RLC电路在接通.断开.改接以及参数发生改变和电源突变时,电路的电压电流从 ...
- CSS Sprites (css精灵)
CSS Sprites CSS Sprites在国内很多人叫css精灵,是一种网页图片应用处理方式.它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不 ...
- “幸福企业”定义-参观“MES项目”有感
作为公司的员工,总是想在一个自己满意的企业里面发展.作为企业主,虽不能天天将“回报社会”挂在嘴上,但凡是有抱负的,还是希望自己的部下“以厂为家的”.然而劳资双方的矛盾总是让双方感觉互有亏欠.这种不信任 ...
- [HDOJ2572]终曲
Problem Description 最后的挑战终于到了!站在yifenfei和MM面前的只剩下邪恶的大魔王lemon一人了!战胜他,yifenfei就能顺利救出MM.Yifenfei和魔王lemo ...
- HTML 5入门知识——Drag
HTML 5拖放 拖放的步骤: 1.对象元素的draggable属性设置为true,还需要注意的是a元素和img元素必须指定href. 2.编写与拖放有关的事件处理代码: DataTransfer对象 ...
- Ionic2开发笔记(2)创建子页面及其应用
1. 当你第一次产生ionic2应用程序,这是生成的项目结构 ├── ├── config.xml 这包含配置应用程序的名称,和包名,将被用于我们的应用程序安装到一个实际的设备. ├── h ...
- ES3:ElasticSearch 索引
ElasticSearch是文档型数据库,索引(Index)定义了文档的逻辑存储和字段类型,每个索引可以包含多个文档类型,文档类型是文档的集合,文档以索引定义的逻辑存储模型,比如,指定分片和副本的数量 ...
- 基于SSH协议的端口转发
[前言] 最近一直在使用ssh协议的端口转发(隧道)功能,完成对内网空透等.这篇文章将主要讲解3种常用的ssh tunnelling使用方法和基本原理. 在介绍具体内容前,我先奉上端口转发的常用情景: ...