Spring AOP兩種使用方式以及如何使用解析

AOP是一種面向切面編程思想,也是面向對象設計(OOP)的一種延伸。

在Spring實現AOP有兩種實現方式,一種是采用JDK動態代理實現,另外一種就是采用CGLIB代理實現,Spring是如何實現的在上篇已經講到了Spring Bean的生命周期以及IOC源碼解析

AOP可以做日志記錄,或者事務回滾,在Spring的事務使用就是通過AOP進行事務的回滾的

JDK動態代理

這個是屬于JDK提供的一種代理方式,需提供接口才能使用,主要用的類有兩個:1、Proxy:這個主要是生成接口代理對象;2、InvocationHandler:反射射包下的一個接口,Proxy生成的代理接口對象,調用接口方法就會走InvocationHandler實現類的invoke()?方法

?使用示例:

//創建一個接口
public class UserDao {String getUserInfo();
}
//實現一個InvocationHandler接口的實現類
public class MyInvocationHandler implements InvocationHandler {//需實現的方法//proxy 代表當前對象自己,建議不要使用,如果使用的話會反復的調用自己,而調用自己會反復走當前invoke方法,容易出現棧溢出;//method 指調用的方法Method;//args 調用方法的參數;@Overridepublic Object invoke(Object proxy, Method method, Object[] args){//....return null;}//獲取接口代理對象public <T> T getProxy(CLass<T> cls){//第一個參數為類加載器,這個可以默認使用當前的AppClassLoader,即使用getClassLoader()方法接口//需創建代理對象的接口class數組,//invocationHandler的實現類對象,這里調用的是當前對象,調用的時候就會走當前對象的invoke方法return (E) Proxy.newProxyInstance(cls.getClassLoader(), new Class<?>[] {cls},this);}}public static void main(Stirng[] args){UserDao dao = new MyInvocationHandler().getProxy(UserDao.class);//這樣就能獲取到了UserDao接口的代理對象了
}

在Spring當中是采用?JdkDynamicAopProxy?這個類實現的,可以去源碼里看一下這個類繼承了InvocationHandler

CGLIB代理

這個代理就比較厲害了,是通過ASM修改 .class字節碼進行實現的,并且不需要接口,具體的組成結構可以去看一下大佬寫的這篇CGLIB(Code Generation Library)

使用示例:

        /*** CGLIB 代理*/Enhancer enhancer = new Enhancer();enhancer.setSuperclass(SpringTest06Service.class);enhancer.setCallback(new MethodInterceptor() {public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {System.out.println(Thread.currentThread().getName()+"run start...");Object result = arg3.invokeSuper(arg0, arg2);System.out.println(Thread.currentThread().getName()+"result:"+result);System.out.println(Thread.currentThread().getName()+"run end...");return result;}});service = (SpringTest06Service) enhancer.create();System.out.println(service);String testAop = service.testAop("aaaaaaaa", "bbbbbbbbbbb");System.out.println(testAop);

在Spring里面實現的類是?ObjenesisCglibAopProxy?

上面就是兩種代理的實現方式,但是在Spring里面是怎么使用的呢

Spring使用AOP

需引入Spring相關的AOP的包

		<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.1.12.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.1.12.RELEASE</version></dependency>

在配置類上需開啟AOP進行方法攔截,@EnableAspectJAutoProxy?啟動AOP代理,這個注解有兩個參數

1、proxyTargetClass:這個是指定使用JDK動態代理攔截(false)還是使用CGLIB進行攔截(true),默認為false,

2、exposeProxy:表示是否能夠讓AopContext訪問,默認為false就是不能訪問。

源碼是怎么解析可以自己去看,這個注解通過使用@Import注入了一個SmartInstantiationAwareBeanPostProcessor的實現類,可以自己調試查看,這里就不具體講了,有空就在聊聊吧

最后配置相對應的切面攔截類

@Aspect
@Component
public class AopConfig {private static final Log log = LogFactory.getLog(AopConfig.class);//切點,需指定到具體修飾符,具體方法名以及具體參數類型,這里表示所有修飾符,com.test.SpringCoreTest.test06.service這個包下的所有類的所有方法并且參數為兩個的類型為String的方法進行攔截@Pointcut("execution(* com.test.SpringCoreTest.test06.service.*.*(String,String))")public void pointCut() {}//執行前,位于Around環繞方法前的后面執行@Before(value = "pointCut()")public void before() {System.out.println("方法執行前 @Before ....");}//執行后,位于Around環繞方法后的后面執行@After(value = "pointCut()")public void after() {System.out.println("方法執行后 @After ....");}//即將返回執行@AfterReturning(value = "pointCut()")public void afterReturning() {System.out.println("方法執行后返回  @AfterReturning ....");}//拋出異常執行@AfterThrowing(value="pointCut()",throwing="e")public void afterThrowing(Exception e) {System.out.println("方法執行異常后返回  @AfterThrowing ....");System.out.println(e);}//環繞方法,能夠攔截執行參數,并且能夠修改@Around(value = "pointCut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("around方法執行前@Around ....");Object obj = joinPoint.proceed();System.out.println("around方法執行后@Around ....");return obj;}}

配置好后,調用攔截的方法就可以觸發AOP攔截了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537139.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537139.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何用python生成可執行程序必須經過_python怎么生成可執行文件

.py文件&#xff1a;對于開源項目或62616964757a686964616fe58685e5aeb931333363393664者源碼沒那么重要的&#xff0c;直接提供源碼&#xff0c;需要使用者自行安裝Python并且安裝依賴的各種庫。(Python官方的各種安裝包就是這樣做的).pyc文件&#xff1a;有些公司或個人因為機…

Jmeter 老司機帶你一小時學會Jmeter

Jmeter的安裝 官網下載地址&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 作為Java應用&#xff0c;是需要JDK環境的&#xff0c;因此需要下載安裝JAVA&#xff0c;并且作必要的的環境變量配置。 一、bin目錄 examples:    目錄中有CSV樣例 jmeter.bat/jmeter…

MongoDB位運算基本使用以及位運算應用場景

最近在公司業務上用到了二進制匹配數據&#xff0c;但是MongoDB進行二進制運算&#xff08;Bitwise&#xff09;沒用過&#xff0c;網上博客文章少&#xff0c;所以就上官網看API&#xff0c;因此記錄一下&#xff0c;順便在普及一下使用二進制位運算的一些應用。 在MongoDB的…

好用的下拉第三方——nicespinner

1.簡介 GitHub地址&#xff1a;https://github.com/arcadefire/nice-spinner Gradle中添加&#xff1a; allprojects {repositories {...maven { url "https://jitpack.io" }} }dependencies {implementation com.github.arcadefire:nice-spinner:1.3.7 }2.使用 xml文…

Mybatis配置文件參數定義

官網有時候進不去&#xff0c;所以就記錄一下Mybatis的配置文件的各項參數定義&#xff0c;大家也可以上官網查詢&#xff0c;官方文檔&#xff0c;進不進的去看各自的緣分了 properties 定義配置&#xff0c;在這里配置的屬性可以在整個配置文件使用&#xff1b;可以加載指定…

python和java后期發展_Python與java的發展前景誰最大

Python和Java是目前IT行業內兩大編程語言&#xff0c;很多人都喜歡拿來比較&#xff0c;一個是后起之秀&#xff0c;潛力無限&#xff1b;一個是行業經典&#xff0c;成熟穩定。對于許多想從事IT行業的同學來說&#xff0c;這兩門語言真的很難抉擇。那么&#xff0c;Python和Ja…

JDK源碼學習筆記——Enum枚舉使用及原理

一、為什么使用枚舉 什么時候應該使用枚舉呢&#xff1f;每當需要一組固定的常量的時候&#xff0c;如一周的天數、一年四季等。或者是在我們編譯前就知道其包含的所有值的集合。 利用 public final static 完全可以實現的功能&#xff0c;為什么要使用枚舉&#xff1f; public…

Mybatis源碼日志模塊分析

看源碼需要先下載源碼&#xff0c;可以去Mybatis的github上的倉庫進行下載&#xff0c;Mybatis 這次就先整理一下日志這一塊的源碼分析&#xff0c;這塊相對來說比較簡單而且這個模塊是Mybatis的基礎模塊。 之前的文章有談到過Java的日志實現&#xff0c;大家也可以參考一下&…

python手機端給電腦端發送數據_期貨交易軟件有哪些比較好用?分手機端和電腦端...

一、電腦端交易軟件期貨電腦端交易軟件目前市場上用的最多的是文華財經和博易大師&#xff0c;這兩個軟件都是免費交易使用的。從投資者使用角度來看&#xff0c;目前電腦端文華財經的評價比博易大師高一些。當然每個投資者有自己的使用習慣&#xff0c;博易大師也有自己優點&a…

Find the Difference(leetcode389)

2019獨角獸企業重金招聘Python工程師標準>>> Given two strings s and t which consist of only lowercase letters. String t is generated by random shuffling string s and then add one more letter at a random position. Find the letter that was added in …

Mybatis源碼之數據源模塊分析

先來看看java純jdbc查詢數據的示例&#xff1a; try {//加載對應的驅動類Class.forName("com.mysql.cj.jdbc.Driver");//創建連接Connection connection DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?serverTimezoneUTC", "roo…

reactnative 獲取定位_[RN] React Native 獲取地理位置

import React, {Component} from react;import {StyleSheet, Text, View}from react-native;exportdefault classTestGeo extends Component {state{longitude:,//經度latitude: ,//緯度city: ,district:,street:,position:,//位置名稱};componentWillMount () >{this.getPo…

第二沖刺階段第三天

查閱資料&#xff0c;修改控件界面轉載于:https://www.cnblogs.com/gyy0/p/10066452.html

Mybatis源碼之緩存模塊分析

緩存這個東西在很多應用中都能看到它們的身影&#xff0c;這次就講講在Mybatis中的緩存是怎么應用的&#xff0c;雖然說吧Mybatis中的緩存基本不怎么用&#xff0c;用的更多是第三方組件redis、MongoDB、MemCache等等。 Mybatis的緩存是基于Map實現的&#xff0c;從緩存中讀寫…

Mybatis源碼之核心流程分析

終于談到了Mybatis最核心的東西了&#xff0c;最核心的就是通過配置XML文件或注解中的SQL&#xff0c;直接調用接口就能執行配置好的SQL語句并封裝成對應的返回類型的數據。 先看一下Mybatis使用示例&#xff1a; //創建Builder對象 SqlSessionFactoryBuilder builder new S…

mimakatz用法_兩步完成利用procdump64+mimikatz獲取win用戶密碼

使用procdump64mimikatz可實現從內存中獲取明文密碼工具鏈接&#xff1a;https://pan.baidu.com/s/1gNc9qLcNSNBohIVrAiqShw 密碼&#xff1a;fc38首先得先獲取到內存文件lsass.exe進程, 它用于本地安全和登陸策略,一般在進程管理器中能看到, 比如這樣1.導出lsass.exeprocdump6…

ios app提交之前需要哪幾個證書

1、遇到的問題 一款App在別人的機器上開發和發布&#xff0c;現在迭代更新和開發需要在一臺新mac機上開發和發布。&#xff08;使用同一個開發者賬號&#xff09;問題&#xff1a; 1.在新mac機器上開發并導入真機測試&#xff0c;是不是需要從別人的機器上面導處開發者證書、開…

Mybatis源碼之與Spring集成包

這次講講Mybatis與Spring的整合&#xff0c;作為兩款優秀的開源框架&#xff0c;被大眾廣泛使用&#xff0c;自然是需要強強聯合的。 使用示例 先看一下怎么使用&#xff0c;首先需要引用這兩款框架的jar包&#xff1a; <dependency>//spring-webmvc會自動去引入其他S…

hadoop主節點切換_hadoop2.0 HA的主備自動切換

在《hadoop2.0 QJM方式的HA的配置》一文中介紹了HA的配置&#xff0c;是通過手工進行主備切換的。本文在這基礎上&#xff0c;繼續介紹HA的主備自動切換(automatic failover)的配置。自動切換是通過配置zookeeper來實現的&#xff0c;關于zookeeper的安裝和配置&#xff0c;在這…

Mybatis源碼之插件模塊分析

總結完這個Mybatis的整體主要功能基本上就差不多完&#xff0c;還有一些細節的部分&#xff0c;后續都會記錄補充。 插件這個東西一般用的比較少&#xff0c;就算用的多的插件也算是PageHelper分頁插件&#xff1b; PageHelper官網&#xff1a;https://github.com/pagehelper…