1
votes

I am trying to implement AOP concept using Spring Boot. But before annotation is not working. This is my code,

POM.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Application.properties

server.port=6500
spring.aop.proxy-target-class=true

Main:

package com.techno.theater;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.techno.theater.services.SampleService;

@SpringBootApplication
public class DigitalTheaterApplication {

     private static  Logger logger=LoggerFactory.getLogger(DigitalTheaterApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DigitalTheaterApplication.class, args);
        new SampleService().sample();

    }
}

Sample Service:

package com.techno.theater.services;

import org.springframework.stereotype.Service;

@Service
public class SampleService {
    public void sample(){
        System.out.println("Sample method inovking");
    }
}

Aspect class

package com.techno.theater.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AspectService {

    @Before("execution(* com.techno.theater.services.SampleService.sample())")
    public void beforeSampleMethod() {
        System.out.println("Sample method aspect");
    }

}

Here I am invoking sample method from DigitalTheaterApplication class but before execute this method my aspect method should be executed but it's not working am not sure do I need to add some configuration.

1
Works as it should. You are creating a new instance yourself, you should use the instance created by the application context. - M. Deinum

1 Answers

6
votes
public static void main(String[] args) {
    SpringApplication.run(DigitalTheaterApplication.class, args);
    new SampleService().sample();
}

The code above is the problem, to be precise the new SampleService().sample(); is what is flawed in your code. You are creating a new instance outside the scope of Spring and as such it will not be exposed to AOP.

Instead what you should do, is retrieve the SampleService from the ApplicationContext.

public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(DigitalTheaterApplication.class, args);
    ctx.getBean(SampleService.class).sample();
}

This will get the Spring created, and proxied, instance, with AOP applied.

Another way, without messing around with the ApplicationContext is to create a CommandLineRunner which will be executed during startup.

public static void main(String[] args) {
    SpringApplication.run(DigitalTheaterApplication.class, args);
}

@Bean
public CommandLineRunner tester(SampleService service) {
    return args -> service.sample();
}

Something like that will also invoke the sample method on the Spring managed instance without having to get it yourself.