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

时间:2017-08-02 00:00:09

标签: java spring spring-boot gradle annotations

我们有一些代码需要在很多方法中运行,而且我们的开发人员不得不一遍又一遍地编写这些代码(我们也希望允许所调用的API能够更改,而无需更改任何将使用它的代码)。

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

我将如何实现这一目标?我需要做些什么来制作Gradle调用的东西,能够改变传递给编译器/构建器的方法定义并能够读取方法的注释吗?

(我们正在使用Spring Boot和Gradle,但这可能没什么区别)

1 个答案:

答案 0 :(得分:1)

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");
    }
}

现在要调用play方法时要捕获的Aspect配置

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

最后是Spring Boot Application Class:

@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的神文档请参阅以下链接。 Spring AOP Doc.