1 xml代码
在springmvc
中,我们经常配置两个xml
,一个spring
专属,一个springMVC
专属,在这两个xml
中我们都可以配置bean
的自动扫描。
一般我们在spring.xml
中不扫描@Controller
注解,在springmvc.xml
中不扫描@service
和@Repository
在主容器中(applicationContext.xml
),将Controller
的注解排除掉
<context:component-scan base-package="com">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
而在springMVC
配置文件中将Service
注解给去掉
<context:component-scan base-package="com">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
2 原因说明
2.1 俩容器关系
Spring
容器和springmvc
容器的关系点击此处看详细说明
Spring
和springmvc
和作为两个独立的容器,会把扫描到的注解对象分别放到两个不同的容器中,Springmvc
容器是spring
容器的一部分,它们访问对象的范围如下所示:
springmvc
子容器可以访问spring
父容器中的对象spring
父容器不能访问springmvc
子容器中的对象
2.2 全部放到spring.xml
如果全部把注解放到spring.xml
中配置会怎么样?
当一旦采用这种方式之后,spring
会将扫描的对象都会存放到spring
的容器,而不会放到springmvc
子容器中,当访问项目的时候,springmvc
找不到处理器映射器,和其对应的Controller
,进而报404错误!
2.3 全部放到springmvc.xml
如果不用spring
容器,把注解全部放到springmvc
中扫描会怎么样?
这个是可以的,在这个里面可以同时扫描Controller
层、service
层、dao
层的注解
但是,子容器Controller
进行扫描装配时装配了@Service
注解的实例,而该实例理应由父容器
进行初始化以保证事务的增强处理(因为事务管理器是配置在spring
容器中的),所以此时得到的将是原样的Service
(没有经过事务加强处理,故而没有事务处理能力
。)
同理,springmvc
中配置controller
后也不能将事务配置在controller
层,因为事务管理器是配置在spring
容器中的,如果将事务配置在Controller
层的话,spring
容器因为不能访问springmvc
子容器,进而无法访问到事务对象。进而导致事务失效。