最近加入了新的公司,因为项目是别人搭建的,自己在使用时不太方便,所以修改了部分配置,以便在spring集成hibernate的时候,依赖aop去管理事务。
首先说一下web.xml,他是一个项目的根节点,用它来管理项目启动和web的上下文,那么本项目前面来的人搭了3个spring-*.xml(可能想通配时方便吧),名字取得不大好,以至于我都不了解那个是spring的上文,哪个是下文。最后才知道是springmvc-servlet.xml,在这个'上文'中配置了<context:component-scan base-package="com.wsjxt2.*" >这样的一个节点属性,他的意思就是spring在启动时,会把标注了@Controller以及与他相关联的@service,@reposity都注册为spring的bean组件.
问题来了我使用的是spring的aop来管理事务,如下
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 定义事务规则 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="modify*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 定义事务入口 -->
<aop:config>
<aop:pointcut expression="execution(* com.wsjxt2.*.service..*.*(..))"
id="pointcut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
</aop:config>
本以为可以安心的在某个方法后面显式的抛一个runtTmeException,让事务回滚,没想到数据库还是写入了不该有的数据。问题就出在<context:component-scan base-package="com.wsjxt2.*" >这里,我使用的是aop管理事务,
如果是全包扫描的话,事务并没有来得及被注册,后来改成下面:
<!-- 注解扫描包 该xml为主容器 只扫描Controller 不扫描aop的切面service -->
<context:component-scan base-package="com.wsjxt2.*" >
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
并且在spring-mvc.xml的下文即spring-hibernate.xml(我的是这个),过滤掉
<!-- 不重复扫描 -->
<context:component-scan base-package="com.wsjxt2.*" >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
最后 可以正常使用了