舉例講解Java的Spring框架中AOP程序設(shè)計(jì)方式的使用
1、什么是AOP
AOP是Aspect Oriented Programming的縮寫,意思是面向方面編程,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è)方法沒有拋出任何異常,正常返回
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-11
Java應(yīng)用啟動(dòng)停止重啟Shell腳本模板server.sh
這篇文章主要為大家介紹了Java應(yīng)用啟動(dòng)、停止、重啟Shell腳本模板server.sh,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
java中實(shí)現(xiàn)漢字按照拼音排序(示例代碼)
這篇文章主要是對(duì)java中將漢字按照拼音排序的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
IDEA 去除 mybatis.xml 文件黃色警告的圖文教程
這篇文章主要介紹了IDEA 去除 mybatis.xml 文件黃色警告的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07

