EJB3笔记7-EJB3 Framwork:apt解析annotation生成代码
Author fancyhf@163.com fancyhf.mblogger.cn
Apt处理流程:
1.apt确定源代码有那些annotations
2.apt查找你写的annotation processor factories,询问factories要处理哪里annotation。
3.processor运行生成新代码文件直到没有新的文件要被产生。
有关的包:
com.sun.mirror.apt:跟apt工具交互的接口
com.sun.mirror.declaration:建模源代码的字段、方法、类等的定义
com.sun.mirror.type:建模在源代码中找到的类型
com.sun.mirror.util:处理type,declaration,visitor的功能集
每个processor实现com.sun.mirror.apt包的AnnotationProcessor接口,这个接口包括一个process方法,将被apt工具调用。一个processor将处理一或多个annotation types。
通过AnnotationProcessorFactory获得一个processor实例,工具将提供AnnotationProcessorEnvironment。在这个环境变量中,process将找到任何启动时需要的值,包括其操作的程序接口,跟apt工具交互操作产生新文件和传送警告和错误信息的方式。
可通过命令行的-facotry来指定factory,也可从META-INF/services读取名为com.sun.mirror.apt.AnnotationProcessorFactory的文本文件,文件列出有关的facotry类。例子:
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.*;
import com.sun.mirror.util.*;
import java.util.Collection;
import java.util.Set;
import java.util.Arrays;
//以下是static import性能
import static java.util.Collections.*;
import static com.sun.mirror.util.DeclarationVisitors.*;
/*列出类名,功能类似doclet的ListClass。*/
public class ListClassApf implements AnnotationProcessorFactory {
//处理任何annotations
private static final Collection<String> supportedAnnotations
= unmodifiableCollection(Arrays.asList("*"));//或可改变*为Command标记
// No supported options
private static final Collection<String> supportedOptions = emptySet();
public Collection<String> supportedAnnotationTypes() {
return supportedAnnotations;
}
public Collection<String> supportedOptions() {
return supportedOptions;
}
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
return new ListClassAp(env);
}
private static class ListClassAp implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
ListClassAp(AnnotationProcessorEnvironment env) {
this.env = env;
}
public void process() {
for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations())
typeDecl.accept(getDeclarationScanner(new ListClassVisitor(),
NO_OP));
}
private static class ListClassVisitor extends SimpleDeclarationVisitor {
public void visitClassDeclaration(ClassDeclaration d) {
System.out.println(d.getQualifiedName());
}
}
}
}
指定处理的annotations:
factory返回import-style字符的结合,如例子。特定的字符入口包括以下格式:
*:处理所有的annotations。也处理空的annotation列表,也即处理就必须提供non-trivial即使没有annotation。这个功能使得com.sun.mirror的api能用来写通用代码生成工具。
foo.bar.Baz:处理规范名为“ foo.bar.Baz”的annotation。
foo.bar.*:处理规范名由“foo.bar.”开始的annotation。
====一定要包括包名,而且不支持Command*,所以不同的annotation可能需要放不不同的subpackage
facotry可使用com.sun.mirror.apt.AnnotationProcessors.getCompositeAnnotationProcessor来联合切按序操作多个annotation processor。
可通过-A传入参数给processor,如-Adebug和-Aloglevel=3。
隐形参数:
-XListAnnotationTypes :List found annotation types
-XListDeclarations :List specified and included declarations
-XPrintAptRounds :Print information about initial and recursive apt rounds
-XPrintFactoryInfo :Print information about which annotations a factory is asked to process
声明和类型:
mirror api主要通过com.sun.mirror.declaration包中的Declaration接口和下层子接口来表示源代码结构。一个Declaration表示一个程序结构如包、类或方法,通常一对一关联到源代码中特定的片断。Declaration是要被标注的结构。
Type通过com.sun.mirror.type包中的TypeMirror接口和其下层子接口表述。包括主类行、类、接口类行、数组类行、类型变量和统配符类型。
Declaration和type有所不同,一个单一的declaration可以定义一个完整的type家族,如类java.util.Set的declaration关联到:
参数类行 java.util.Set<String>
参数类行java.util.Set<Number>
参数类行java.util.Set<T> for some type T other than String or Number the raw type java.util.Set.
一个declaration有doc被主,源代码位置,modifier和标注,它可有不同类型的名称(简单、合格)。更多特定的declaration子类提供访问构造函数和父类。
TypeMirrors用来建模源代码中的返回类型、参数类型等,一个蚕注类型的TypeMirror映射到有关的declaration。
Apt与javadoc的不同:
Apt生成文件,源代码可有标注了annotation,也可以没有标注;之后直接compile所有代码。
如果任何processor生成了新的源代码,将递归调用apt。在这个递归apt调用中,调用上个循环中的facotry的getProcessorFor提供processor,即使那个factory不processor当前任何一个annotation。这允许factory在apt的子循序循环中注册一个listner;尽管多数factories在这个例子中只会简单返回AnnotationProcessors.NO_OP。当一个循环后没有产生新的代码文件,apt将调用javac来编译原始和生成的代码文件。如果没有processors被找到或者不支持当前annotation,调用apt就等于调用javac。
如果一个facotry类被annotation process的多个循环使用,factory导入一次,而其getProcessorFor方法将在每次循环中调用。这使得一个factory能在跨循环保存静态状态。
所以,生成代码前,一定要检测是否属于标注的annotation,如:
boolean isCommandClass = false;
CommandClass ann = d.getAnnotation(CommandClass.class);
isCommandClass = (ann != null);
if (isCommandClass){
PrintWriter writer =
env.getFiler().createSourceFile(packageName+"."+className+"command");
}
相关推荐
高校技术转移办公室人员如何高效开展技术需求挖掘工作?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
科技中介服务机构如何提升服务的专业性与用户粘性?.docx
科技中介服务机构如何提升服务的专业性与用户粘性?
高校技术转移办公室人员在组织科研成果展示时,如何提升推介材料的专业性与吸引力?.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。
三相并网逆变器无功功率扰动+孤岛检测控制算法仿真【参考文献+仿真】
内容概要:本文系统梳理了一套面向电力电子与新能源并网领域的仿真研究资源,聚焦三相并网逆变器的关键控制技术,涵盖无功功率扰动、孤岛检测算法、低电压穿越(LVRT)、中点电位平衡、虚拟同步发电机(VSG)、下垂控制、模型预测控制(MPC)、准PR控制及LCL滤波器设计等核心技术。资源包含多种逆变器拓扑结构(如T型三电平、Z源、ANPC、四桥臂等)的Simulink仿真模型,并结合扫频法进行正负序阻抗建模与稳定性分析,强调通过复现经典科研案例提升实际科研能力,适用于电力系统稳定性、微电网运行与可再生能源并网等方向的研究与验证。; 适合人群:电力电子、电气工程及其自动化、新能源科学与工程等相关专业的高校研究生、科研人员及从事光伏、储能逆变器开发的工程技术人员,需具备MATLAB/Simulink仿真基础和一定的电力系统控制理论知识。; 使用场景及目标:① 掌握三相并网逆变器在孤岛检测、无功调节、不平衡电网等复杂工况下的先进控制策略设计与仿真方法;② 借助提供的仿真模型与参考文献快速搭建科研平台,用于论文复现、课题开发或项目验证;③ 深入理解VSG、MPC、阻抗建模与下垂控制等关键技术的实现机制与工程应用路径。; 阅读建议:建议结合文中提供的网盘链接与公众号“荔枝科研社”获取完整仿真模型与参考资料,按照目录顺序循序渐进学习,注重理论推导与仿真实践相结合,优先复现基础模型再进行参数优化与创新拓展。
香橙派5-uefi-edk2-spi-flash镜像
香橙派5-uefi-edk2-spi-flash镜像


