舉例講解Java的Spring框架中AOP程序設(shè)計(jì)方式的使用
1、什么是AOP
AOP是Aspect Oriented Programming的縮寫(xiě),意思是面向方面編程,AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù)。
2、關(guān)于Spring AOP的一些術(shù)語(yǔ):
A、切面(Aspect):在Spring AOP中,切面可以使用通用類或者在普通類中以@Aspect 注解(@AspectJ風(fēng)格)來(lái)實(shí)現(xiàn)
B、連接點(diǎn)(Joinpoint):在Spring AOP中一個(gè)連接點(diǎn)代表一個(gè)方法的執(zhí)行
C、通知(Advice):在切面的某個(gè)特定的連接點(diǎn)(Joinpoint)上執(zhí)行的動(dòng)作。通知有各種類型,其中包括"around"、"before”和"after"等通知。許多AOP框架,包括Spring,都是以攔截器做通知模型, 并維護(hù)一個(gè)以連接點(diǎn)為中心的攔截器鏈
D、切入點(diǎn)(Pointcut):定義出一個(gè)或一組方法,當(dāng)執(zhí)行這些方法時(shí)可產(chǎn)生通知,Spring缺省使用AspectJ切入點(diǎn)語(yǔ)法。
3、通知類型
A、前置通知(@Before):在某連接點(diǎn)(join point)之前執(zhí)行的通知,但這個(gè)通知不能阻止連接點(diǎn)前的執(zhí)行(除非它拋出一個(gè)異常)
B、返回后通知(@AfterReturning):在某連接點(diǎn)(join point)正常完成后執(zhí)行的通知:例如,一個(gè)方法沒(méi)有拋出任何異常,正常返回
C、拋出異常后通知(@AfterThrowing):方法拋出異常退出時(shí)執(zhí)行的通知
D、后通知(@After):當(dāng)某連接點(diǎn)退出的時(shí)候執(zhí)行的通知(不論是正常返回還是異常退出)
E、環(huán)繞通知(@Around):包圍一個(gè)連接點(diǎn)(join point)的通知,如方法調(diào)用。這是最強(qiáng)大的一種通知類型,環(huán)繞通知可以在方法調(diào)用前后完成自定義的行為,它也會(huì)選擇是否繼續(xù)執(zhí)行連接點(diǎn)或直接返回它們自己的返回值或拋出異常來(lái)結(jié)束執(zhí)行
4、@AspectJ風(fēng)格的AOP配置
Spring AOP配置有兩種風(fēng)格:
A、XML風(fēng)格 = 采用聲明形式實(shí)現(xiàn)Spring AOP
B、AspectJ風(fēng)格 = 采用注解形式實(shí)現(xiàn)Spring AOP
5、實(shí)例
切面類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的實(shí)現(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("測(cè)試異常"); } 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>
測(cè)試類AOPTest
public class AOPTest extends AbstractDependencyInjectionSpringContextTests { private AService aService; private BServiceImpl bService; protected String[] getConfigLocations() { String[] configs = new String[] { "/applicationContext.xml"}; return configs; } /** * 測(cè)試正常調(diào)用 */ public void testCall() { System.out.println("SpringTest JUnit test"); aService.fooA("JUnit test fooA"); aService.barA(); bService.fooB(); bService.barB("JUnit test barB",0); } /** * 測(cè)試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; } }
運(yùn)行結(jié)果如下:
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 測(cè)試異常
- Spring AOP日志框架實(shí)現(xiàn)過(guò)程圖解
- Spring AspectJ AOP框架注解原理解析
- Spring框架基于AOP實(shí)現(xiàn)簡(jiǎn)單日志管理步驟解析
- Spring框架實(shí)現(xiàn)AOP添加日志記錄功能過(guò)程詳解
- 在Spring Boot框架中使用AOP的正確姿勢(shì)
- 實(shí)例講解Java的Spring框架中的AOP實(shí)現(xiàn)
- Java的Spring框架中AOP項(xiàng)目的一般配置和部署教程
- Java的Spring框架下的AOP編程模式示例
- Spring框架學(xué)習(xí)之AOP詳解
相關(guān)文章
SpringBoot項(xiàng)目集成xxljob實(shí)現(xiàn)全紀(jì)錄
XXL-JOB是一個(gè)分布式任務(wù)調(diào)度平臺(tái),本文主要介紹了SpringBoot項(xiàng)目集成xxljob實(shí)現(xiàn)全紀(jì)錄,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Java應(yīng)用啟動(dòng)停止重啟Shell腳本模板server.sh
這篇文章主要為大家介紹了Java應(yīng)用啟動(dòng)、停止、重啟Shell腳本模板server.sh,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08java中實(shí)現(xiàn)漢字按照拼音排序(示例代碼)
這篇文章主要是對(duì)java中將漢字按照拼音排序的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12IDEA 去除 mybatis.xml 文件黃色警告的圖文教程
這篇文章主要介紹了IDEA 去除 mybatis.xml 文件黃色警告的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07