您好,登錄后才能下訂單哦!
小編給大家分享一下如何通過AOP環(huán)繞通知如何實現(xiàn)事務控制,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> </dependencies>
以下采用的是xml配置方式,當然也可以使用純注解配置
<!-- 配置數(shù)據(jù)源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!--連接數(shù)據(jù)庫的必備信息--> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean> <!--開啟spring對注解AOP的支持--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
package com.gzl.utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.sql.Connection; /** * 連接的工具類,它用于從數(shù)據(jù)源中獲取一個連接,并且實現(xiàn)和線程的綁定 */ @Component("connectionUtils") public class ConnectionUtils { private ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); @Autowired private DataSource dataSource; /** * 獲取當前線程上的連接 * @return */ public Connection getThreadConnection() { try{ //1.先從ThreadLocal上獲取 Connection conn = tl.get(); //2.判斷當前線程上是否有連接 if (conn == null) { //3.從數(shù)據(jù)源中獲取一個連接,并且存入ThreadLocal中 conn = dataSource.getConnection(); tl.set(conn); } //4.返回當前線程上的連接 return conn; }catch (Exception e){ throw new RuntimeException(e); } } /** * 把連接和線程解綁 */ public void removeConnection(){ tl.remove(); } }
package com.gzl.utils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * 和事務管理相關的工具類,它包含了,開啟事務,提交事務,回滾事務和釋放連接 */ @Component("txManager") @Aspect public class TransactionManager { @Autowired private ConnectionUtils connectionUtils; /** * 需要進行事務控制的類或者方法,EL表達式配置 */ @Pointcut("execution(* com.gzl.service.impl.*.*(..))") private void pt1(){} /** * 開啟事務 */ public void beginTransaction(){ try { connectionUtils.getThreadConnection().setAutoCommit(false); }catch (Exception e){ e.printStackTrace(); } } /** * 提交事務 */ public void commit(){ try { connectionUtils.getThreadConnection().commit(); }catch (Exception e){ e.printStackTrace(); } } /** * 回滾事務 */ public void rollback(){ try { connectionUtils.getThreadConnection().rollback(); }catch (Exception e){ e.printStackTrace(); } } /** * 釋放連接 */ public void release(){ try { connectionUtils.getThreadConnection().close();//還回連接池中 connectionUtils.removeConnection(); }catch (Exception e){ e.printStackTrace(); } } @Around("pt1()") public Object aroundAdvice(ProceedingJoinPoint pjp){ Object rtValue = null; try { //1.獲取參數(shù) Object[] args = pjp.getArgs(); //2.開啟事務 this.beginTransaction(); //3.執(zhí)行方法 rtValue = pjp.proceed(args); //4.提交事務 this.commit(); //返回結(jié)果 return rtValue; }catch (Throwable e){ //5.回滾事務 this.rollback(); throw new RuntimeException(e); }finally { //6.釋放資源 this.release(); } } }
環(huán)繞通知Around Advice就是在指定的程序前后均執(zhí)行相關的服務,設計思路如下:
package com.spring.service; public interface IComponent { public void bussiness1(); public void bussiness2(); public void bussiness3(); }
package com.spring.service; public class Component implements IComponent{ @Override public void bussiness1() { // TODO Auto-generated method stub System.out.println("這是業(yè)務1"); } @Override public void bussiness2() { // TODO Auto-generated method stub System.out.println("這是業(yè)務2"); } @Override public void bussiness3() { // TODO Auto-generated method stub System.out.println("這是業(yè)務3"); } }
該代碼必須實現(xiàn)org.aopalliance.intercept.Method Interceptor接口,需要的服務都寫在這里。
通過代理來實現(xiàn)AOP的環(huán)繞通知,看一下org.aopalliance.intercept.MethodInterceptor接口的源代碼。該接口不是Spring內(nèi)部的接口,而是AOP Alliance標準所指定的,不過Spring對這個接口有一個具體的實現(xiàn)過程,同時該接口相融所有遵守AOP Alliance標準的所有AOP框架。
環(huán)繞通知相當于前置通知和后置通知的結(jié)合,不同的是在MethodInterceptor的invoke()方法中,可以自由地使用MethodInvocation提供的proceed()方法來執(zhí)行目標對象的方法,同時proceed()方法將會返回目標方法執(zhí)行后的返回結(jié)果,在invoke方法結(jié)束前還可以修改該結(jié)果,下面還是以上面的那個例子來示范一下環(huán)繞通知的應用。
編寫一個環(huán)繞通知的類,該類實現(xiàn)MethodInterceptor接口。這里調(diào)用了MethodInvocation的proceed()方法,也就是說,調(diào)用了目標對象Component中的business1等方法,在這個方法的前后分別增加了驗證和通知執(zhí)行,接著修改一下配置文件,去掉前置通知和后置通知的配置,只需要將這個環(huán)繞通知添加進去就可以了,具體代碼如下:
這里只需要配置一個環(huán)繞通知的Bean,并且將這個Bean配置到interceptorNames中就完成了所有的工作,測試代碼與前面的相同,可以看到結(jié)果也與前面的相同。
看完了這篇文章,相信你對“如何通過AOP環(huán)繞通知如何實現(xiàn)事務控制”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。