设计模式 - 代理模式(jdk)
定义:为另一个对象提供一个替身或占位符以控制对这个对象的访问。
一、静态代理
静态代理说白了就是把原先直接调用被代理类的方法放到代理类来调用,同时
我们可以在代理类额外的添加一些操作。
接口:
package com.proxy.example; public interface Employ { void work(); }
实现:
package com.proxy.example; public class Engineer implements Employ { @Override public void work() { System.out.println("写代码。。。"); } }
代理:
package com.proxy.example; public class StaticProxy implements Employ { private Employ employ; public StaticProxy(Employ employ) { super(); this.employ = employ; } @Override public void work() { punchCard(); employ.work(); getfforkunch(); } private void punchCard(){ System.out.println("上班打卡。。。"); } private void getfforkunch(){ System.out.println("下班打卡。。。"); } }
测试:
package com.proxy.example; public class TestStaticProxy { public static void main(String[] args) { StaticProxy proxy = new StaticProxy(new Engineer()); proxy.work(); } }
二、jdk动态代理
从前面的静态代理可以看出,我们可以使用代理添加一些额外的操作,但是如果我有
许多不同的接口的实现类要代理,那么就要写很多不同的静态代理类,因此动态代理就孕育而生了。
在添加一个被代理的类:
接口:
package com.proxy.example.dynamic; public interface Manager { void analysis(); }
实现:
package com.proxy.example.dynamic; public class DemandManager implements Manager { @Override public void analysis() { System.out.println("分析需求。。。"); } }
创建代理的类:
package com.proxy.example.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } /** * proxy: 指代我们所代理的那个对象 * method: 指代的是我们所要调用真实对象的某个方法的Method对象 * args: 指代的是调用真实对象某个方法时接受的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { punchCard(); Object result = method.invoke(target, args); getfforkunch(); return result; } private void punchCard(){ System.out.println("上班打卡。。。"); } private void getfforkunch(){ System.out.println("下班打卡。。。"); } /** * 通过Proxy类的newProxyInstance方法来创建我们的代理类对象,三个参数含义: * 第一个参数target.getClass().getClassLoader() ,我们这里使用被代理对象target这个类的ClassLoader对象来加载我们的代理对象 * 第二个参数target.getClass().getInterfaces(),我们这里为代理对象提供的接口是被代理对象所实现的接口,这样我们生成的代理对象的方法就有我们被代理的对象的方法了 * 第三个参数this, 指当前的代理对象 */ public Object getProxy() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } }
测试:
package com.proxy.example.dynamic; import com.proxy.example.Employ; import com.proxy.example.Engineer; public class TestDynamicProxy { public static void main(String[] args) { Engineer engineer = new Engineer(); DynamicProxy engineerProxy = new DynamicProxy(engineer); Employ employEngineer = (Employ)engineerProxy.getProxy(); employEngineer.work(); Manager manager = new DemandManager(); DynamicProxy managerProxy = new DynamicProxy(manager); Manager demandManager = (Manager)managerProxy.getProxy(); demandManager.analysis(); } }
如果按照静态代理就要再写一个代理类,但是动态代理就可以和它的名字一样进行动态的生成代理类。