一、代理
代理是一种设计模式,即通过代理对象访问目标对象;这样的好处是可以在目标对象原有功能的基础上,在代理对象中扩展更多的功能。
二、三种代理
1.静态代理
需要定义接口或父类,目标类和代理类都要实现接口或继承父类。
package com.cary.proxy; /** * 基类 */ public interface IBuy { void buyHouse(); }
package com.cary.proxy; /** * 目标对象:房子 */ public class House implements IBuy { @Override public void buyHouse() { System.out.print("我是房子"); } }
package com.cary.proxy; /** * 代理对象:中介 */ public class Intermediary implements IBuy{ private IBuy mTarget; public Intermediary(IBuy target){ this.mTarget = target; } @Override public void buyHouse() { System.out.println("收点中介费"); System.out.println("推荐房源"); mTarget.buyHouse();//买房子 System.out.println("办理房产手续"); } }
package com.cary.proxy; /** * 测试 */ public class Main { public void buyHouse(){ IBuy house = new House();//目标对象 Intermediary intermediary = new Intermediary(house);//代理对象 intermediary.buyHouse();//通过代理买房子 } }
2.动态代理
动态代理不需要实现接口,但目标对象必须实现接口,否则无法使用动态dialing。通多调用jdk中newProxyInstance方法即可在内存中动态生成代理对象。
方法声明:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
- ClassLoader loader:目标对象的类加载器。
- Class interfaces:目标对象实现的接口类型。
- InvocationHandler h:目标对象方法处理器,执行对象的方法时,被执行方法的会作为参数传递给该处理器。
package com.cary.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 动态代理 */ public class ProxyFactory { private Object mTarget;//目标对象 public ProxyFactory(Object target){ this.mTarget = target; } public Object getProxy(){ return Proxy.newProxyInstance(mTarget.getClass().getClassLoader(), mTarget.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("增强操作1"); Object result = method.invoke(mTarget, args);//执行目标对象方法 System.out.println("增强操作2"); return result; } }); } }
package com.cary.proxy; /** * 测试 */ public class Main { public void buyHouse(){ IBuy house = new House();//目标对象 IBuy proxy = (IBuy) new ProxyFactory(house).getProxy(); proxy.buyHouse();//执行方法时,会调用InvocationHandler处理目标方法 } }
3.Cglib代理
上面的两种代理都需要目标对象实现一个接口,这种代理跨越这种限制。Cglib是一个开源项目,需要引入cglib-nodep-xx.jar包。
Cglib的原理是目标类动态生成一个子类,覆盖目标类中的方法来增强内容,因为采用的是继承方式,所以对final修饰的类和final修饰的方法无法处理。
补充:https://my.oschina.net/kun123/blog/726812