有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带注释字段的java Spring AOP切入点表达式

是否可以捕获带有特定注释的任何字段?我的最终目标是向该字段中注入一个值,但目前我的切入点是错误的(不确定语法是否正确)

@Pointcut("execution(* *(..)) && @annotation(com.mycompany.MyAnnotation)")
private void annotatedField(){}

@Around("annotatedField()")
public Object injectValue(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {}

我相信切入点是用注释说明任何方法。我想把它改成任何领域


共 (1) 个答案

  1. # 1 楼答案

    我认为你应该遵循Sotirios Delimanolis的建议,尽可能地使用Spring车载方式。如果您仍然认为它们不够充分,并且绝对希望使用方面来实现您的想法,那么您可以使用AspectJ within Spring而不是Spring AOP,并利用get()set()等切入点的全部功能来拦截类成员(静态和非静态)上的读/写操作。例如:

    标记注释:

    package de.scrum_master.app;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface MyAnnotation {}
    

    驱动程序应用程序:

    应用程序读取(toString())并写入(构造函数、主方法)所有字段,其中包括带注释的status字段

    package de.scrum_master.app;
    
    public class Application {
        private int id;
        private String name;
        @MyAnnotation private String status;
    
        public Application(int id, String name, String status) {
            this.id = id;
            this.name = name;
            this.status = status;
        }
    
        @Override
        public String toString() {
            return "Application [id=" + id + ", name=" + name + ", status=" + status + "]";
        }
    
        public static void main(String[] args) {
            Application application = new Application(11, "AspectJ demo", "starting");
            System.out.println(application);
            application.id = 22;
            application.name = "AspectJ field access demo";
            application.status = "running";
            System.out.println(application);
            application.status = "shutting down";
            System.out.println(application);
            application.status = "stopped";
            System.out.println(application);
        }
    }
    

    方面:

    package de.scrum_master.aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    
    @Aspect
    public class AnnotatedFieldAspect {
        @Before("get(* *) && @annotation(de.scrum_master.app.MyAnnotation)")
        public void interceptRead(JoinPoint thisJoinPoint) {
            System.out.println(thisJoinPoint);
        }
    
        @Before("set(* *) && @annotation(de.scrum_master.app.MyAnnotation) && args(newValue)")
        public void interceptWrite(JoinPoint thisJoinPoint, Object newValue) {
            System.out.println(thisJoinPoint + " -> " + newValue);
        }
    }
    

    控制台日志:

    set(String de.scrum_master.app.Application.status) -> starting
    get(String de.scrum_master.app.Application.status)
    Application [id=11, name=AspectJ demo, status=starting]
    set(String de.scrum_master.app.Application.status) -> running
    get(String de.scrum_master.app.Application.status)
    Application [id=22, name=AspectJ field access demo, status=running]
    set(String de.scrum_master.app.Application.status) -> shutting down
    get(String de.scrum_master.app.Application.status)
    Application [id=22, name=AspectJ field access demo, status=shutting down]
    set(String de.scrum_master.app.Application.status) -> stopped
    get(String de.scrum_master.app.Application.status)
    Application [id=22, name=AspectJ field access demo, status=stopped]