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


    基础部份:

    接下来讲编译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,后面会有详细介绍

  • 相关阅读:
    visualSVNYou don't have permission to access on this server
    怎样截取Http请求
    ASP.NET @page 指令详解
    我的XMLHelperC# XML操作基类(修改,删除,新增,创建)
    最新Visual Studio 2010 下载及学习资料
    redis主从哨兵和集群的区别
    uniapp nvue 支持iconfont
    Error (Error Code: 1175) during executing update command on table using MySQL
    org.apache.jasper.JasperException: Unable to compile class for JSP
    java.sql.SQLException: Access denied for user 'root'@'10.10.10.10' (using password: YES)
  • 原文地址:https://www.cnblogs.com/solq111/p/6669713.html
Copyright © 2020-2023  润新知