Hossein
Hossein

Reputation: 147

@annotaion in Aspect Oriented Programming

I want to print "Welcome to AOP" on the console whenever a method has a custom annotation. For doing that, I have used @annotation, but it does not seem to work in my code. Does anyone know the reason of it?

My custom annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Greeting {
}

Student class using the annotation:

public class Student {
    private String name;
    private String familyName;

    public Student(String name, String familyName) {
        super();
        this.name = name;
        this.familyName = familyName;
    }

    @Greeting
    public String getFullName() {
        return this.name + " " + this.familyName;
    }
}

Aspect config class:

@Configuration
@EnableAspectJAutoProxy
@Aspect
public class AspectConfig {
    @Before("execution(* com.example.demo..*.* (..)) && @annotation(com.example.demo.Greeting)")
    public void logBeforeAllMethods() {
        System.out.println("Welcome to AOP");
    }

and finally my rest controller

@RestController
public class Test {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String mainPage() {
        Student student = new Student("X", "Y");
        String r =  student.getFullName();
        return r;
    }
}

Upvotes: 0

Views: 76

Answers (1)

R.G
R.G

Reputation: 7121

For Spring AOP to work here , the Student should be a spring managed bean . Either annotate the class with @Component and include in the component scan or from a @Configuration class declare it as a bean using @Bean annotation

When new operator is used the Student instance created is not a spring container managed bean.

Update

You may also restructure the classes . For Example , the Aspect may be moved to a different class of its own . A configuration class is better left to have only configuration entries.

@Aspect
@Component
public class GreetingAspect {
    @Before("execution(* com.example.demo..*.* (..)) && @annotation(com.example.demo.Greeting)")
    public void logBeforeAllMethods() {
        System.out.println("Welcome to AOP");
    }
}

and the configuration class as follows

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackageClasses= {Student.class,GreetingAspect.class})
public class AppConfig {

}

Also the Student bean can be of scope prototype

@Component
@Scope(scopeName="prototype")
public class Student {
    private String name;
    private String familyName;

    public Student(String name, String familyName) {
        super();
        this.name = name;
        this.familyName = familyName;
    }

    @Greeting
    public String getFullName() {
        return this.name + " " + this.familyName;
    }
}

and obtain the Student bean from the application context.

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    ApplicationContext ctx;

    @Override
    public void testStudent(String name, String familyName) {
        Student student = ctx.getBean(Student.class,name,familyName);
        student.getFullName();
    }

}

Upvotes: 1

Related Questions