Spring深入探索AOP切面編程
AOP概念的引入
傳統(tǒng)的登錄原理:

如上圖所示這是一個(gè)基本的登錄原理圖,但是如果我們想要在這個(gè)登錄之上添加一些新的功能,比如權(quán)限校驗(yàn)
那么我們能想到的就有兩種方法:
①:通過(guò)對(duì)源代碼的修改實(shí)現(xiàn)
②:不通過(guò)修改源代碼方式添加新的功能 (AOP)

AOP相關(guān)的概念
1、AOP的概述
什么是AOP的技術(shù)?
在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程
AOP是一種編程范式,隸屬于軟工范疇,指導(dǎo)開發(fā)者如何組織程序結(jié)構(gòu)
AOP最早由AOP聯(lián)盟的組織提出的,制定了一套規(guī)范.Spring將AOP思想引入到框架中,必須遵守AOP聯(lián)盟的規(guī)范
通過(guò)預(yù)編譯方式或者運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)
AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍
生范型
利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可
重用性,同時(shí)提高了開發(fā)的效率
AOP采取橫向抽取機(jī)制,取代了傳統(tǒng)縱向繼承體系重復(fù)性代碼(事務(wù)管理、安全檢查、緩存)
為什么要學(xué)習(xí)AOP,可以在不修改源代碼的前提下,對(duì)程序進(jìn)行增強(qiáng)??!
2、AOP的優(yōu)勢(shì)
運(yùn)行期間,不修改源代碼的情況下對(duì)已有的方法進(jìn)行增強(qiáng)
優(yōu)勢(shì):
- 減少重復(fù)的代碼
- 提供開發(fā)的效率
- 維護(hù)方便
3、AOP的底層原理
JDK的動(dòng)態(tài)代理技術(shù)
1、為接口創(chuàng)建代理類的字節(jié)碼文件
2、使用ClassLoader將字節(jié)碼文件加載到JVM
3、創(chuàng)建代理類實(shí)例對(duì)象,執(zhí)行對(duì)象的目標(biāo)方法
cglib代理技術(shù)
為類生成代理對(duì)象,被代理類有沒(méi)

Spring的AOP技術(shù)-配置文件方式
1、AOP相關(guān)的術(shù)語(yǔ)
Joinpoint(連接點(diǎn)) 類里面有哪些方法可以增強(qiáng)這些方法稱為連接點(diǎn)
Pointcut(切入點(diǎn)) – 所謂切入點(diǎn)是指我們要對(duì)哪些Joinpoint進(jìn)行攔截的定義
Advice(通知/增強(qiáng))-- 所謂通知是指攔截到Joinpoint之后所要做的事情就是通知.通知分為前置通知,后置通知,異常通知,最終通知,環(huán)繞通知(切面要完成的功能)
Aspect(切面)-- 是 切入點(diǎn)+通知 的結(jié)合,以后咱們自己來(lái)編寫和配置的
增強(qiáng):是對(duì)業(yè)務(wù)功能的擴(kuò)充


