首先說下作用,method.invoke(Object obj,Object args[])的作用就是調用method類代表的方法,其中obj是對象名,args是傳入method方法的參數
舉個例子:如果接口中沒有close方法,但是實現類中提供了close,那麼就可以用反射來處理,調用實現類的close方法
首先說下作用,method.invoke(Object obj,Object args[])的作用就是調用method類代表的方法,其中obj是對象名,args是傳入method方法的參數
舉個例子:如果接口中沒有close方法,但是實現類中提供了close,那麼就可以用反射來處理,調用實現類的close方法
invoke()方法接收的參數必須爲對象,如果參數爲基本類型數據,必須轉換爲相應的包裝類型的對象。
invoke()方法的返回值總是對象,如果實際被調用的方法的返回類型是基本類型數據,那麼invoke()方法會把它轉換爲相應的包裝類型的對象,再將其返回.
有四種獲得method對象的方法,返回結果是method對象,或者說是 方法的全限定名:
一共有4種方法,全部都在Class類中:
- getMethods(): 獲得類的public類型的方法
- getMethod(String name, Class[] params): 獲得類的特定方法,name參數指定方法的名字,params參數指定方法的參數類型
- getDeclaredMethods(): 獲取類中所有的方法(public、protected、default、private)
- getDeclaredMethod(String name, Class[] params): 獲得類的特定方法,name參數指定方法的名字,params參數指定方法的參數類型
另外關於代理類,以下Proxy.newProxyInstance的相關內容 是整理自B站的一個視頻,
鏈接如下:https://www.bilibili.com/video/av15369076?p=19
Proxy.newProxyInstance
Proxy.newProxyInstance
-
參數1:loader ,類加載器,動態代理類 運行時創建,任何類都需要類加載器將其加載到內存。
-
一般情況:方式1:當前類.class.getClassLoader();
-
方式2:目標類實例.getClass().get...
-
參數2:Class[] interfaces 代理類需要實現的所有接口
-
方式1:目標類實例.getClass().getInterfaces() ;但是需要注意:這種方法只能獲得自己接口,不能獲得父元素接口
-
方式2:new Class[]{UserService.class}
-
例如:jdbc 驅動 --> DriverManager 不能獲得接口 Connection
-
參數3:InvocationHandler 處理類,接口,必須進行實現類,一般採用匿名內部
-
提供invoke 方法,代理類的每一個方法執行時,都將調用一次invoke
-
參數31:Object proxy :代理對象
-
參數32:Method method : 代理對象當前執行的方法的描述對象(反射)
-
執行方法名:method.getName()
-
參數33:Object[] args :方法實際參數
Invoke方法內部:
-
執行方法:method.invoke(對象,實際參數)
public class MyBeanFactory {
public static UserService createService(){
//1 目標類
final UserService userService = new UserServiceImpl();
//2切面類
final MyAspect myAspect = new MyAspect();
/* 3 代理類:將目標類(切入點)和 切面類(通知) 結合 --> 切面
* Proxy.newProxyInstance
* 參數1:loader ,類加載器,動態代理類 運行時創建,任何類都需要類加載器將其加載到內存。
* 一般情況:當前類.class.getClassLoader();
* 目標類實例.getClass().get...
* 參數2:Class[] interfaces 代理類需要實現的所有接口
* 方式1:目標類實例.getClass().getInterfaces() ;注意:只能獲得自己接口,不能獲得父元素接口
* 方式2:new Class[]{UserService.class}
* 例如:jdbc 驅動 --> DriverManager 獲得接口 Connection
* 參數3:InvocationHandler 處理類,接口,必須進行實現類,一般採用匿名內部
* 提供 invoke 方法,代理類的每一個方法執行時,都將調用一次invoke
* 參數31:Object proxy :代理對象
* 參數32:Method method : 代理對象當前執行的方法的描述對象(反射)
* 執行方法名:method.getName()
* 執行方法:method.invoke(對象,實際參數)
* 參數33:Object[] args :方法實際參數
*
*/
UserService proxService = (UserService)Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前執行
myAspect.before();
//執行目標類的方法
Object obj = method.invoke(userService, args);
//後執行
myAspect.after();
return obj;
}
});
return proxService;
}
}