如何创建由 gradle 预编译运行的注释处理器以向方法添加代码?



我们有一些代码需要在很多方法中运行,对于我们的开发人员来说,一遍又一遍地编写这些代码是很乏味的(而且我们希望允许调用的 API 能够更改,而无需更改任何使用它的代码(。

我们的想法是在调用此代码的方法上放置一个自定义注释,我们将编写自己的注释处理代码来查找该注释,然后在编译之前将代码添加到方法的末尾(但是当他们在此之后在 IDE 中查看文件时, 代码仍然不会在那里(。

我将如何实现这一目标?我需要做什么才能使 Gradle 调用的东西能够更改传递给编译器/构建器的方法定义并能够读取方法上的注释?

(我们正在使用Spring Boot和Gradle,但这可能不会有什么不同(

Spring AOP 足以满足您的要求。

这是一个小例子,给你一个想法:有两个类,每个类有三个共同的方法:play((,addPlayer((和gameover((,每次调用play方法时,程序都必须调用一个例程来打印文本,使用AOP,你不需要重复相同的代码。

对于组织订单,我将使用一个接口,这不是强制性的,但这是一个很好的做法:

游戏界面:

public interface Game {
void play();
void addPlayer(String name);
void gameOver();
}

实施游戏的足球课

public class Soccer implements Game {
@Override
public void play() {
System.out.println("Soccer Play started");
}
@Override
public void addPlayer(String name) {
System.out.println("New Soccer Player added:" + name);
}
@Override
public void gameOver() {
System.out.println("This soccer Game is Over");
}
}

实现游戏的棒球类

public class Baseball implements Game {
@Override
public void play() {
System.out.println("Baseball game started at " + new Date());
}
@Override
public void addPlayer(String name) {
System.out.println("New Baseball Player added: " +name);
}
@Override
public void gameOver() {
System.out.println("The game is over");
}
}

现在调用播放方法时要捕获的方面配置

@Aspect
@Component
public class AspectConfiguration {
@Before("execution(* org.boot.aop.aopapp.interfaces.Game.play(..))")
public void callBefore(JoinPoint joinPoint){
System.out.println("Do this allways");
System.out.println("Method executed: " + joinPoint.getSignature().getName());
System.out.println("******");
}
}

@Before注释意味着将在执行播放方法之前调用该方法。 此外,您还需要指定一个切入点表达式,告诉Aspect如何匹配您需要触发的方法调用。 例如,在这种情况下,我们使用 play 方法,它是切入点的表达式:"execution(* org.boot.aop.aopapp.interfaces.Game.play(..))"

最后是 Spring Boot 应用程序类:

@EnableAspectJAutoProxy
@SpringBootApplication
public class AopappApplication {
public static void main(String[] args) {
Game soccer=null;
Game baseball=null;
AnnotationConfigApplicationContext ctx = (AnnotationConfigApplicationContext) SpringApplication.run(AopappApplication.class, args);
soccer = (Game) ctx.getBean("soccer");
baseball = (Game) ctx.getBean("baseball");
soccer.play();
baseball.play();
soccer.addPlayer("Player 1");
soccer.addPlayer("Player 2");
baseball.addPlayer("Player 23");
soccer.gameOver();
baseball.gameOver();
}
@Bean("soccer")
public Game soccer(){
return new Soccer();
}
@Bean("baseball")
public Game baseball(){
return new Baseball();
}
}

有一个关于Spring AOP的上帝文档,请参阅以下链接。春季AOP文档

最新更新