我想在@RequestMapping方法调用下面做AOP,注意hello()方法是 NOT public。
@RestController
class HelloController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
String hello() {
return "Hello";
}
}
这是主要类,我添加了@Aspect,@ EnableAspectJAutoProxy注释。
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
@SpringBootApplication
public class FooServiceApplication {
public static void main(String[] args) {
SpringApplication.run(FooServiceApplication.class, args);
}
@Around("@annotation(requestMapping)")
public Object around(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {
return pjp.proceed();
}
}
pom.xml中的我只是添加下面的依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
结果是,如果hello()方法是公共的,AOP将正常工作,但如果与上面的例子相同而没有公开声明,则AOP根本不起作用。但是, EnableAspectJAutoProxy 是否会使用CGLIB并拦截受保护/私有方法调用?
答案 0 :(得分:2)
根据documentation Spring的基于代理的AOP只能拦截public
方法
由于Spring的AOP框架基于代理的特性,根据定义,受保护的方法既不是针对JDK代理(这不适用),也不针对CGLIB代理(这在技术上可行,但不建议用于AOP)目的)。因此,任何给定的切入点都只能与公共方法匹配!
如果您的拦截需要包括受保护/私有方法甚至构造函数,请考虑使用Spring驱动的本机AspectJ编织而不是Spring的基于代理的AOP框架。这构成了具有不同特征的不同AOP使用模式,因此在做出决定之前一定要先熟悉编织。
在决定使用AspectJ编织之前,我建议您通过文档中的appropriate section来帮助您做出决定。
根据您希望实现的目标,您还可以考虑使用Filter
s。
过滤器拦截每个请求,并且有权添加/删除标头,验证,登录等;通常执行通用/应用程序范围的操作。
添加一个只需声明一个类
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class SomeFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
/*execute your logic*/
if (/* request may proceed*/) {
chain.doFilter(request,response);
} else {
/* write response */
}
}
}