静态代理
package proxy; /* @author zsben @create 2020-01-06 23:25 */ interface ClothFactory{ void produceCloth(); } //代理类 class ProxyClothFactory implements ClothFactory{ private ClothFactory factory; public ProxyClothFactory(ClothFactory factory){ this.factory = factory; } @Override public void produceCloth() { System.out.println("代理工厂做一些准备工作"); factory.produceCloth(); System.out.println("代理工厂做一些收尾工作"); } } //被代理类 class NikeClothFactory implements ClothFactory{ @Override public void produceCloth() { System.out.println("Nike 开始生产产品"); } } public class StaticProxyTest { public static void main(String[] args) { NikeClothFactory nike = new NikeClothFactory(); ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nike); proxyClothFactory.produceCloth(); } }
动态代理
package proxy; /* 动态代理的举例 AOP:面向切面 @author zsben @create 2020-01-06 23:37 */ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface Human{ String getBelief(); void eat(String food); } class HumanUtil{ public void method1(){ System.out.println("==================通用方法一=================="); } public void method2(){ System.out.println("==================通用方法二=================="); } } //被代理类 class SuperMan implements Human{ @Override public String getBelief() { return "I believe I can fly!"; } @Override public void eat(String food) { System.out.println("我喜欢吃"+food); } } /* * 要想实现动态代理,需要解决的问题: * 问题一:如何根据加载到内存中的被代理类,动态创建一个代理类和其代理对象 * 问题二:当通过代理类的对象调用方法时,如何动态调用被代理类中的同名方法 * * */ class ProxyFactory{ //调用此方法返回一个代理类的对象,解决问题一 public static Object getProxyInstance(Object obj){//obj:被代理类的对象 MyInvocationHandler myInvocationHandler = new MyInvocationHandler(); myInvocationHandler.bind(obj); //返回代理类对象 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),myInvocationHandler); } } class MyInvocationHandler implements InvocationHandler{ private Object obj;//需要使用被代理类的对象进行赋值 public void bind(Object obj){ this.obj=obj; } //当我们通过代理类对象调用方法a时,就会自动调用如下方法:invoke //将被代理类要执行的方法a的功能声明在invoke方法中 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开始代理"); HumanUtil util = new HumanUtil(); util.method1(); //method:代理类对象调用的方法,此方法也就作为被代理类对象要调用的方法 Object returnValue = method.invoke(obj, args); util = new HumanUtil(); util.method2(); System.out.println("结束代理"); //上述方法的返回值就作为invoke的返回值 return returnValue; } } public class ProxyTest { public static void main(String[] args) { SuperMan superMan = new SuperMan(); //proxyInstance : 代理类的对象 Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan); //通过代理类对象调用方法时,会自动的调用被代理类中同名方法 String string = proxyInstance.getBelief(); System.out.println(string); // 其实是交给MyInvocationHandler类的invoke执行了 // obj参数就是superMan,args[]参数就是eat方法的参数列表 proxyInstance.eat("四川麻辣烫"); System.out.println("*****************************************************"); System.out.println("用静态例子里的被代理类"); NikeClothFactory nikeClothFactory = new NikeClothFactory(); ClothFactory proxyInstance1 = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory); proxyInstance1.produceCloth(); } }