舉例講解Java的Spring框架中AOP程序設計方式的使用
1、什么是AOP
AOP是Aspect Oriented Programming的縮寫,意思是面向方面編程,AOP實際是GoF設計模式的延續(xù)。
2、關于Spring AOP的一些術語:
A、切面(Aspect):在Spring AOP中,切面可以使用通用類或者在普通類中以@Aspect 注解(@AspectJ風格)來實現(xiàn)
B、連接點(Joinpoint):在Spring AOP中一個連接點代表一個方法的執(zhí)行
C、通知(Advice):在切面的某個特定的連接點(Joinpoint)上執(zhí)行的動作。通知有各種類型,其中包括"around"、"before”和"after"等通知。許多AOP框架,包括Spring,都是以攔截器做通知模型, 并維護一個以連接點為中心的攔截器鏈
D、切入點(Pointcut):定義出一個或一組方法,當執(zhí)行這些方法時可產(chǎn)生通知,Spring缺省使用AspectJ切入點語法。
3、通知類型
A、前置通知(@Before):在某連接點(join point)之前執(zhí)行的通知,但這個通知不能阻止連接點前的執(zhí)行(除非它拋出一個異常)
B、返回后通知(@AfterReturning):在某連接點(join point)正常完成后執(zhí)行的通知:例如,一個方法沒有拋出任何異常,正常返回
C、拋出異常后通知(@AfterThrowing):方法拋出異常退出時執(zhí)行的通知
D、后通知(@After):當某連接點退出的時候執(zhí)行的通知(不論是正常返回還是異常退出)
E、環(huán)繞通知(@Around):包圍一個連接點(join point)的通知,如方法調用。這是最強大的一種通知類型,環(huán)繞通知可以在方法調用前后完成自定義的行為,它也會選擇是否繼續(xù)執(zhí)行連接點或直接返回它們自己的返回值或拋出異常來結束執(zhí)行
4、@AspectJ風格的AOP配置
Spring AOP配置有兩種風格:
A、XML風格 = 采用聲明形式實現(xiàn)Spring AOP
B、AspectJ風格 = 采用注解形式實現(xiàn)Spring AOP
5、實例
切面類TestAspect
package com.spring.aop; /** * 切面 */ public class TestAspect { public void doAfter(JoinPoint jp) { System.out.println("log Ending method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long time = System.currentTimeMillis(); Object retVal = pjp.proceed(); time = System.currentTimeMillis() - time; System.out.println("process time: " + time + " ms"); return retVal; } public void doBefore(JoinPoint jp) { System.out.println("log Begining method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public void doThrowing(JoinPoint jp, Throwable ex) { System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception"); System.out.println(ex.getMessage()); } private void sendEx(String ex) { //TODO 發(fā)送短信或郵件提醒 } }
package com.spring.service; /** * 接口A */ public interface AService { public void fooA(String _msg); public void barA(); }
package com.spring.service; /** *接口A的實現(xiàn)類 */ public class AServiceImpl implements AService { public void barA() { System.out.println("AServiceImpl.barA()"); } public void fooA(String _msg) { System.out.println("AServiceImpl.fooA(msg:"+_msg+")"); } }
package com.spring.service; /** * Service類B */ public class BServiceImpl { public void barB(String _msg, int _type) { System.out.println("BServiceImpl.barB(msg:"+_msg+" type:"+_type+")"); if(_type == 1) throw new IllegalArgumentException("測試異常"); } public void fooB() { System.out.println("BServiceImpl.fooB()"); } }
ApplicationContext
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-autowire="autodetect"> <aop:config> <aop:aspect id="TestAspect" ref="aspectBean"> <!--配置com.spring.service包下所有類或接口的所有方法--> <aop:pointcut id="businessService" expression="execution(* com.spring.service.*.*(..))" /> <aop:before pointcut-ref="businessService" method="doBefore"/> <aop:after pointcut-ref="businessService" method="doAfter"/> <aop:around pointcut-ref="businessService" method="doAround"/> <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/> </aop:aspect> </aop:config> <bean id="aspectBean" class="com.spring.aop.TestAspect" /> <bean id="aService" class="com.spring.service.AServiceImpl"></bean> <bean id="bService" class="com.spring.service.BServiceImpl"></bean> </beans>
測試類AOPTest
public class AOPTest extends AbstractDependencyInjectionSpringContextTests { private AService aService; private BServiceImpl bService; protected String[] getConfigLocations() { String[] configs = new String[] { "/applicationContext.xml"}; return configs; } /** * 測試正常調用 */ public void testCall() { System.out.println("SpringTest JUnit test"); aService.fooA("JUnit test fooA"); aService.barA(); bService.fooB(); bService.barB("JUnit test barB",0); } /** * 測試After-Throwing */ public void testThrow() { try { bService.barB("JUnit call barB",1); } catch (IllegalArgumentException e) { } } public void setAService(AService service) { aService = service; } public void setBService(BServiceImpl service) { bService = service; } }
運行結果如下:
log Begining method: com.spring.service.AServiceImpl.fooA AServiceImpl.fooA(msg:JUnit test fooA) log Ending method: com.spring.service.AServiceImpl.fooA process time: 0 ms log Begining method: com.spring.service.AServiceImpl.barA AServiceImpl.barA() log Ending method: com.spring.service.AServiceImpl.barA process time: 0 ms log Begining method: com.spring.service.BServiceImpl.fooB BServiceImpl.fooB() log Ending method: com.spring.service.BServiceImpl.fooB process time: 0 ms log Begining method: com.spring.service.BServiceImpl.barB BServiceImpl.barB(msg:JUnit test barB type:0) log Ending method: com.spring.service.BServiceImpl.barB process time: 0 ms log Begining method: com.spring.service.BServiceImpl.barB BServiceImpl.barB(msg:JUnit call barB type:1) log Ending method: com.spring.service.BServiceImpl.barB method com.spring.service.BServiceImpl.barB throw exception 測試異常
相關文章
SpringBoot項目集成xxljob實現(xiàn)全紀錄
XXL-JOB是一個分布式任務調度平臺,本文主要介紹了SpringBoot項目集成xxljob實現(xiàn)全紀錄,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11Java應用啟動停止重啟Shell腳本模板server.sh
這篇文章主要為大家介紹了Java應用啟動、停止、重啟Shell腳本模板server.sh,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08IDEA 去除 mybatis.xml 文件黃色警告的圖文教程
這篇文章主要介紹了IDEA 去除 mybatis.xml 文件黃色警告的方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07