【发布时间】:2021-09-16 10:46:01
【问题描述】:
我有一个关于使用aspectJ和spring aop方法拦截的问题。我创建了 2 个注解:@AJTest 和 @SAOPTest。
package com.test.company;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AJTestAspect {
@Pointcut("@annotation(AJTest)")
public void aJTest() {
}
@Around("aJTest()")
public Object profile(ProceedingJoinPoint joinPoint) throws Throwable {
final long start = System.currentTimeMillis();
try {
return joinPoint.proceed();
} finally {
long finish = System.currentTimeMillis() - start;
System.out.println("Method execution time: " + (start - finish));
}
}
}
注册了
package com.test.company;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AJConfiguration {
@Bean
public AJTestAspect ajTestAspect() {
return new AJTestAspect();
}
}
其他
package com.test.company;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class SAOPInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("Number of parameters " + methodInvocation.getArguments().length);
return methodInvocation.getMethod().invoke(methodInvocation.getThis(), methodInvocation.getArguments());
}
}
并注册
package com.test.company;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties
public class SpringSAOPTestConfiguration {
@Bean
public Advisor springAopTestAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("@annotation(com.test.company.SAOPTest)");
return new DefaultPointcutAdvisor(pointcut, new SAOPInterceptor());
}
}
并将其添加到我在控制器中的方法中
package com.test.company;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@SAOPTest
@AJTest
@GetMapping("/test")
public String doSomething(@RequestParam("firstParam") String firstParam, @RequestParam("secondParam") Integer secondParam) throws InterruptedException {
Thread.sleep(2_500);
return firstParam + " " + secondParam;
}
}
应用类
package com.test.company;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy
@SpringBootApplication
public class AopTestApplication {
public static void main(String[] args) {
SpringApplication.run(AopTestApplication.class, args);
}
}
但是当我通过http://localhost:8080/test?firstParam=test&secondParam=2 调用它时,我看不到方法执行时间的消息,但可以看到传递给方法的参数数量。如果我将删除 @SAOPTest - 方法的执行时间按预期工作,但它不适用于两个注释。是spring创建的代理对象的问题,还是我遗漏了什么?
【问题讨论】:
-
你可以尝试在切入点表达式中使用注释的完整路径。示例:
@annotation(xxx.yyy.abc.AJTest) -
同一个包中的所有类,但它不能正常工作
@Pointcut("@annotation(com.test.company.AJTest)") -
你是怎么运行这个的?你有多个配置?那些是如何加载的?这是 Spring Boot 还是普通 Spring 或 ... 对于
@AspectJ,您还需要在配置中使用@EnableAspectJAutoProxy(如果这不是 Spring Boot 应用程序)。 -
这是带有 1 个端点的示例的 spring-boot 演示项目
-
请在您的源代码中包含软件包并包含您的
@SpringBootApplication注释类。
标签: java spring spring-boot aspectj spring-aop