javascript
Spring 从入门到入土——AOP 就这么简单!| 原力计划
作者| ?冢狐
責編 |?夕顏
出品?|?CSDN博客
?
什么是AOP?
面向切面編程(Aspect Oriented Programming),通過預編譯的方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術。AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生泛型,利用AOP可以對業(yè)務邏輯的各個部分進行隔離,從而使業(yè)務邏輯各個部分的耦合度降低,提高程序的可重用性,同時提高了開發(fā)效率。
AOP在Spring中的作用
提供聲明式事務;允許用戶自定義切面
核心名詞
橫切關注點:橫跨應用程序多個模塊的方法或功能。即是,與我們業(yè)務邏輯無關的,但是我們需要關注的地方,就是橫切關注點,如:日志、安全、緩存、事務
切面:橫切關注點被模塊化的特性對象,即:它是一個類
通知:切面必須要完成的工作。即它是類中的一個方法
目標:被通知對象
代理:向目標對象應用通知以后創(chuàng)建的對象。
切入點:切面通知執(zhí)行的“地點的定義
連接點:與切入點匹配的執(zhí)行點
Spring中支持的五種類型的Advice
即Aop在不改變原有代碼的情況下,去增加新的功能。
使用Spring實現(xiàn)Aop
使用AOP,需要導入一個依賴包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version> </dependency>第一種方式——通過Spring API實現(xiàn)
業(yè)務接口和實現(xiàn)類
public interface UserService {public void add();public void delete();public void update();public void search();} public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加用戶");}@Overridepublic void delete() {System.out.println("刪除用戶");}@Overridepublic void update() {System.out.println("更新用戶");}@Overridepublic void search() {System.out.println("查詢用戶");} }增強類
前置增強
后置增強
去Spring的文件中注冊,并實現(xiàn)aop切入實現(xiàn)
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注冊bean--><bean id="userService" class="com.zhonghu.service.UserServiceImpl"/><bean id="log" class="com.zhonghu.log.Log"/><bean id="afterLog" class="com.zhonghu.log.AfterLog"/><!--aop的配置--><aop:config><!--切入點 expression:表達式匹配要執(zhí)行的方法--><aop:pointcut id="pointcut" expression="execution(* com.zhonghu.service.UserServiceImpl.*(..))"/><!--執(zhí)行環(huán)繞; advice-ref執(zhí)行方法 . pointcut-ref切入點--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config></beans>測試
public class MyTest {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService) context.getBean("userService");userService.search();} }Aop的重要性:很重要,一定要理解其中的思路
Spring的Aop就是將公共的業(yè)務(日志、安全)和領域業(yè)務結合起來,當執(zhí)行領域業(yè)務時,將會把公共業(yè)務加起來,實現(xiàn)公共業(yè)務的重復利用,領域業(yè)務更加純粹,程序員只需要專注領域業(yè)務。
其本質(zhì)還是動態(tài)代理
第二種方式:自定義類來實現(xiàn)Aop
目標業(yè)務不變依舊是userServiceImpl
切入類
public class DiyPointcut {public void before(){System.out.println("---------方法執(zhí)行前---------");}public void after(){System.out.println("---------方法執(zhí)行后---------");}}去spring中配置
<!--第二種方式自定義實現(xiàn)--> <!--注冊bean--> <bean id="diy" class="com.zhonghu.config.DiyPointcut"/><!--aop的配置--> <aop:config><!--第二種方式:使用AOP的標簽實現(xiàn)--><aop:aspect ref="diy"><aop:pointcut id="diyPonitcut" expression="execution(* com.zhonghu.service.UserServiceImpl.*(..))"/><aop:before pointcut-ref="diyPonitcut" method="before"/><aop:after pointcut-ref="diyPonitcut" method="after"/></aop:aspect> </aop:config>測試
public class MyTest {@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService) context.getBean("userService");userService.add();} }第三種方式——使用注解
注解實現(xiàn)的增強類
package com.zhonghu.config;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;@Aspect public class AnnotationPointcut {@Before("execution(* com.zhonghu.service.UserServiceImpl.*(..))")public void before(){System.out.println("---------方法執(zhí)行前---------");}@After("execution(* com.zhonghu.service.UserServiceImpl.*(..))")public void after(){System.out.println("---------方法執(zhí)行后---------");}@Around("execution(* com.zhonghu.service.UserServiceImpl.*(..))")public void around(ProceedingJoinPoint jp) throws Throwable {System.out.println("環(huán)繞前");System.out.println("簽名:"+jp.getSignature());//執(zhí)行目標方法proceedObject proceed = jp.proceed();System.out.println("環(huán)繞后");System.out.println(proceed);} }在spring配置文件中,注冊bean,并增加支持注解的配置
<!--第三種方式:注解實現(xiàn)--> <bean id="annotationPointcut" class="com.zhonghu.config.AnnotationPointcut"/> <aop:aspectj-autoproxy/>aop:aspectj-autoproxy:說明
通過aop創(chuàng)建的命名空間的<aop:aspectj-autoproxy />聲明自動為spring容器中那些配置@aspectJ切面的bean創(chuàng)建代理,織入切面。當然,spring 在內(nèi)部依舊采用AnnotationAwareAspectJAutoProxyCreator進行自動代理的創(chuàng)建工作,但具體實現(xiàn)的細節(jié)已經(jīng)被<aop:aspectj-autoproxy />隱藏起來了
<aop:aspectj-autoproxy />有一個proxy-target-class屬性,默認為false,表示使用jdk動態(tài)代理織入增強,當配為<aop:aspectj-autoproxy poxy-target-class=“true”/>時,表示使用CGLib動態(tài)代理技術織入增強。不過即使proxy-target-class設置為false,如果目標類沒有聲明接口,則spring將自動使用CGLib動態(tài)代理
進行自動代理的創(chuàng)建工作,但具體實現(xiàn)的細節(jié)已經(jīng)被<aop:aspectj-autoproxy />隱藏起來了。
<aop:aspectj-autoproxy />有一個proxy-target-class屬性,默認為false,表示使用jdk動態(tài)代理織入增強,當配為<aop:aspectj-autoproxy poxy-target-class=“true”/>時,表示使用CGLib動態(tài)代理技術織入增強。不過即使proxy-target-class設置為false,如果目標類沒有聲明接口,則spring將自動使用CGLib動態(tài)代理
版權聲明:本文為CSDN博主「冢狐」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/issunmingzhi/java/article/details/106051063
推薦閱讀不知道路由器工作原理?沒關系,來這看看!看不懂你捶我 | 原力計劃
秋名山老司機從上車到翻車的悲痛經(jīng)歷,帶你深刻了解什么是 Spark on Hive!| 原力計劃
出道50年+!乘風破浪的編程語言們,能二次翻紅嗎?
Service Mesh 如何重定義云原生計算?阿里服務網(wǎng)格技術大揭秘
國士無雙:賣掉美國房子,回國創(chuàng)辦姚班,他只為培養(yǎng)一流的程序員!
萬字長文帶你入門 GCN
真香,朕在看了!
總結
以上是生活随笔為你收集整理的Spring 从入门到入土——AOP 就这么简单!| 原力计划的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 赠书 | SkyWalking 观测 S
- 下一篇: 深度思考 Spring Cloud +