面向方面编程中的@annotaion

@annotaion in Aspect Oriented Programming

只要方法具有自定义注释,我就想在控制台上打印 "Welcome to AOP"。为此,我使用了@annotation,但它似乎在我的代码中不起作用。有谁知道原因吗?

我的自定义注释:

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

学生 class 使用注释:

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

方面配置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");
    }

最后是我的休息控制器

@RestController
public class Test {

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

要使 Spring AOP 在这里工作,Student 应该是一个 spring 托管 bean。使用 @Component 注释 class 并包含在组件扫描中,或者从 @Configuration class 中使用 @Bean 注释

将其声明为 bean

当使用 new 运算符时,创建的 Student 实例不是 spring 容器管理的 bean。

更新

您也可以重组 classes 。 例如,方面可能会移动到它自己的不同 class。配置 class 最好只保留配置条目。

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

和配置class如下

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

}

Student bean 也可以是 scope 原型

@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;
    }
}

并从应用程序上下文中获取 Student bean。

@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();
    }

}