設計模式-23種設計模式-結構型-代理模式
阿新 • • 發佈:2021-07-07
一、代理模式介紹
二、代理模式引入
1.靜態代理
程式碼實現(Java):
//介面 public interface ITeacherDao { void teach(); // 授課的方法 }
public class TeacherDao implements ITeacherDao { @Override public void teach() { System.out.println(" 老師授課中 。。。。。"); } }
//代理物件,靜態代理 public class TeacherDaoProxy implementsITeacherDao{ private ITeacherDao target; // 目標物件,通過介面來聚合 //構造器 public TeacherDaoProxy(ITeacherDao target) { this.target = target; } @Override public void teach() { System.out.println("開始代理 完成某些操作。。。。。 ");//方法 target.teach(); System.out.println("提交。。。。。");//方法 } }
public class Client { public static void main(String[] args) { //建立目標物件(被代理物件) TeacherDao teacherDao = new TeacherDao(); //建立代理物件, 同時將被代理物件傳遞給代理物件 TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao); //通過代理物件,呼叫到被代理物件的方法//即:執行的是代理物件的方法,代理物件再去呼叫目標物件的方法 teacherDaoProxy.teach(); } }
2.動態代理(JDK代理、介面代理)
程式碼實現(Java):
//介面 public interface ITeacherDao { void teach(); // 授課方法 void sayHello(String name); }
public class TeacherDao implements ITeacherDao { @Override public void teach() { System.out.println(" 老師授課中.... "); } @Override public void sayHello(String name) { System.out.println("hello " + name); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyFactory { //維護一個目標物件 , Object private Object target; //構造器 , 對target 進行初始化 public ProxyFactory(Object target) { this.target = target; } //給目標物件 生成一個代理物件 public Object getProxyInstance() { //說明 /* * public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) //1. ClassLoader loader : 指定當前目標物件使用的類載入器, 獲取載入器的方法固定 //2. Class<?>[] interfaces: 目標物件實現的介面型別,使用泛型方法確認型別 //3. InvocationHandler h : 事情處理,執行目標物件的方法時,會觸發事情處理器方法, 會把當前執行的目標物件方法作為引數傳入 */ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("JDK代理開始~~"); //反射機制呼叫目標物件的方法 Object returnVal = method.invoke(target, args); System.out.println("JDK代理提交"); return returnVal; } }); } }
public class Client { public static void main(String[] args) { //建立目標物件 ITeacherDao target = new TeacherDao(); //給目標物件,建立代理物件, 可以轉成 ITeacherDao ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance(); // proxyInstance=class com.sun.proxy.$Proxy0 記憶體中動態生成了代理物件 System.out.println("proxyInstance=" + proxyInstance.getClass()); //通過代理物件,呼叫目標物件的方法 //proxyInstance.teach(); proxyInstance.sayHello(" tom "); } }
3.Cglib代理
程式碼實現(Java):
相關jar包:
public class TeacherDao { public String teach() { System.out.println(" 老師授課中 , 我是cglib代理,不需要實現介面 "); return "hello"; } }
import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class ProxyFactory implements MethodInterceptor { //維護一個目標物件 private Object target; //構造器,傳入一個被代理的物件 public ProxyFactory(Object target) { this.target = target; } //返回一個代理物件: 是 target 物件的代理物件 public Object getProxyInstance() { //1. 建立一個工具類 Enhancer enhancer = new Enhancer(); //2. 設定父類 enhancer.setSuperclass(target.getClass()); //3. 設定回撥函式 enhancer.setCallback(this); //4. 建立子類物件,即代理物件 return enhancer.create(); } //重寫 intercept 方法,會呼叫目標物件的方法 @Override public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable { System.out.println("Cglib代理模式 ~~ 開始"); Object returnVal = method.invoke(target, args); System.out.println("Cglib代理模式 ~~ 提交"); return returnVal; } }
public class Client { public static void main(String[] args) { //建立目標物件 TeacherDao target = new TeacherDao(); //獲取到代理物件,並且將目標物件傳遞給代理物件 TeacherDao proxyInstance = (TeacherDao)new ProxyFactory(target).getProxyInstance(); //執行代理物件的方法,觸發intecept 方法,從而實現 對目標物件的呼叫 String res = proxyInstance.teach(); System.out.println("res=" + res); } }