通过代理模式 ,代理类可以在被代理类的基础上做前置和后置的操作。---- 代理类就好比 房产中介或者代购,买方只要通过中介,就可以购买到房子或者想要的东西。中介提供 售前和售后的服务。
静态代理
通过封装被代理的类的方法,在方法前后增加增强的代码。缺点是,每次扩展一个方法 ,都需要修改代理类。
例如
public class Lison { AaFactory aaFactory = new AaFactory(); BbFactory bbFactory = new BbFactory(); public void getManToolsFactroy(){ System.out.println("我是getManToolsFactroy方法前置增强"); aaFactory.saleManTools(20); System.out.println("我是getManToolsFactroy方法后置增强"); } public void getWomanToolsFactroy(){ System.out.println("我是getWomanToolsFactroy方法前置增强"); bbFactory.saleWomanTools(20); System.out.println("我是getWomanToolsFactroy方法后置增强"); }
//...... }
又或者
public class Lison2 implements ManToolsFactory,WomanToolsFactory { public ManToolsFactory factory = new AaFactory(); public WomanToolsFactory wFactory = new BbFactory(); public Lison2() { } @Override public void saleManTools(int size) { System.out.println("我是saleManTools方法前置增强"); factory.saleManTools(20); System.out.println("我是saleManTools方法后置增强"); } @Override public void saleWomanTools(int size) { // TODO Auto-generated method stub System.out.println("我是saleWomanTools方法前置增强"); wFactory.saleWomanTools(20); System.out.println("我是saleWomanTools方法后置增强"); } }
这两种方法区别不大,一个是通过自己新增方法,实现代理其他类。一个是通过实现接口的方法
动态代理
符合开闭原则,只要扩展被代理类的接口和实现类,然后直接 动态 提供代理服务
这是代理类
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class LisonCompany1 implements InvocationHandler { //被代理的对象 Object factory; public Object getFactory() { return factory; } public void setFactory(Object factory) { this.factory = factory; } //获取动态代理对象实例 //,调度员工 //通过Proxy 获取动态代理的对象 //第一个参数,类加载器。因为factory和 LisonCompany 是在同一个类里面,所以就用factory.getClass().getClassLoader() //第二个参数,指定的接口 public Object getProxyInstance(){ return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this); } public LisonCompany1() { } public LisonCompany1( Object factory) { this.factory = factory; } @Override //通过代理对象,将方法争强 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("前置增强,售前服务,市场调研"); Object ret = method.invoke(factory, args); System.out.println("后置增强,精美包装"); return ret; } }
这是被代理的接口:
public interface ManToolsFactory { void saleManTools(int size); }
这是被代理的实现类:
public class AaFactory implements ManToolsFactory { @Override public void saleManTools(int size) { System.out.println("定制size="+size+"女模特"); } }
这是测试的main方法
import test.designpatterns.proxy.dynamic.LisonCompany1; import test.designpatterns.proxy.staticc.AaFactory; import test.designpatterns.proxy.staticc.BbFactory; import test.designpatterns.proxy.staticc.Lison; import test.designpatterns.proxy.staticc.Lison2; import test.designpatterns.proxy.staticc.ManToolsFactory; import test.designpatterns.proxy.staticc.WomanToolsFactory; import test.designpatterns.proxy.util.ProxyUtil; public class Client { public static void main(String[] args) { System.out.println("-----------------------------静态代理1"); //每次增加需求,不仅需要增加某工厂类,例如化妆品工厂类,Lison对象需要做修改,违背了 面向对象设计原则(单一职责原则),和下面静态代理2一样的问题 //静态代理不符合开闭原则 Lison lison = new Lison(); lison.getManToolsFactroy(); lison.getWomanToolsFactroy(); System.out.println("-----------------------------静态代理2"); Lison2 lison2 = new Lison2(); lison2.saleManTools(100); lison2.saleWomanTools(200); System.out.println("-----------------------------动态代理"); ManToolsFactory aFactory = new AaFactory(); WomanToolsFactory bFactory = new BbFactory(); //LisonCompany对象不用修改,直接增加Factory类 用动态代理Proxy就可以或者对应的方法 LisonCompany1 lisonCompany = new LisonCompany1(); lisonCompany.setFactory(aFactory); LisonCompany1 lisonCompany2 = new LisonCompany1(); lisonCompany2.setFactory(bFactory); //委派一号员工 ManToolsFactory lison0 = (ManToolsFactory) lisonCompany.getProxyInstance(); WomanToolsFactory lison1 = (WomanToolsFactory) lisonCompany2.getProxyInstance(); lison0.saleManTools(60); lison1.saleWomanTools(40); ProxyUtil.generateClassFile(aFactory.getClass(), lison0.getClass().getSimpleName()); } }
控制台打印的输出:
-----------------------------静态代理1 我是getManToolsFactroy方法前置增强 定制size=20女模特 我是getManToolsFactroy方法后置增强 我是getWomanToolsFactroy方法前置增强 定制size=20男模特 我是getWomanToolsFactroy方法后置增强 -----------------------------静态代理2 我是saleManTools方法前置增强 定制size=20女模特 我是saleManTools方法后置增强 我是saleWomanTools方法前置增强 定制size=20男模特 我是saleWomanTools方法后置增强 -----------------------------动态代理 前置增强,售前服务,市场调研 定制size=60女模特 后置增强,精美包装 前置增强,售前服务,市场调研 定制size=40男模特 后置增强,精美包装