Spring和SpringMVC配置冲突导致事务无法开启
本文原因已经找到,参考文章[最少依赖启动SSM][plus]
[plus]:http://alanli7991.github.io/2016/11/01/从空Pom文件用最少依赖配置SSM框架/
Spring和SpringMVC并不是同一个东西,虽然都是一个公司出的,但是配置上也会冲突导致事务失效
产生冲突的原因
根据配置文件的讲解,必不可少的是扫描component,这里就牵扯到一个问题SpringMVC和Spring都会进行扫描,那谁先谁后呢?
SpringMVC先于Spring进行扫描
我们假设这样的一种情况
后台分层 | 所用包名 | 所用组件 | 所用注解 |
---|---|---|---|
Web层 | com.company.project.web | SpringMVC | @Controller |
Service层 | com.company.project.service | Spring | @Service |
DAL层 | com.company.project.dal | MyBatis | 无 |
根据文章Spring的四个注解解释,@Controller和@Service没有实质上的区别,假如我们使用 com.company.project 作为基础包名配置Spring和SpringMVC就会导致事务失效
会导致失效的SpringMVC的配置
1 | <beans .......> |
会导致失效的Spring的配置
1 | <beans .....> |
推测导致失效的原因
- 因为Tomcat等容器扫描web.xml的时候有先后顺序,推测是先扫描Servlet然后再扫描Context(大概,不确定)
- 使用以上配置导致Servlet加载Component的时候,把Service层的Service也进行了实例化,并且对其加了一系列动态代理
- 由于单例模式的原因,导致Context配置无法自己加载Component而是拿到的Servlet实例化的Component的指针
- 由于没有由Context进行实例化,导致Spring对Context内容的动态代理无法加载
以上原因是我猜的,也没有验证,因为我在反射问题里也遇到了一个类似的问题导致事务失效
解决事务失效的方法
通过面向百度和Google编程,得到了采用 配置文件中互相排除多余的注解 来防止事务失效
正确的SpringMVC配置
在Servlet中不扫描Service的注解
1 | <beans .......> |
正确的Spring配置
在Context中不扫描Controller的注解
1 | <beans .......> |