Spring容器的父子关系
ContextLoaderListener初始化的上下文和DispatcherServlet初始化的上下文关系:
图片来源:http://jinnianshilongnian.iteye.com/blog/1602617
从图中可以看出:
ContextLoaderListener初始化的上下文加载的Bean是对于整个应用程序共享的,不管是使用什么表现层技术,一般如DAO层、Service层Bean;
DispatcherServlet初始化的上下文加载的Bean是只对Spring Web MVC有效的Bean,如Controller、HandlerMapping、HandlerAdapter等等,该初始化上下文应该只加载Web相关组件。
访问规则:子容器可以访问父容器的对象,父容器不可以访问子容器的对象。
如果子容器加载了service 、dao ,则controller调用service的时候,会调用子容器中的service,但是service 的事务事务是在父容器中设置得,所以会导致事务失效。子容器和父容器的功能时一样的。
为什么要有两个容器??
DispatcherServlet表现层框架,而spring和其他框架也可以整合,Spring扩展性比较好;
xml中通过配置<context:component-scan base-package="com.ty.service"/> ;
<context:component-scan>提供了2个子标签
<context:include-filter>
<context:exclude-filter>
<context:component-scan>如果只想扫描controller,
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
use-default-filter="true":对base-package 包或者子包下的所有@component 或者子类@Service @Reposity 等注册为bean
如果是下面:
<context:component-scan base-package="com.ty"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
上面的代码会扫描Controller 、service等下面类或者子类。
出现上面的问题时因为 <context:include-filter >没有起作用,如果要起作用只需把:use-default-filter=false;
所以如果想要 <context:include-filter> <context:exclude-filter> 这两个起作用,use-default-filter必须设为false.