[编织消息框架][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等信息

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

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

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

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

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

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

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

上一篇:Linux字符集的查看及修改


下一篇:OneProxy构建