代理模式:通過代理間接的調(diào)用被代理對象的方法忠寻,結(jié)構(gòu)如下:
Java的反射包提供了一個Porxy類和InvokationHandler接口建丧。它們結(jié)合在一起后可以創(chuàng)建動態(tài)代理類函似。Porxy類基于傳遞的參數(shù)創(chuàng)建動態(tài)代理類。InvokationHandler則用于激發(fā)動態(tài)代理類的方法。這個過程是在程序執(zhí)行過程中動態(tài)生成與處理的鸡挠,所以叫動態(tài)代理。分析一下
Porxy類
Porxy類提供了一個靜態(tài)方法創(chuàng)建動態(tài)代理類搬男。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
1拣展、ClassLoader:ClassLoader會定義動態(tài)代理類,ClassLoader可以通過類或者接口獲得缔逛,如果我們想通過接口獲得备埃,調(diào)用方法如下姓惑。
Task.class.getClassLoader()
如果通過類來獲得,加入我們有一個類TaskImpl實現(xiàn)了Task接口按脚,我們有個TaskImpl的對象ob于毙,然后ClassLoader獲取方法如下
ob.getClassLoader()
2、 Class<?>[] interfaces:動態(tài)代理類需要實現(xiàn)的接口
3辅搬、InvocationHandler:傳遞一個實現(xiàn)了InvokationHandler接口的類的實例
InvokationHandler
InvokationHandler是Java 反射包里面的一個接口唯沮。InvokationHandler通過用戶類來實現(xiàn),來激發(fā)一個動態(tài)代理類的方法堪遂。它只有一個方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
1介蛉、Object:實現(xiàn)方法的代理對象
2、Method:代理實例激發(fā)的方法溶褪,Porxy參數(shù)中的接口方法
3币旧、Object[]:傳遞給方法的一系列參數(shù)
實現(xiàn)
1、我們提供一個接口
package me.aihe;
public interface Task {
void setData(String data);
int getCalData(int x);
}
2猿妈、實現(xiàn)這個接口
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類,并且實現(xiàn)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彭则、創(chuàng)建一個工廠類獲取動態(tài)代理類:
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));
}
}
看到程序的輸出結(jié)果:
...set Method Executing...
Test Data is saved
============
...get Method Executing...
50
總結(jié)
動態(tài)代理的實現(xiàn)流程:
1、創(chuàng)建一個接口
2贰剥、提供一個實現(xiàn)這個接口的類
3倾剿、創(chuàng)建一個實現(xiàn)了InvokationHandler接口的類筷频,實現(xiàn)Invoke方法蚌成。
傳遞參數(shù):實現(xiàn)接口的類
4、可選:創(chuàng)建一個代理工廠凛捏。
返回值傳遞參數(shù):ClassLoader担忧,實現(xiàn)的接口,實現(xiàn)接口的類
參考: