一、MethodInterceptor簡介
public interface MethodInterceptor extends Callback {
Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable;
}
MethodInterceptor是CGLIB動態代理中的一個回調接口,用於攔截方法調用,並在方法調用前後執行一些額外的邏輯。它定義了一個intercept()方法,在代理對象調用被代理方法前後都會被調用。
二、MethodInterceptor源碼分析
MethodInterceptor接口源碼如下:
public interface MethodInterceptor extends Callback {
Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable;
}
這個接口繼承了Callback接口,同時聲明了一個intercept()方法,該方法用於代理對象的方法攔截。參數含義如下:
- obj:代理對象
- method:被代理方法
- args:被代理方法的參數
- proxy:MethodProxy對象,可以用來執行原始方法
接下來看一下MethodInterceptor接口的實現類:
public class UserServiceInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("進入代理方法");
Object result = proxy.invokeSuper(obj, args);
System.out.println("離開代理方法");
return result;
}
}
在UserServiceInterceptor實現類中,我們重寫了intercept()方法,並在方法調用前後分別打印了日誌。此時通過CGLIB動態代理創建一個UserService對象,然後使用MethodInterceptor攔截該對象,就可以在方法調用前後,添加一些額外的邏輯。
三、MethodInterceptor的應用場景
1、MethodInterceptor找不到
如果使用Spring AOP切面,我們往往需要在目標Bean上添加註解或進行配置,然後再在配置文件中指定切面來對目標對象的方法進行增強。但是在某些情況下,我們無法修改目標Bean的代碼,這時候就需要使用MethodInterceptor來對目標對象的方法進行增強。
2、MethodInterceptor攔截不到
有時候我們可能會遇到一些問題,例如使用代理對象調用String類的equals()方法,但是通過MethodInterceptor並不能攔截到equals()方法的調用。這是因為equals()方法是final方法,CGLIB無法對其進行代理。
3、MethodInterceptor接口的作用
MethodInterceptor接口的作用是攔截方法調用,並在方法調用前後執行一些額外的邏輯。我們可以在intercept()方法中添加一些我們需要的額外邏輯,例如日誌、緩存、權限等。
四、MethodInterceptor示例代碼
下面是一個使用MethodInterceptor實現事務攔截的示例代碼:
public class TransactionInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Connection connection = getConnection();
try {
connection.setAutoCommit(false);
Object result = proxy.invokeSuper(obj, args);
connection.commit();
return result;
} catch (Exception e) {
e.printStackTrace();
connection.rollback();
throw e;
} finally {
closeConnection();
}
}
private void closeConnection() {
//...
}
private Connection getConnection() {
//...
}
}
在TransactionInterceptor類中,我們定義了一個intercept()方法,用於實現事務攔截的邏輯。首先獲取數據庫連接,然後關閉自動提交,執行被代理對象的方法,如果方法調用成功則提交事務,否則回滾事務。最後釋放數據庫連接。
接下來我們使用CGLIB動態代理來創建UserService對象,並使用TransactionInterceptor攔截該對象,實現事務的攔截和管理。
Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserService.class); TransactionInterceptor transactionInterceptor = new TransactionInterceptor(); enhancer.setCallback(transactionInterceptor); UserService userService = (UserService) enhancer.create(); userService.addUser(user);
以上代碼中,我們使用Enhancer對UserService類進行代理,使用TransactionInterceptor對代理對象進行攔截。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/192688.html
微信掃一掃
支付寶掃一掃