springMVC和spring的包扫描

springmvc 的配置文件 和 spring 的配置文件都可以配置包扫描,如下:

<context:component-scan base-package="com.xxx"/>


一般将controller的扫描配置在springmvc 的配置文件中,将service和dao的扫描配置在spring的配置文件中.
即 springmvc 只扫描controller的包, spring扫描其他组件.

不要让两个扫描有重叠.原因有如下几点(已亲自测试,的确如此):
1, 扫描的类增多, 项目启动时间会延长
2, @PostConstruct 注解标注的方法会执行2次
3, 会使事物失效

对于第三点会使事物失效,原因是什么?
同时使用springmvc 和 spring, 那么项目中就会有两个容器.
spring的是父容器,先进行初始化; springmvc是子容器, 后进行初始化.
springmvc后初始化,会重新创建service对象并重新注入,而springmvc再次创建service对象时不会读取spring的配置文件,因此也就无法知道service层是需要创建代理对象的,所以springmvc创建的service是普通的对象,而不是动态代理对象.

解决重叠扫描的方式
方式1,即上面提到的 springmvc 只扫描controller的包, spring扫描其他组件.
springmvc 配置如下:
<context:component-scan base-package="com.xxx.**.cotroller"/>

springmvc只会扫描com.xxx下任意目录或子目录下的controller包下的类

spring的配置如下:
<context:component-scan base-package="com.xxx.**.service.impl,com.xxx.**.dao"/>


方式2,用<context:include-filter/> 或 <context:exclude-filter/> 指定或排除某些类
假设springmvc扫描如下:
<context:component-scan base-package="com.xxx"/>


spring扫描如下:
<context:component-scan base-package="com.xxx"/>


那么就会重叠,springmvc会扫描service和dao,可以这样修改springmvc的配置:
<context:component-scan base-package="com.xxx">
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context>


用 <context:exclude-filter/> 排除了@Service 和 @Repository 两种注解标注的类,意思是告诉springmvc在扫描时,如果碰到这两个注解标注的类直接忽略,不要创建和注入对象.


方式1比方式2好,扫描的类更少,方式2仅仅是个例子,看起来有点画蛇添足,
故意让springmvc扫描service和dao的包,又告诉他扫描时忽略service和dao,我仅仅是想引出还有<context:include-filter/> 和 <context:exclude-filter/>  这个配置. 有些特殊场景才用得上这个配置.




猜你喜欢

转载自18810098265.iteye.com/blog/2377847