AOP with Spring

I am still working with the Boot Spring Web Application that in the previous post has got concrete Knight and Quest. By injection, the app knows which Knight has to be used the the RESTful service is consumed, and similarly the Knight knows which is his quest.

In this post I add a Minstrel, whose task is singing a song when a knight starts and ends a quest. Following the idea that we don't know to create tight connections between components, we are going to use an Aspect Oriented Programming (AOP) design, treating Minstrel as an aspect of our application.

AOP suggests to let Knight unaware of the Minstrel existence. I could have left the Knight code as was before Minstrel entered the game, I just added logging to let see better how the execution stream passes from Knight to Minstrel.

However there is some job to be done to let a Spring application using AOP. Fistly, I have to add a dependency to the spring-boot-starter-aop artifact, group id org.springframework.boot, in the application POM file.

Moreover, Spring should know about the aspects I want to use in the app. This could be done by an XML or a Java class, in the AspectJ configuration style. I followed the second way, creating this SpringInActionConfig class:
@Configuration
@EnableAspectJAutoProxy
public class SpringInActionConfig {
    @Bean
    public Minstrel minstrel() {
        return new Minstrel();
    }
}

I have implemented Minstrel using the Spring AspectJ support:
@Aspect
public class Minstrel {
    private final Log log = LogFactory.getLog(Minstrel.class);

    @Before("execution(public String Knight.doQuest())")
    public void singBeforeQuest() {
        log.info("Fa la la, the knight is so brave!");
    }

    @After("execution(public String Knight.doQuest())")
    public void singAfterQuest() {
        log.info("Tee hee hee, the brave knight did embark on a quest!");
    }
}
The aspect Minstrel has a method annotated as Before, with the specification that is related to the execution of the Knight doQuest() method, and another one annotated as After, again referring to the same Knight method.

Running the application we should see a change in its log:

Before and after the knight doQuest() execution, the minstrel methods are executed, just as we should have expected.

I have written this post while reading the first chapter of Spring in Action, Fourth Edition by Craig Walls. I have ported the original code to a Maven Spring Boot Web project on the STS IDE, using AspectJ annotations instead of the classic xml configuration.

Full code on github.

No comments:

Post a Comment