团结源码阐明 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;
}
}
/**
* @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";
}
}
/**
* @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";
}
}
<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" />
<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.foo.service.processor.PrintTimeProcessor"/>
迁移至 spring.xml 中,发明 Service 层与 Controller 层的注解切面均可正常运行。WHY???
从源码的角度探究该问题
由于源码中的要领较长,所以只贴出重点且与主题相关的代码。发起团结当地源码一起看。
Web 项目标进口是 web.xml,所以咱们从它开始。
<!-- Spring Config -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-config.xml</param-value>
</context-param>
<!-- SpringMvc Config -->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>