spring-aop-事務-註解開發-代理
1.spring + mybatis:
Aop流程:
提前定義好幾個用於Aop的類
前置通知:新建MyBeForeAdvice類 實現 MethodBeforeAdvice,並實現其方法
後置通知:新建MyAfterAdvice類 實現 AfterReturningAdvice,並實現其方法
環繞通知:新建RoundAdvice類 實現 MethodInterceptor ,並實現其方法
異常通知:新建ExceptionAdvice類 實現 ThrowsAdvice , 並編寫 ”afterThrowing“ 方法,如下:
public void afterThrowing(Exception ex){ System.out.println("異常通知: my throws 異常通知輔助功能"); }
applicationContext.xml配置如下:
<!-- 目標 : 原始業務,自己的某個bean都行--> <bean id="us" class="com.qf.service.UserServiceImpl" /> <!-- 通知:額外功能 --> <!-- 前置通知類 --> <bean id="before" class="com.qf.aop.MyBeforeAdvice"></bean> <!-- 後置通知,在核心之後執行,如果核心有異常,則不執行 --> <bean id="after" class="com.qf.aop.MyAfterAdvice"></bean> <!-- 在核心中拋異常時,執行 --> <bean id="throws" class="com.qf.aop.MyThrowsAdvice"></bean> <!-- 環繞通知 --> <bean id="mi" class="com.qf.aop.MyMethodInterceptor"></bean>
定義切入點,形成切面
<aop:config> <!-- 切入點【修飾符 返回值 包.類 方法名 引數表 】 --> <aop:pointcut id="pc_shine" expression="execution(* queryUsers())"/> <aop:pointcut id="pc_shine2" expression="execution(* deleteUser(..))"/> <aop:pointcut id="pc_shine3" expression="execution(* updateUser(..))"/> <aop:pointcut id="pc_shine4" expression="execution(* saveUser(..))"/> <!-- 組裝 --> <aop:advisor advice-ref="before" pointcut-ref="pc_shine"/> <aop:advisor advice-ref="after" pointcut-ref="pc_shine2"/> <aop:advisor advice-ref="throws" pointcut-ref="pc_shine3"/> <aop:advisor advice-ref="mi" pointcut-ref="pc_shine4"/> </aop:config>
根據表示式通配切入點:
語法 : execution(返回值型別 包名.方法名(引數包名.型別))
<aop:config>
<!--匹配引數-->
<aop:pointcut id="pc01" expression="execution(* *(com.qf.pojo.User))"/>
<!--匹配任意方法(無參)-->
<aop:pointcut id="pc02" expression="execution(* *())"/>
<!--匹配方法名(任意引數)-->
<aop:pointcut id="pc03" expression="execution(* saveUser(..))"/>
<!--匹配返回值型別(任意引數)-->
<aop:pointcut id="pc04" expression="execution(java.lang.Integer *(..))"/>
<!--匹配類名(任意引數)-->
<aop:pointcut id="pc05" expression="execution(* com.qf.service.UserServiceImpl.*(..))"/>
<!--匹配包名(任意引數)-->
<aop:pointcut id="pc06" expression="execution(* com.qf.service.*.*(..))"/>
<!--匹配包名、以及子包名(任意引數)-->
<aop:pointcut id="pc07" expression="execution(* com..*.*(..))"/>
<!--組裝-->
<aop:advisor advice-ref="after" pointcut-ref="pc01"/>
</aop:config>
2.事務控制:
1.配置DataSourceTransactionManager事務管理器,其中持有DataSource,可以控制事 務功能(commit,rollback等)。
<!-- 1. 引入一個事務管理器,其中依賴DataSource,藉以獲得連線,進而控制事務邏輯 -->
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
2.配置事務切面, 事務使用的規則
<!--aop在事務中的使用, 配置事務切面, 事務使用的規則-->
<tx:advice id="txManager" transaction-manager="tx">
<tx:attributes>
<!--規定哪些方法不需要事務(查詢方法)propagation="SUPPORTS" 取消事務-->
<tx:method name="find*" propagation="SUPPORTS"/>
<tx:method name="query*" propagation="SUPPORTS"/>
<tx:method name="select*" propagation="SUPPORTS"/>
<tx:method name="get*" propagation="SUPPORTS"/>
<!--規定哪些方法需要事務(增刪改) rollback-for="Exception" 遇到異常執行回滾操作-->
<tx:method name="insert*" rollback-for="Exception"></tx:method>
<tx:method name="update*" rollback-for="Exception"></tx:method>
<tx:method name="delete*" rollback-for="Exception"></tx:method>
</tx:attributes>
</tx:advice>
3.將事務管理的Advice 切入需要事務的業務方法中
<!--使用AOP切入事務-->
<aop:config>
<!--規定切點(某個方法,或匹配範圍內的方法)-->
<aop:pointcut id="pc" expression="execution(* com.qf.service.*.*(..))"/>
<!--組織切面-->
<aop:advisor advice-ref="txManager" pointcut-ref="pc"/>
</aop:config>
3.開啟註解開發
<!--開啟註解使用(掃描此包下的所有註解)-->
<context:component-scan base-package="com.qf"></context:component-scan>
@Autowhrid與@Resource的區別
一個介面只有一個實現類的時候,用@Autowhird
一個人介面有多個實現類的時候,
bean的註解後面應加上括號,例如@Service(value = “u2”)
注入時用@Resource(name = "u2"),而不是@Autowhird
@Controller 用在控制層的實現類上
@Service 用在service實現類上
@Repository 用在dao層的實現類上
@Component 用在其他需要被spring管理的bean上
@Value("${某個屬性名}") //獲取引入的properties檔案內的某個屬性,賦值給變數
private String ha;
4.使用註解@Transactional控制事務 (方便)
-
在applicationContext.xml中配置好事務管理器,上面有配置方法
-
在applicationContext.xml中配置宣告式事務標籤,並指定事務管理器
-
<!--宣告式事務,註解實現--> <!-- 告知spring,@Transactional在定製事務時,基於tx=DataSourceTransactionManager --> <tx:annotation-driven transaction-manager="tx"/>
-
在applicationContext.xml中配置好註解掃描,上面有配置方法
-
在想新增事務的方法上新增@Transactional註解即可
(事務控制應該在ServiceImpl層實現,而不是controller層)