廊坊住房和城乡建设厅网站wordpress lover

当前位置: 首页 > news >正文

廊坊住房和城乡建设厅网站,wordpress lover,建网站先要申请网址吗,有关网站建设的论文1. 概叙 Lombok是什么#xff1f; Project Lombok 是一个 JAVA 库#xff0c;它可以自动插入编辑器和构建工具#xff0c;为您的 JAVA 锦上添花。再也不要写另一个 getter/setter 或 equals 等方法#xff0c;只要有一个注注解#xff0c;你的类就有一个功能齐全的生成器…1. 概叙 Lombok是什么 Project Lombok 是一个 JAVA 库它可以自动插入编辑器和构建工具为您的 JAVA 锦上添花。再也不要写另一个 getter/setter 或 equals 等方法只要有一个注注解你的类就有一个功能齐全的生成器自动记录变量等等。 官方地址https://projectlombok.org/ Lombok是一种Java™实用工具可用来帮助开发人员消除Java的冗长代码尤其是对于简单的Java对象POJO。它通过注释实现这一目的。 首先Lombok是一款Java IDE的应用工具插件一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具比如属性的构造器、getter、setter、equals、hashcode、toString方法。结合IDE通过使用对应的注解可以在编译源码的时候生成对应的方法。 通过在开发环境中实现Lombok开发人员可以节省构建诸如hashCode()和equals()这样的方法以及以往用来分类各种accessor和mutator的大量时间。 虽然上述的那些常用方法IDE都能生成但是lombok更加简洁与方便能够达到的效果就是在源码中不需要写一些通用的方法但是在编译生成的字节码文件中会帮我们生成这些方法这就是lombok的神奇作用。 lombok插件安装 使用的IDE是Intellij idea编译器需要在 preference-plugins-Browse repositories
搜索lombok然后安装plugins需要稍等片刻 添加jar包 在项目中添加lombok的jar包笔者用的是maven所以在pom文件中添加了如下的依赖。gradle使用见官网。 dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.16.16/versionscopeprovided/scope /dependency常用的注解 官网注解介绍Stable 2. Lombok原理介绍 2.1 Java类文件编译过程 首先我们知道 Lombok 功能是作用在类编译时期那我们来看下一个类编译的过程。 定义一个 PersonDTO.Java 类 代码语言javascript 复制 public class PersonDTO {//姓名private String name;
}Javac PersonDTO.Java 对源代码进行解析转化会生成一棵抽象语法树( AST )运行过程中会调用实现了 JSR 269 注解处理器下面介绍JSR 实现可处理自定义逻辑包括可修改编译后的抽象语法树(AST)Javac 使用修改后的抽象语法树(AST)生成字节码文件 过程如下图 AST 是抽象语法树Abstract Syntax Tree) 的缩写是 JAVA 源代码展示的一种树状结构它将代码的结构和语法元素映射到树节点上使得程序可以在编译、 分析和转换过程中更容易地操作和理解。有兴趣可以学习 JavaParser 源码 了解将 Java 源代码解析生成成一个抽象语法树 AST 这个树形结构表示了代码的 语法结构包括类、方法、变量、语句等等过程。 github地址:https://github.com/javaparser/javaparser. 如: PersonDTO.Java 在 idea 中使用可视化工具展示文件 AST 树 2.2 JSR 269介绍 首先 JSR 269全称 Pluggable Annotation Processing API 是 JAVA 平台的一项规范也被称之为注解处理器 API 。在Java6引入用于在编译时处理 注解目标是提供更丰富的编译时元数据处理能力以增强Java编译器的功能。这个规范允许开发人员创建自定义的注解处理器这些处理器可以在编译时检查、分析和生成Java代码。 JSR 269在JDK6中被引入作为APT的替代方案。javac执行的时候会调用Pluggable Annotation Processing API因此我们可以通过实现此API来改变编译期的一些行为从而达到目的。具体的编译流程如下 javac编译流程 举例来说现在有一个实现了Pluggable Annotation Processing API的程序A那么使用javac编译时的具体流程如下 1. javac编译器对源码进行分析生成一个抽象的语法树AST) 2. javac编译器运行A程序 3. A程序完成逻辑一般是修改此语法树 4. javac使用修改后的语法树生成可执行的字节码文件 Lomok便是通过Pluggable Annotation Processing API来实现代码生成的。 应用框架: Servlet、JAX-RSRESTful Web服务JSR 269 来生成用于处理 HTTP 请求的代码。Spring Boot 项目中以处理各种自定义注解如 Controller、Service、Repository 等。这些注解可以用于自动化配置、依赖注入等方面。Hibernate 它使用 JSR 269 来处理 JPA 注解并生成与数据库交互的代码。Lombok 是一个 JAVA 库它通过注解处理器生成常见的 JAVA 代码如 getter、setter、equals、hashCode 等以简化开发工作。MapStruct 是一个用于对象映射的 JAVA 库它使用 JSR 269 来生成类型安全的映射代码帮助开发人员将一个对象映射到另一个对象。 如何实现自定义注解注解处理器 1.声明自定义注解如 Lombok 下的 DataGetterSetter等。 2.实现 Process接口或者继承 AbstractProcessor 复写 process 方法处理自定义注解逻辑。 代码语言javascript 复制 import javax.annotation.processing.; import javax.lang.model.SourceVersion; import javax.lang.model.element.; import java.util.Set;SupportedAnnotationTypes(com.example.MyAnnotation) // 自定义注解 SupportedSourceVersion(SourceVersion.RELEASE_8) //支持的Java版本 public class MyAnnotationProcessor extends AbstractProcessor {Overridepublic boolean process(Set? extends TypeElement annotations RoundEnvironment roundEnv) {// 在这里处理自定义注解生成代码或执行其他任务return true;} }3.注册注解处理器 两种方式: Resource 文件:项目 META-INF/services 创建 javax.annotation.processing.Processor 文件自定义注解处理器的全类名写到此文件中。通过谷歌工具包 auto-service 可自动生成以上配置文件。 代码语言javascript 复制 !– 编译注解执行注册 jar包– dependencygroupIdcom.google.auto.service/groupIdartifactIdauto-service/artifactIdversion1.0.1/version /dependency AutoService(Processor.class) //谷歌工具包方式:注册注解处理器 SupportedAnnotationTypes(com.example.MyAnnotation) // 自定义注解 SupportedSourceVersion(SourceVersion.RELEASE_8) //支持的Java版本 public class MyAnnotationProcessor extends AbstractProcessor {Overridepublic boolean process(Set? extends TypeElement annotations RoundEnvironment roundEnv) {// 在这里处理自定义注解生成代码或执行其他任务return true;} }2.3 Lombok 实现原理

  1. Lombok 实际就是结合注解处理器和 AST 技术 Lombok 实现的注解处理器会遍历 AST 查找与 Lombok 注解相关的元素根据注解的要求生成新的代码。 2.编译前后的 AST 语法树对比 加入Getter注解编译后 3. Lombok 注解处理器采用 Resource 方式注册编译注解处理器 注解处理器 AnnotationProcessor 源码 代码语言javascript 复制 class AnnotationProcessorHider {public static class AstModificationNotifierData {public volatile static boolean lombokInvoked false;}public static class AnnotationProcessor extends AbstractProcessor {// 获取支持的注解类型Overridepublic SetString getSupportedOptions() {return instance.getSupportedOptions();}// 获取支持的注解类型Overridepublic SetString getSupportedAnnotationTypes() {return instance.getSupportedAnnotationTypes();}// 支持的JDK版本Overridepublic SourceVersion getSupportedSourceVersion() {return instance.getSupportedSourceVersion();}//初始化环境Overridepublic void init(ProcessingEnvironment processingEnv) {disableJava9SillyWarning();AstModificationNotifierData.lombokInvoked true;instance.init(processingEnv);super.init(processingEnv);}// 处理自定义注解逻辑Overridepublic boolean process(Set? extends TypeElement annotations RoundEnvironment roundEnv) {return instance.process(annotations roundEnv);}}自定义注解处理器 Handler : 在 Jar 包的 lombok.javac.handlers下每个注解处理对应一个 Handler. 如 HadlerGetter.java 操作 AST 树生成 getter 方法. 2.4手动实现一个 Getter 功能 2.4.1.创建 maven 工程 demo 包含两个子模块 getter/getter-use 2.4.2. getter 工程 pom文件 代码语言javascript 复制 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIddemo/artifactIdgroupIdcom.example/groupIdversion0.0.1-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdgetter/artifactIddependencies!– 注解执行器依赖jar –dependencygroupIdcom.sun/groupIdartifactIdtools/artifactIdversion1.6.0/versionscopesystem/scopesystemPath${java.home}/../lib/tools.jar/systemPath/dependency!– 编译注解执行注册 –dependencygroupIdcom.google.auto.service/groupIdartifactIdauto-service/artifactIdversion1.0.1/version/dependency/dependencies /project自定义 GetterTest 注解 代码语言javascript 复制 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** author zcy1/ Retention(RetentionPolicy.SOURCE) Target(ElementType.TYPE) public interface GetterTest { }GetterTest 编译注解处理器 GetterProcessor 代码语言javascript 复制 import com.google.auto.service.AutoService; import com.sun.source.tree.Tree; import com.sun.tools.javac.api.JavacTrees; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator; import com.sun.tools.javac.util.;import javax.annotation.processing.; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic; import java.util.Set;/** author zcy1/ AutoService(Processor.class) //谷歌工具包方式:注册注解处理器 SupportedSourceVersion(SourceVersion.RELEASE_8) SupportedAnnotationTypes(GetterTest) public class GetterProcessor extends AbstractProcessor {/** 用于在编译器打印消息的组件/private Messager messager;/** 提供待处理抽象语法树/private JavacTrees trees;/** 用来构造语法树节点/private TreeMaker treeMaker;/** 用于创建标识符的对象/private Names names;/** 获取一些注解处理器执行处理逻辑时一些关键对象* param processingEnv 处理环境/Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);this.messager processingEnv.getMessager();this.trees JavacTrees.instance(processingEnv);Context context ((JavacProcessingEnvironment) processingEnv).getContext();this.treeMaker TreeMaker.instance(context);this.names Names.instance(context);}Overridepublic boolean process(Set? extends TypeElement annotations RoundEnvironment roundEnv) {// 获取自定义GetterTest注解的类Set? extends Element elementsAnnotatedWith roundEnv.getElementsAnnotatedWith(GetterTest.class);elementsAnnotatedWith.forEach(e - {JCTree tree trees.getTree(e);tree.accept(new TreeTranslator() {Overridepublic void visitClassDef(JCTree.JCClassDecl jcClassDecl) {ListJCTree.JCVariableDecl jcVariableDeclList List.nil();// 在抽象树中找出所有的成员变量for (JCTree jcTree : jcClassDecl.defs) {if (jcTree.getKind().equals(Tree.Kind.VARIABLE)) {JCTree.JCVariableDecl jcVariableDecl (JCTree.JCVariableDecl) jcTree;jcVariableDeclList jcVariableDeclList.append(jcVariableDecl);}}// 对于变量进行生成getter方法的操作jcVariableDeclList.forEach(jcVariableDecl - {messager.printMessage(Diagnostic.Kind.NOTE jcVariableDecl.getName() has been processed);jcClassDecl.defs jcClassDecl.defs.prepend(createGetterMethod(jcVariableDecl));});super.visitClassDef(jcClassDecl);}});});return true;}private JCTree.JCMethodDecl createGetterMethod(JCTree.JCVariableDecl jcVariableDecl) {ListBufferJCTree.JCStatement statements new ListBuffer();// 生成表达式 this.name nameJCTree.JCExpressionStatement aThis makeAssignment(treeMaker.Select(treeMaker.Ident(names.fromString(this)) jcVariableDecl.getName()) treeMaker.Ident(jcVariableDecl.getName())); statements.append(aThis);JCTree.JCBlock block treeMaker.Block(0 statements.toList());// 生成入参 (String name)JCTree.JCVariableDecl param treeMaker.VarDef(treeMaker.Modifiers(Flags.PARAMETER)jcVariableDecl.getName() jcVariableDecl.vartype null);ListJCTree.JCVariableDecl parameters List.of(param);// 生成返回对象 voidJCTree.JCExpression methodType treeMaker.Type(new Type.JCVoidType());//生成方法名 getNameName methodName getMethodName(jcVariableDecl.getName());// 返回语法树对象return treeMaker.MethodDef(treeMaker.Modifiers(Flags.PUBLIC)methodName methodType List.nil()parameters List.nil() block null);}/** 驼峰方法名*/private Name getMethodName(Name name) {String s name.toString();return names.fromString(get s.substring(0 1).toUpperCase() s.substring(1 name.length()));}private JCTree.JCExpressionStatement makeAssignment(JCTree.JCExpression lhs JCTree.JCExpression rhs) {return treeMaker.Exec(treeMaker.Assign(lhs rhs));} }2.4.4 getter-use工程 pom 文件 引入getter工程 代码语言javascript 复制 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIddemo/artifactIdgroupIdcom.example/groupIdversion0.0.1-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdgetter-use/artifactIddependenciesdependencygroupIdcom.example/groupIdartifactIdgetter/artifactIdversion0.0.1-SNAPSHOT/version/dependency/dependencies /projectPersonDTO 使用GetterTest 代码语言javascript 复制 GetterTest public class PersonDTO {private String name;private Integer age; }2.5.5 项目进行编译 getter 模块下自动生成注册器 getter-use 模块下 PersonDTO.class 可见生成了对应属性的 get 方法 3.总结 本文通过以上对 Lombok 相关介绍通过对 JAVA 文件编译过程分析和 JSR269 实现的方式 基于这个规范然后引申出 Lombok 实现原理过程介绍以及手动实现 getter 案例想必我们对 Lombok 原理也有了相应的了解。虽然 Lombok 提供了许多便利由于生成的代码不在源文件中可见就会导致代码的可读性和维护性较差。在工作中 Lombok 使用时注意闭坑 问题 解决 Data 和 Builder 一起使用时无参构造方法会被干掉 手动加上注解: AllArgsConstructor、NoArgsConstructor。 Builder 导致类属性默认值无效。 有默认值属性上加注解 : lombok.Builder.Default。 Data 生成的 toString 方法默认能不输出父类属性 子类添加: ToString(callSuper true)。
    参考文献 Lombok 官网地址: https://projectlombok.org JavaParser 源码地址: https://github.com/javaparser/javaparser JAVA 抽象语法树 AST 浅析与使用: https://www.freesion.com/article/4068581927/