Spring MVC集成Spring AOP无报错但不生效,请求排查问题
我来帮你梳理下可能导致AOP不生效的几个核心关键点,你可以逐一排查验证:
1. 切入点表达式匹配范围问题
你的@Pointcut只写了方法签名,没有指定目标类的全限定名,Spring无法精准定位到控制器里的getHomePage方法。建议把切入点表达式修改为包含完整类路径的形式:
@Pointcut("execution(protected ModelAndView com.samik.controller.Main.getHomePage())")
如果想匹配控制器包下所有符合规则的方法,也可以用通配符简化:
@Pointcut("execution(protected ModelAndView com.samik.controller.*.*())")
2. Spring AOP对方法访问修饰符的限制
Spring AOP默认优先使用JDK动态代理(当目标类实现接口时),而JDK动态代理只能拦截public方法。你的控制器方法是protected,即便Spring切换到CGLIB代理(目标类无接口时),默认配置下也不会拦截非public方法。
最直接的解决方式是把控制器方法的访问修饰符改为public:
@RequestMapping(value="/Home.html", method = RequestMethod.GET) public ModelAndView getHomePage(){ ModelAndView modelAndView = new ModelAndView("content/home/Home"); return modelAndView; }
同时同步更新切入点表达式:
@Pointcut("execution(public ModelAndView com.samik.controller.Main.getHomePage())")
3. 确认AOP命名空间是否正确声明
你的配置里用了<aop:aspectj-autoproxy>标签,但要确保XML头部已经正确声明AOP命名空间和对应的Schema地址,否则该标签不会生效:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
4. 确认切面与控制器的容器一致性
Spring的DispatcherServlet子容器和根容器(applicationContext)是相互独立的,如果你的切面类配置在根容器,而控制器在DispatcherServlet子容器中,AOP代理无法跨容器作用到控制器。建议把切面的<bean>配置和<aop:aspectj-autoproxy>标签都放在DispatcherServlet的配置文件中,和控制器配置保持在同一个容器内。
5. 验证代理类是否生成
可以在控制器的构造方法中添加一行打印代码,查看当前类是否为代理类:
public Main() { System.out.println("当前类:" + this.getClass().getName()); }
如果输出的类名包含$Proxy(JDK代理)或$$EnhancerByCGLIB$$(CGLIB代理),说明代理已生成;如果是原始类名,那就要回到前面的配置步骤重新检查。
按照上述步骤逐一排查,应该就能解决AOP未生效的问题了。
内容的提问来源于stack exchange,提问作者Samik_htik

