杂(关于spring容器启动时加载过程的探索)

这两天一直被事务的问题困扰,直到昨天才有突破性的进展,在此记录一下。

在做某业务逻辑的保存时,service的保存方法逻辑是分别对不同的表先后进行保存,而且service方法是加了事务控制的,但在测试过程中发现,即使保存出错,出错点保存的数据没有回滚,数据依旧是插入到相应的表中,也就是说,spring的事务控制没起作用!第一反应是,是不是我的配置有问题,

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref = "dataSource" />
</bean>
</pre><pre name="code" class="html"><tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Execption" />
</tx:attributes>

<aop:config>
<aop:pointcut id="allServiceMethod" expression="execution(* com.ll..service.impl.*.*(..))" />
<aop:advisor advice-ref="txAdvice" point-ref="allServiceMethod" />
</aop:config>

经过与老工程比较,发现这几个配置配的都没什么问题,那问题究竟出现在哪呢?挠头...

接着怀疑会不会是切点表达式写的不对,但经过个人的小例子验证,切点表达式写的也没问题,那会是什么问题呢?

接着思考,得看看Service的实现类是不是代理类,结果显示,的确没代理类。为什么没创建代理类呢?突然想起来,前段时候在利用老工程择出框架时,发现老工程里把spring配置文件spring-*.xml都放在类文件的根目录下,而因为如此,在web.xml里配置dispatcherServlet时,需要显式的初始化参数并指明spring配置文件地址;而Spring容器默认去WEB-INF下搜索spring配置文件(个人猜测,尚未验证),所以认为spring既然默认去WEB-INF下找,那应该是将Spring配置文件放在WEB-INF下更合理,故而挪过去了,

而类包的部署配置(包括Controller、service、dao)信息都放在了spring-servlet里,事务的配置信息都在spring-application里,会不会是因为配置信息在不同的文件导致的呢?为了验证,把Service的配置信息挪到spring-application里,经验证,果然,事务起效了,愁了几天的问题终于有突破性进展了。但依旧存在困惑:

1. dispatcherServlet是不是默认去WEB-INF下找Spring配置文件?

2.如果第一个问题的答案是“是”的话,那当Spring配置都在WEB-INF下时,事务起作用到底是因为只能放在相同的配置文件,还是因为在加载dispatcherServlet时重新加载了实例化了Service类导致的?(配置dispatcherServlet的servlet-name是spring,而Service的部署配置信息刚好在spring-servlet.xml里)

(6月16日更新)经过测试,得出最新结论:spring容器分父子容器,先启动父容器,即通过Web容器上下文参数contextConfigLocation指定的配置文件所加载的容器;然后再启动子容器,即DispatcherServlet,如果配置的时候没显式配置contextConfigLocation参数,则会按照Spring默认的规则<servlet-name>-servlet.xml寻找配置文件;否则将根据显式配置的配置文件加载子容器。

所以上面问题出现的原因就不言而明了:在加载父容器的时候,事务是生效了的,所有的Service类都生成了对应的代理类;但在加载子容器的时候,由于默认根据<servlet-name>-servlet.xml寻找配置文件,该该配置文件中没有事务控制,所以也生成了一份Service类,且没有创建事务的代理类,故而在Controller层调用Service时,实际调用的却是子容器创建的没有事务的对象。

而经过测试,在父容器中的实现类的确是代理类,而子容器中是原生的实现类对象。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值