spring aop可以建议哪种方法,或者spring aop连接点的限制是什么?

问题描述 投票:0回答:1

我正在使用spring aop,但发现有3种情况,但我不太清楚:情况1:一个没有实现或扩展任何类或接口的类在这种情况下,任何非私有方法都将成为连接点

情况2:一个类实现一个接口并实现方法在此结果中,仅在interface中声明的方法将是连接点

情况3:一个类扩展了超类并覆盖了超类的方法在这种缝合中,所有子类的方法都不会成为连接点。

弹簧aop是如何设计的?

这是我使用的代码:

JdkProxyInterface.java

package com.example.proxytestdemo;

public interface JdkProxyInterface {

    void function(int i);
}

JdkProxy.java

package com.example.proxytestdemo;
import org.springframework.stereotype.Component;

@Component
public class JdkProxy implements JdkProxyInterface {

    @Override
    @TimeIt
    public void function(int i) {
        System.out.println("JdkProxy function");
    }

    @TimeIt
    public void function1(int i) {
        System.out.println("JdkProxy function");
    }

    @TimeIt
    public void function2(int i) {
        System.out.println("JdkProxy function");
    }

}

SubJdkProxy.java

package com.example.proxytestdemo;

import org.springframework.stereotype.Component;

@Component
public class SubJdkProxy extends JdkProxy {

    @TimeIt
    public void functionSubJdkProxy(int i) {
        System.out.println("functionSubJdkProxy");
    }
}

TimeIt.java

package com.example.proxytestdemo;
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Inherited
public @interface TimeIt {
    boolean enabled() default true;
}

TimePointCut.java

package com.example.proxytestdemo;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;


@Aspect
@Component
public class TimePointCut {

    @Pointcut("execution(* com.example.proxytestdemo..*(..))")
    public void calcTime1() {
    }

    @Around(value = "calcTime1()")
    public Object aspectProcess(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("proxy begin....... ");
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        TimeIt annotation = method.getAnnotation(com.example.proxytestdemo.TimeIt.class);
        if (annotation == null) {
            annotation = pjp.getTarget().getClass().getAnnotation(TimeIt.class);
            if (annotation == null) {
                for (Class<?> cls : pjp.getClass().getInterfaces()) {
                    annotation = cls.getAnnotation(TimeIt.class);
                    if (annotation != null) {
                        break;
                    }
                }
            }
        }
        if (annotation != null) {
            System.out.println(annotation.enabled());
        }
        Object o = null;
        long t1 = 0, t2 = 0;
        try {
            t1 = System.currentTimeMillis();
            o = pjp.proceed();
            t2 = System.currentTimeMillis();
        } catch (Exception e) {
            throw e;
        } finally {
            System.out.println("proxy end....... ");
            System.out.println("time cost: "+ (t2-t1)/1000 + "s");
        }

        return o;
    }
}

我发现不建议使用JdkProxy.function1()和JdkProxy.function2()以及SubJdkProxy.functionSubJdkProxy()。

java spring spring-aop
1个回答
0
投票
您的应用程序应该可以运行。看,我尝试了各种组合,它们都起作用:

驱动程序应用程序:

package com.example.proxytestdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { try (ConfigurableApplicationContext context = SpringApplication.run(Application.class, args)) { doStuff(context); } } private static void doStuff(ConfigurableApplicationContext context) { JdkProxy jdkProxy = (JdkProxy) context.getBean("jdkProxy"); jdkProxy.function(11); jdkProxy.function1(22); jdkProxy.function2(33); System.out.println("----------"); JdkProxyInterface jdkProxyInterface = jdkProxy ; jdkProxyInterface.function(11); System.out.println("=========="); SubJdkProxy subJdkProxy = (SubJdkProxy) context.getBean("subJdkProxy"); subJdkProxy.function(11); subJdkProxy.function1(22); subJdkProxy.function2(33); subJdkProxy.functionSubJdkProxy(44); System.out.println("----------"); jdkProxyInterface = subJdkProxy; jdkProxyInterface.function(11); } }

控制台日志:

execution(void com.example.proxytestdemo.JdkProxy.function(int)) JdkProxy function execution(void com.example.proxytestdemo.JdkProxy.function1(int)) JdkProxy function execution(void com.example.proxytestdemo.JdkProxy.function2(int)) JdkProxy function ---------- execution(void com.example.proxytestdemo.JdkProxy.function(int)) JdkProxy function ========== execution(void com.example.proxytestdemo.JdkProxy.function(int)) JdkProxy function execution(void com.example.proxytestdemo.JdkProxy.function1(int)) JdkProxy function execution(void com.example.proxytestdemo.JdkProxy.function2(int)) JdkProxy function execution(void com.example.proxytestdemo.SubJdkProxy.functionSubJdkProxy(int)) functionSubJdkProxy ---------- execution(void com.example.proxytestdemo.JdkProxy.function(int)) JdkProxy function
顺便说一句,为了专注于基础知识,我将您方面的建议方法简化为:

@Around(value = "calcTime1()") public Object aspectProcess(ProceedingJoinPoint pjp) throws Throwable { System.out.println(pjp); return pjp.proceed(); }

© www.soinside.com 2019 - 2024. All rights reserved.