原文出处:
Fooisart
结合源码分析 Spring 容器与 SpringMVC 容器之间的关系
问题
问题描述:项目中发现,自定义切面注解在 Controller 层正常工作,在 Service 层却无法正常工作。为了便于分析,去掉代码中的业务逻辑,只留下场景。
自定义注解,打印时间
/** * Description: 自定义打印时间的注解 * Created by jiangwang3 on 2018/5/9. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Documented public @interface PrintTime { }
注解解析器
/** *Description:打印时间注解的解析器 * @author jiangwang * @date 11:28 2018/5/14 */ @Aspect public class PrintTimeProcessor { private Logger LOGGER = LoggerFactory.getLogger(getClass()); @Pointcut("@annotation(com.foo.service.annotation.PrintTime)") public void printTimePoint() { } @Around("printTimePoint()") public Object process(ProceedingJoinPoint jp) throws Throwable{ System.out.println(); LOGGER.error("开始运行程序。。。Start==>"); Object proceed = jp.proceed(); LOGGER.error("结束啦,运行结束==>"); System.out.println(); return proceed; } }
Controller层
/** * @author jiangwang * @date 2018/5/14 */ @RestController @RequestMapping(value = "/user") public class UserController { private Logger logger = LoggerFactory.getLogger(getClass()); @Resource private UserService userService; @RequestMapping(value = "/serviceAspect", method={RequestMethod.GET}) public String serviceAspect(){ return userService.serviceAspect(); } @RequestMapping(value = "/controllerAspect", method={RequestMethod.GET}) @PrintTime public String name(){ logger.info("Controller层----测试切面"); return "controllerAspect"; } }
Service层
/** * @author jiangwang * @date 11:34 2018/5/14 */ @Service public class UserService { private Logger logger = LoggerFactory.getLogger(getClass()) @PrintTime public String serviceAspect(){ logger.info("Service层---测试切面"); return "serviceAspect"; } }
spring.xml 配置文件,主要部分
<context:annotation-config /> <!-- 动态代理开启 --> <aop:aspectj-autoproxy proxy-target-class="true" /> <context:component-scan base-package="com.foo" > <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 公共配置引入 --> <import resource="classpath:spring/spring-config-dao.xml" />
springmvc.xml 配置文件,主要部分
<mvc:annotation-driven /> <mvc:default-servlet-handler /> <!-- 动态代理开启 --> <aop:aspectj-autoproxy proxy-target-class="true" /> <!-- mvc controller --> <context:component-scan base-package="com.foo.web.controller" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan> <bean class="com.foo.service.processor.PrintTimeProcessor"/>
以上为主要代码。项目运行之后,发现在 Service 层的注解切面未生效,而在 Controller 层正常。而当我将 springmvc.xml 中的
<bean class="com.