- <context:component-scan base-package="org.example"/>
- 然后可以用@Component、@Controller、@Service、@Repository注解来标注需要由Spring IoC容器进行对象托管的类。这几个注解没有本质区别,只不过@Controller通常用于控制器,@Service通常用于业务逻辑类,@Repository通常用于仓储类(例如我们的DAO实现类),普通的类用@Component来标注。
- <!-- 自动扫描组件,这里要把web下面的 controller去除,他们是在spring-mvc.xml中配置的,如果不去除会影响事务管理的。 -->
<context:component-scan base-package="com.cfcmms">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
在主容器中(applicationContext.xml),将Controller的注解打消掉
<!-- 自动扫描组件,这里要把web下面的 controller去除,他们是在spring-mvc.xml中配置的,如果不去除会影响事务管理的。 -->
<context:component-scan base-package="com.cfcmms">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
2 而在springMVC配置文件中将Service注解给去掉
<!-- 把标记了@Controller注解的类转换为bean -->
<context:component-scan base-package="com.cfcmms.**.controller">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Service" />
</context:component-scan>
因
为spring的context是父子容器,所以会产生冲突,Controller会进步前辈行扫描装配,而此时的Service还没有进行事务的加强处
理惩罚,获得的将是原样的Service(没有经过事务加强处理惩罚,故而没有事务处理惩罚才能)
,最后才是applicationContext.xml中的扫描设备进行事务处理
这个用的是 hibernate5 的sessionFactory 配置的session事务
<!-- 配置一个事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 事务管理 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 定义以下开头的方法名都是只读的模式 -->
<tx:method name="select*" read-only="true" />
<tx:method name="count*" read-only="true" />
<tx:method name="get*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="load*" read-only="true" />
<!-- 其他所有方法都使用事务 -->
<tx:method name="*" propagation="REQUIRED" read-only="false"
rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<!-- 事务 aop 配置 -->
<aop:config>
<!-- 定义一个切入点 -->
<aop:pointcut id="serviceMethods"
expression="execution(* com.cfcmms..*.service.*Service.*(..))" />
<!-- 对切入点和事务的通知,进行适配 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"
order="2" />
<!-- 多数据源切换 -->
<aop:aspect ref="dataSourceAspect" order="1">
<aop:before method="intercept" pointcut-ref="serviceMethods" />
</aop:aspect>
</aop:config>
<!-- 启用对事务注解的支持 -->
<tx:annotation-driven transaction-manager="transactionManager" />
153、Spring支持的事务管理类型有哪些?你在项目中使用哪种方式?答:Spring支持编程式事务管理和声明式事务管理。许多Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理,因为编程式事务允许你通过代码控制业务。事务分为全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器JTA支持(如WebLogic、WildFly等)。局部事务和底层采用的持久化方案有关,例如使用JDBC进行持久化时,需要使用Connetion对象来操作事务;而采用Hibernate进行持久化时,需要使用Session对象来操作事务。Spring提供了如下所示的事务管理器。事务管理器实现类 目标对象DataSourceTransactionManager 注入DataSourceHibernateTransactionManager 注入SessionFactoryJdoTransactionManager 管理JDO事务JtaTransactionManager 使用JTA管理事务PersistenceBrokerTransactionManager 管理Apache的OJB事务这些事务的父接口都是PlatformTransactionManager。Spring的事务管理机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何管理事务,但是它的实现类必须提供getTransaction()方法(开启事务)、commit()方法(提交事务)、rollback()方法(回滚事务)的多态实现,这样就可以用不同的实现类代表不同的事务管理策略。使用JTA全局事务策略时,需要底层应用服务器支持,而不同的应用服务器所提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器是可能需要使用JtaTransactionManager的子类,如:WebLogicJtaTransactionManager(Oracle的WebLogic服务器提供)、UowJtaTransactionManager(IBM的WebSphere服务器提供)等。