【发布时间】:2020-04-23 08:31:42
【问题描述】:
我正在使用 spring aop,我发现有 3 种情况,但我不太清楚: 情况 1:单个类不实现或扩展任何类或接口 在这种情况下,任何非私有方法都将成为连接点
情况2:类实现接口,实现方法 在这种情况下,只有在接口中声明的方法才会是连接点
情况3:一个类扩展了一个超类并覆盖了超类的方法 在这种情况下,所有子类的方法都不会是连接点。
spring 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() 不能建议。
对不起,由于IDEA的提示,我犯了一个错误。 IDEA's hint
【问题讨论】:
-
AOP 将作用于您在 PointCut 正则表达式中指定的位置!
-
是的,但有一些限制,例如,我不能建议从另一个类扩展的类方法。
-
如何调用方法
function1()、function2()和functionSubJdkProxy()?如果可以调用这些方法,则可以拦截所有 3 个方法。您能否分享调用这些方法的代码以便拦截调用? -
对我来说,您的代码也可以正常工作。你必须犯一个配置错误。所以请展示你如何启动和配置你的应用程序。
标签: java spring spring-aop