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/>这个配置.有些特殊场景才用得上这个配置.

相关推荐