個(gè)人主頁: 幾分醉意的CSDN博客_傳送門
??AOP概念
什么是AOP?
AOP(Aspect Orient Programming):面向切面編程
Aspect:表示切面,給業(yè)務(wù)方法增加的功能,叫做切面。切面一般都是非業(yè)務(wù)功能,而且切面功能一般都是可以復(fù)用的。例如日志功能,事務(wù)功能,權(quán)限檢查,參數(shù)檢查,統(tǒng)計(jì)信息等等。
Orient:面向,對著
Programming:編程。
怎么理解面向切面編程?
以切面為核心設(shè)計(jì)開發(fā)你的應(yīng)用。1)設(shè)計(jì)項(xiàng)目時(shí),找出切面的功能。2)安排切面的執(zhí)行時(shí)間,執(zhí)行的位置。
?AOP作用
1. 讓切面功能復(fù)用
2. 讓開發(fā)人員專注業(yè)務(wù)邏輯。提高開發(fā)效率
3. 實(shí)現(xiàn)業(yè)務(wù)功能和其他非業(yè)務(wù)功能解耦合。
4. 給存在的業(yè)務(wù)方法,增加功能,不用修改原來的代碼
?AOP術(shù)語
AOP中重要的三個(gè)要素:Aspect,Pointcut,Advice.這個(gè)概念的理解是:在Advice的時(shí)間,在Pointcut的位置, 執(zhí)行Aspect。
-
Aspect:切面,給業(yè)務(wù)方法增加的功能。
-
JoinPoint:連接點(diǎn),連接切面的業(yè)務(wù)方法。在這個(gè)業(yè)務(wù)方法執(zhí)行時(shí),會同時(shí)執(zhí)行切面的功能。
-
Pointcut:切入點(diǎn),是一個(gè)或多個(gè)連接點(diǎn)集合。表示這些方法執(zhí)行時(shí),都能增加切面的功能。表示切面執(zhí)行的位置。
-
target:目標(biāo)對象,給那個(gè)對象增加切面的功能,這個(gè)對象就是目標(biāo)對象。
-
Advice:通知(增強(qiáng)),表示切面的執(zhí)行時(shí)間。在目標(biāo)方法之前執(zhí)行切面,還是目標(biāo)方法之后執(zhí)行切面。
AOP是一個(gè)動(dòng)態(tài)的思想。在程序運(yùn)行期間,創(chuàng)建代理(ServcieProxy),使用代理執(zhí)行方法時(shí),增加切面的功能。這個(gè)代理對象是存在內(nèi)存中的。
?什么時(shí)候需要用AOP
你要給某些方法增加相同的一些功能。源代碼不能改。給業(yè)務(wù)方法增加非業(yè)務(wù)功能,也可以使用AOP。
??Aspectj框架介紹
AOP技術(shù)思想的實(shí)現(xiàn):使用框架實(shí)現(xiàn)AOP。實(shí)現(xiàn)AOP的框架有很多。有名的兩個(gè)
1. Spring:Spring框架實(shí)現(xiàn)AOP思想中的部分功能。Spring框架實(shí)現(xiàn)AOP的操作比較繁瑣,笨重。
2. Aspectj:獨(dú)立的框架,專門做AOp的,功能最強(qiáng)大的。屬于Eclipse。
而我下面主要介紹的就是Aspectj框架來實(shí)現(xiàn)Aop,Aspectj框架可以使用注解和xml配置文件兩種方式實(shí)現(xiàn)AOP。
?Aspectj的5個(gè)通知注解
Aspectj表示切面執(zhí)行時(shí)間,用的通知(Advice)。這個(gè)通知可以使用注解表示。講5個(gè)注解,表示切面的5個(gè)執(zhí)行時(shí)間,這些注解叫做通知注解。
@Before :前置通知
@AfterRetunring: 后置通知
@Around: 環(huán)繞通知
@AfterThrowing:異常通知
@After:最終通知
?Aspectj切入點(diǎn)表達(dá)式
Pointcut 位置
Pointcut用來表示切面執(zhí)行的位置,使用Aspectj中切入點(diǎn)表達(dá)式。
切入點(diǎn)表達(dá)式語法:execution(訪問權(quán)限 方法返回值 方法聲明(參數(shù))異常類型)
通配符
舉例:
指定切入點(diǎn)為:任意公共方法
?前置通知@Before
使用aspectj框架的注解,實(shí)現(xiàn)前置通知
實(shí)現(xiàn)步驟:
1. 新建maven項(xiàng)目
2. 修改pom.xml 加入依賴
spring-context依賴, spring-aspects依賴(能使用aspectj框架的功能)junit
3. 創(chuàng)建業(yè)務(wù)接口和實(shí)現(xiàn)類。
4. 創(chuàng)建一個(gè)叫做切面類,是一個(gè)普通類
1)在類的上面加入@Aspect
2) 在類中定義方法, 方法表示切面的功能。
在方法的上面加入Aspect框架中的通知注解,例如@Before(value=“切入點(diǎn)表達(dá)式”)
5. 創(chuàng)建spring配置文件。
1)聲明目標(biāo)對象
2)聲明切面類對象
3)聲明自動(dòng)代理生成器
6. 創(chuàng)建測試類,測試目標(biāo)方法執(zhí)行時(shí),增加切面的功能
下面我們開始跟著步驟實(shí)踐
pom.xml 加入依賴
<dependencies>
<!--spring依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--spring-aspects依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
創(chuàng)建業(yè)務(wù)接口和實(shí)現(xiàn)類
public interface SomeService {
void doSome(String name,Integer age);
}
public class SomeServiceImpl implements SomeService {
@Override
public void doSome(String name, Integer age) {
System.out.println("業(yè)務(wù)方法doSome(),創(chuàng)建商品訂單");
}
}
創(chuàng)建切面類
/**
* @Aspect: 切面類的注解。
* 位置:放在某個(gè)類的上面
* 作用:表示當(dāng)前類是切面類。
* 切面類:表示切面功能的類
*/
@Aspect
public class MyAspect {
//定義方法,表示切面的具體功能
/*
前置通知方法的定義
1)方法是public
2)方法是void
3)方法名稱自定義
4)方法可以有參數(shù),如果有是JoinPoint
也可以沒有
*/
/**
@Before:前置通知
屬性:value 切入點(diǎn)表達(dá)式,表示切面的執(zhí)行位置。
在這個(gè)方法時(shí),會同時(shí)執(zhí)行切面的功能
位置:在方法的上面
特點(diǎn):
1)執(zhí)行時(shí)間:在目標(biāo)方法之前先執(zhí)行的。
2)不會影響目標(biāo)方法的執(zhí)行。
3)不會修改目標(biāo)方法的執(zhí)行結(jié)果。
*/
@Before(value = "execution(public void youfei1_v.service.impl.SomeServiceImpl.doSome(String ,Integer))")
public void myBefore(){
//切面代碼
System.out.println("前置通知,切面功能在目標(biāo)方法之前執(zhí)行"+new Date());
}
}
創(chuàng)建配置文件
<?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.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--聲明目標(biāo)對象-->
<bean id="someService" class="youfei1_v.service.impl.SomeServiceImpl" />
<!--聲明切面類對象-->
<bean id="myAspect" class="youfei1_v.handle.MyAspect" />
<!--聲明自動(dòng)代理生成器:目的是創(chuàng)建目標(biāo)對象的代理
調(diào)用aspectj框架中的功能, 尋找spring容器中的所有目標(biāo)對象,
把每個(gè)目標(biāo)對象加入切面類中的功能, 生成代理。
這個(gè)代理對象是修改的內(nèi)存中的目標(biāo)對象, 這個(gè)目標(biāo)對象就是代理對象(ServiceProxy)
-->
<aop:aspectj-autoproxy />
</beans>
測試文章來源:http://www.zghlxwxcb.cn/news/detail-793613.html
@Test
public void test(){
//如果沒有加入代理的處理:
// 1)目標(biāo)方法執(zhí)行時(shí),沒有切面功能的。
// 2) service對象沒有被改變
//加入代理的處理:
// 1)目標(biāo)方法執(zhí)行時(shí),有切面功能的。
// 2) service對象是改變后的 代理對象 com.sun.proxy.$Proxy8
String s = "applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(s);
SomeService service = (SomeService)ctx.getBean("someService");
service.doSome("ll" , 22);
}
執(zhí)行結(jié)果:
文章來源地址http://www.zghlxwxcb.cn/news/detail-793613.html
??投票傳送門(歡迎伙伴們投票)
到了這里,關(guān)于【Spring】一文帶你吃透AOP面向切面編程技術(shù)(上篇)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!