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