我是使用XML配置开发AspectJ框架。
1、 所以!一点要在pom文件引入spring-aspects的配置。
版本自行选择
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
2、 在applicationContext.xml配置数据源和会话工厂和扫描Dao层
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/early_warning_system?characterEncoding=utf8&useSSL=true" />
<property name="username" value="root" />
<property name="password" value="123456" />
<!-- 最大连接数 -->
<property name="maxTotal" value="30"/>
<!-- 最大空闲连接数 -->
<property name="maxIdle" value="10"/>
<!-- 初始化连接数 -->
<property name="initialSize" value="5"/>
</bean>
<!-- 配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- configLocation的属性值为MyBatis的核心配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--mapperLocations 映射器,告诉 MyBatis到哪里去找映射文件-->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!--Mapper代理开发,使用Spring自动扫描MyBatis的接口并装配
(Spring将指定包中所有被@Mapper注解标注的接口自动装配为MyBatis的映射接口) --> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer" >
<!-- mybatis-spring组件的扫描器 ,必须写全dao的包名,且只能扫描一个dao包-->
<property name="basePackage" value="team.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
3、 配置事务管理的bean
<bean id= "txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
4、 开启事务注解
<!-- 开启事务注解-->
<tx:annotation-driven transaction-manager="txManager" />
5、
全局AOP事物,除get,list,select,query开头的方法外,都处在事物当中。“*”表示通配符,这个应该都知道。
<!-- 全局AOP事物,除get,list,select,query开头的方法外,都处在事物当中 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="select*" propagation="REQUIRED" read-only="true" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="list*" propagation="REQUIRED" read-only="true" />
<tx:method name="query*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
这里需要在注意!!
事务属性在tx:method中进行设置,Spring支持对不同的方法设置不同的事务属性,所以可以为一个tx:advice设置多个tx:method,其中name属性指定匹配的方法(这里需要对这些方法名进行约定,如果事务切入点在service上,则最好和Dao的方法命名区分开,也不要使用get set关键字,防止和属性的getter setter发生混淆)
事务有以下几个常用属性:
a.read-only:设置该事务中是否允许修改数据。(对于只执行查询功能的事务,设置为TRUE可以提高事务的执行速度)
b.propagation:事务的传播机制。一般设置为required。可以保证在事务中的代码只在当前事务中运行,防止创建多个事务。
c.isolation:事务隔离级别。不是必须的。默认值是default。
d.timeout:允许事务运行的最长时间,以秒为单位。
e.rollback-for:触发回滚的异常。
f.no-rollback-for:不会触发回滚的异常。
实际开发中,对于只执行查询功能的事务,要设置read-only为TRUE,其他属性一般使用默认值即可。
6、 最后一步,把事务处理织入service的方法中
<aop:config>
<!--配置事务切点 -->
<aop:pointcut id="services"
expression="execution(* team.service.*.*(..))" />
<aop:advisor pointcut-ref="services" advice-ref="txAdvice" />
</aop:config>
注意!"execution(* team.service..(…))"的第一个“*”号后面一定要有一个空格!
否则就会出现错误:
Error creating bean with name 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'name pattern' at character position 27
execution(team.service.*.*(..))