为一个对象提供一个替身,来控制这个对象的访问。通过代理对象访问目标对象,这样做的好处是可以在目标对象实现的基础上,增强额外的功能操作
被代理的对象可以是远程对象,创建开销大的对象,需要安全控制的对象
代理模式主要分为三种 静态代理,动态代理(也叫接口代理、jdk代理),cglib代理(可以在内存创建对象而不需要实现接口,属于动态代理的范畴)
静态代理
被代理类和代理类需要实现相同接口或者继承父类
public interface BuyHouse { public void housePrice(); }
public class Buyer implements BuyHouse { @Override public void housePrice() { System.out.println("顾客要去买房子"); } }
public class BuyerProxy implements BuyHouse { BuyHouse buyer; public BuyerProxy(BuyHouse buyer) { this.buyer = buyer; } @Override public void housePrice() { System.out.println("中介开始谈条件"); buyer.housePrice(); System.out.println("房子买下来签合约"); } public static void main(String[] args) { BuyerProxy buyerProxy = new BuyerProxy(new Buyer()); buyerProxy.housePrice(); } }
优点:可以动态的扩展代理类的功能而不影响到原来的被代理类的功能
缺点:两者实现同一个接口,所以一旦接口增加方法,目标类和代理类都需要维护
动态代理--动态体现在并没有把对象固定死
代理对象不需要实现接口但是被代理对象还是要实现接口,这其种是使用了jdk的api
public class JDKProxy { Object object; public JDKProxy(Object object) { this.object = object; } public Object getProxyInstance(){ //参数说明 //第一个参数是对象的类加载器 //第二个对象是类对应所有的接口 //第三个参数是即将调用目标类的方法 return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("这是jdk代理买房"); //通过反射来调用方法 Object invoke = method.invoke(object, args); System.out.println("完成购房"); //返回目标方法 return invoke; } }); } public static void main(String[] args) { Buyer buyer=new Buyer(); JDKProxy jdkProxy=new JDKProxy(buyer); //注意这里在使用的时候要转成相应的接口 BuyHouse proxyInstance = (BuyHouse)jdkProxy.getProxyInstance(); proxyInstance.housePrice(); } }
Cglib代理(子类代理)
如果被代理类没有实现任何接口,那么我们就可以使用cglib代理
在内存种构建一个子类对象从而实现对目标对象功能扩展
需要四个包-注意版本
目标类
public class BuyHouse { public void buyHouse(){ System.out.println("我不继承东西,但是我要买房"); } }
代理类
public class ProxyFactory implements MethodInterceptor { Object object; public ProxyFactory(Object object) { this.object = object; } //返回一个代理对象 public Object getProxyInstance(){ //创建一个工具类 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(object.getClass()); //设置回调函数 enhancer.setCallback(this); //返回子类对象 return enhancer.create(); } //这个方法会调用目标的方法 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib代理模式开始啦"); //这里用的也是反射 Object invoke = method.invoke(object, objects); System.out.println("买房结束"); return invoke; } }