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