Reputation: 147
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
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