Java使用Porxy和InvocationHandler實現動態代理
代理模式:通過代理間接的呼叫被代理物件的方法,結構如下:
Java的反射包提供了一個Porxy類和InvokationHandler介面。它們結合在一起後可以建立動態代理類。Porxy類基於傳遞的引數建立動態代理類。InvokationHandler則用於激發動態代理類的方法。這個過程是在程式執行過程中動態生成與處理的,所以叫動態代理。分析一下
Porxy類
Porxy類提供了一個靜態方法建立動態代理類。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
1、ClassLoader:ClassLoader會定義動態代理類,ClassLoader可以通過類或者介面獲得,如果我們想通過介面獲得,呼叫方法如下。
Task.class.getClassLoader()
如果通過類來獲得,加入我們有一個類TaskImpl實現了Task介面,我們有個TaskImpl的物件ob,然後ClassLoader獲取方法如下
ob.getClassLoader()
2、 Class<?>[] interfaces:動態代理類需要實現的介面
3、InvocationHandler:傳遞一個實現了InvokationHandler介面的類的例項
InvokationHandler
InvokationHandler是Java 反射包裡面的一個介面。InvokationHandler通過使用者類來實現,來激發一個動態代理類的方法。它只有一個方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
1、Object:實現方法的代理物件
2、Method:代理例項激發的方法,Porxy引數中的介面方法
3、Object[]:傳遞給方法的一系列引數
實現
1、我們提供一個介面
package me.aihe;
public interface Task {
void setData(String data);
int getCalData(int x);
}
2、實現這個介面
package me.aihe;
public class TaskImpl implements Task {
@Override
public void setData(String data) {
System.out.println(data+ " Data is saved");
}
@Override
public int getCalData(int x) {
return x * 10;
}
}
3、定義自己的InvokationHandler類,並且實現InvokationHandler介面的Invoke方法
package me.aihe;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MyInvokationHandler implements InvocationHandler {
private Object obj;
public MyInvokationHandler(Object object){
this.obj = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
if(method.getName().contains("get")){
System.out.println("...get Method Executing...");
}else{
System.out.println("...set Method Executing...");
}
result = method.invoke(obj, args);
return result;
}
}
4、建立一個工廠類獲取動態代理類:
package me.aihe;
import java.lang.reflect.Proxy;
public class ProxyFactory {
public static Object newInstance(Object ob) {
return Proxy.newProxyInstance(ob.getClass().getClassLoader(),
new Class<?>[] { Task.class }, new MyInvokationHandler(ob));
}
}
5、提供我們的測試類
package me.aihe;
public class Test {
public static void main(String[] args) {
Task task = (Task)ProxyFactory.newInstance(new TaskImpl());
task.setData("Test");
System.out.println("============");
System.out.println(task.getCalData(5));
}
}
看到程式的輸出結果:
...set Method Executing...
Test Data is saved
============
...get Method Executing...
50
總結
動態代理的實現流程:
1、建立一個介面
2、提供一個實現這個介面的類
3、建立一個實現了InvokationHandler介面的類,實現Invoke方法。
傳遞引數:實現介面的類
4、可選:建立一個代理工廠。
返回值傳遞引數:ClassLoader,實現的介面,實現介面的類
參考:
相關文章
- jdk proxy invocationhandler (jdk動態代理)JDK
- Mybatis(一)Porxy動態代理和sql解析替換MyBatisSQL
- SAP ABAP和Java的動態代理實現Java
- Java JDK 動態代理使用及實現原理分析JavaJDK
- java靜態代理和動態代理Java
- Java JDK 動態代理(AOP)使用及實現原理分析JavaJDK
- Java代理(jdk靜態代理、動態代理和cglib動態代理)JavaJDKCGLib
- Java代理設計模式(Proxy)的四種具體實現:靜態代理和動態代理Java設計模式
- Java 靜態代理和動態代理的使用及原理解析Java
- Java動態代理 jdk和cglib的實現比較JavaJDKCGLib
- Java-JDK動態代理(AOP)使用及實現原理分析JavaJDK
- Java中的靜態代理和動態代理Java
- 反射-動態代理的概述和實現反射
- java 反射和動態代理Java反射
- java動態代理如何使用Java
- Java代理機制分析——JDK代理(Proxy、InvocationHandler與示例)JavaJDK
- JDK解構 - Java中的引用和動態代理的實現JDKJava
- Java基礎系列-靜態代理和動態代理Java
- SmartSql使用教程(2)—使用動態代理實現CURDSQL
- go如何實現類似java的動態代理GoJava
- java 動態代理簡單使用Java
- JAVA 靜態代理 & 動態代理Java
- Android 動態代理以及利用動態代理實現 ServiceHookAndroidHook
- JDK 和 CGLib 實現動態代理和區別JDKCGLib
- java執行原理、靜態代理和動態代理區分Java
- 靜態代理和動態代理
- java動態代理Java
- Java動態代理(JDK和cglib)JavaJDKCGLib
- Java動態代理和反射機制Java反射
- 【JAVA】代理模式之Java動態代理Java模式
- Java 8 動態代理的新技巧(1):為什麼使用動態代理?Java
- 使用Netty和動態代理實現一個簡單的RPCNettyRPC
- java動態代理動態在哪裡?Java
- 深入理解 Java 反射和動態代理Java反射
- Java動態代理(AOP)Java
- java動態代理(1)Java
- java 的動態代理Java
- Java Proxy動態代理Java