我正在使用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()。
驱动程序应用程序:
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(); }