2、基本準(zhǔn)備工作
AspectJ是一個(gè)面向切面的框架,它擴(kuò)展了Java語(yǔ)言。AspectJ定義了AOP語(yǔ)法,AspectJ實(shí)際上是對(duì)AOP編程思想的一個(gè)實(shí)踐.
2.1、aop的使用
創(chuàng)建被增強(qiáng)的類:
public class Demo {
//要增強(qiáng),成為---->連接點(diǎn)---->切入點(diǎn)
public void login(){
//int a=10/0;
System.out.println("登錄。。。");
}
}將目標(biāo)類配置到Spring中:
<bean id="demo" class="com.qcby.Demo"/>
定義切面類
package com.notice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect //表明我們是通知
public class Power {
//前置通知的方法
public void authentication(){
System.out.println("登錄前---權(quán)限驗(yàn)證。。。");
}
}在spring.xml中配置文件中定義切面類:
<bean id="power" class="com.notice.Power"/>
在spring.xml中配置切面:
<aop:config>
<!--aspect:前置通知,在登錄前執(zhí)行-->
<aop:aspect ref="power">
<!--前置通知:-->
<!--method:登錄前執(zhí)行的方法,權(quán)限驗(yàn)證的方法-->
<!--pointcut:切入點(diǎn),之后最終要執(zhí)行的方法-->
<!--前置通知:-->
<aop:before method="authentication" pointcut="execution(public void com.qcby.Demo.login())"/>
</aop:aspect>
</aop:config>測(cè)試:
public class DemoTest {
@Test
public void demo1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");
Demo demo = (Demo) ac.getBean("demo");
demo.login();
}
}
2.2、配置文件的方式的aop5種通知方式
也可以在spring.xml中加入其他通知方式:
<aop:config>
<!--aspect:前置通知,在登錄前執(zhí)行-->
<aop:aspect ref="power">
<!--前置通知:-->
<!--method:登錄前執(zhí)行的方法,權(quán)限驗(yàn)證的方法-->
<!--pointcut:切入點(diǎn),之后最終要執(zhí)行的方法-->
<!--前置通知:-->
<aop:before method="authentication" pointcut="execution(public void com.qcby.Demo.login())"/>
<!--后置通知:當(dāng)方法執(zhí)行不成功的時(shí)候方法不執(zhí)行-->
<aop:after-returning method="authenticationEnd" pointcut="execution(public void com.qcby.Demo.login())"/>
<!--當(dāng)切入點(diǎn)(登錄方法)發(fā)生異常的時(shí)候執(zhí)行,沒(méi)有異常則不執(zhí)行:-->
<aop:after-throwing method="findThrowError" pointcut="execution(public void com.qcby.Demo.login())"/>
<!--最終通知:無(wú)論切入點(diǎn)的方法執(zhí)行成功與否,最終都執(zhí)行的通知(增強(qiáng))-->
<aop:after method="finallyMethod" pointcut="execution(public void com.qcby.Demo.login())"/>
<!--環(huán)繞通知:在切面前后執(zhí)行方法-->
<aop:around method="round" pointcut="execution(public void com.qcby.Demo.login())"/>
</aop:aspect>
</aop:config>
3、通知類型注解:用注解的方式加入通知
@Before – 前置通知
@AfterReturing – 后置通知
@Around – 環(huán)繞通知(目標(biāo)對(duì)象方法默認(rèn)不執(zhí)行的,需要手動(dòng)執(zhí)行)
@After – 最終通知
@AfterThrowing – 異常拋出通知
package com.notice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect //表明我們是通知
public class Power {
//增強(qiáng)的方法:權(quán)限驗(yàn)證
//@Before(value="execution(public void com.qcby.Demo.login())")
//@AfterReturning(value="execution(public void com.qcby.Demo.login())")
//前置通知
@Before(value="execution(public void com.qcby.Demo.login())")
public void authentication(){
System.out.println("登錄前---權(quán)限驗(yàn)證。。。");
}
//后置通知
@AfterReturning(value="execution(public void com.qcby.Demo.login())")
public void authenticationEnd(){
System.out.println("登錄后---權(quán)限驗(yàn)證。。。");
}
//發(fā)生異常時(shí)通知
@AfterThrowing(value="execution(public void com.qcby.Demo.login())")
public void findThrowError(){
System.out.println("登錄發(fā)現(xiàn)異常了");
}
//最終通知
@After(value="execution(public void com.qcby.Demo.login())")
public void finallyMethod(){
System.out.println("最終都執(zhí)行的通知");
}
//環(huán)繞通知
@Around(value="execution(public void com.qcby.Demo.login())")
public void round(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("在登錄之前進(jìn)行了權(quán)限驗(yàn)證");
//之間執(zhí)行登錄的方法
proceedingJoinPoint.proceed();
System.out.println("在登錄之后進(jìn)行了權(quán)限驗(yàn)證");
}
}到此這篇關(guān)于Spring深入探索AOP切面編程的文章就介紹到這了,更多相關(guān)Spring AOP內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot?整合Redis?數(shù)據(jù)庫(kù)的方法
Redis是一個(gè)基于內(nèi)存的日志型可持久化的緩存數(shù)據(jù)庫(kù),保存形式為key-value格式,Redis完全免費(fèi)開源,它使用ANSI?C語(yǔ)言編寫。這篇文章主要介紹了SpringBoot?整合Redis?數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下2018-03-03
SWT(JFace)體驗(yàn)之Sash(活動(dòng)控件)
SWT(JFace)體驗(yàn)之Sash(活動(dòng)控件)2009-06-06
Java三目運(yùn)算符的實(shí)戰(zhàn)案例
三目運(yùn)算符在java中運(yùn)用可以說(shuō)非常的廣泛,下面這篇文章主要給大家介紹了關(guān)于Java三目運(yùn)算符的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09
springboot集成nacos讀取nacos配置數(shù)據(jù)的原理
這篇文章主要介紹了springboot集成nacos讀取nacos配置數(shù)據(jù)的原理,文中有詳細(xì)的代碼流程,對(duì)大家學(xué)習(xí)springboot集成nacos有一定的幫助,需要的朋友可以參考下2023-05-05
Java編程實(shí)現(xiàn)軌跡壓縮之Douglas-Peucker算法詳細(xì)代碼
Java業(yè)務(wù)中臺(tái)確保數(shù)據(jù)一致性的解決方案

