文章目录
背景:我们都知道,在正常情况下,我们无法去变更二方,三方包中源码的Java文件的内容,但是在某些场景下,我们又希望可以去改动源码中的java文件中的代码,让其最终编译出来以后加载到Jvm当中的是我们改动以后的文件,那么有这样的一种方式可以做到,就是AbstractProcessor,下面给大家看一个例子,原理就是AbstractProcessor提供了一个process的抽象方法,允许你在应用的编译期进行一些处理,在你的Java文件还未编译成class文件时,你可以利用这种机制去更改Java文件,使得应用最终加载到Jvm中的class文件是你更改以后的文件,以此来达到更改源码文件内容的效果
Step1 项目准备
准备一个SpringBoot应用与一个父子模块的应用,目录结构如下
SpringBoot应用:
父子模块的应用(主要是为了在这个模块中开发AbstractProcessor二方包,让SpringBoot引用):
Step2 开发一个自定义的AbstractProcessor
首先因为AbstractProcessor本身是属于jdk的rt包总的内容,所以不需要额外引入。但是需要引入如下依赖
这个依赖主要是为了使得应用可以自动生成META-INF/services/javax.annotation.processing.Processor文件的,这个文件是为了激活我们自己定义的AbstractProcessor,是必不可少的。
然后我们再定义一个注解,这个注解是为了可以在AbstractProcessor的process让我们去识别处理的,可以理解为触发机制,比如我标注了这个注解,那么才需要去做一些编译期的替换内容的动作
整体的目录结构如下,@CompileTag注解的内容则是我们自定义的一些内容了,比如我可以设计一个源文件字段,一个目标文件字段,编译期想做的事情就是去把这两个文件做一个替换等等
那么接下来再看看我们自定义的编译器Processor是长啥样的
@SupportedAnnotationTypes标识了这个编译器所支持的注解
@SupportedSourceVersion标识了这个编译器所支持的Java版本
@AutoService(Processor.class)则是为了生成META-INF/services/javax.annotation.processing.Processor文件的注解
那么核心其实就是在prosess方法里面的逻辑了,这个就是要自己开发拉
Step3 Debug AbstractProcessor替换源码内容
当我们开发完以后就要去debug我们的处理器,看是否有生效了,我们在demoSync中引入shutdown的二方包,这样就引入了我们对应的处理器,然后在应用中打上CompileTag注解,方便识别
debug方式:
第一步:在idea的terminal控制台输入mvnDebug clean install进行回车,会看到如下界面
第二步:创建一个连接8000端口的Jvm Debug进程
然后运行该debug,并且在自己的processor方法处打上断点,不一会儿就可以看到断点进来了
运行SpringBoot应用测试源码内容是否成功替换
我自己的话是实验了一下在org.springframework.boot.autoconfigure.jdbc.DataSourceProperties的afterPropertiesSet方法执行处多执行一行代码,日志做一个打印,是有正确输出的,因此还是比较有成就感的哈哈