代理模式
为某一个对象(委托类)提供一个代理(代理类),用来控制对这个对象的访问
委托类和代理类有一个共同的父类或接口
代理模式的两个设计原则:
- 代理类和委托类具有共同的行为
- 代理类能够增强委托类的行为
常见的代理模式:
静态代理
动态代理
静态代理
代理三要素
1、有共同的行为 —定义接口
2、目标角色 —实现接口
3、代理角色 --实现接口 增强角色行为
public interface Marry { public void toMarry(); }
public class MarryCompanyProxy implements Marry { private Marry target; public MarryCompanyProxy(Marry target) { this.target = target; } @Override public void toMarry() { System.out.println("marry before..."); target.toMarry(); System.out.println("marry after..."); } }
public class You implements Marry { @Override public void toMarry() { System.out.println(" i am marry "); } }
public class StaticProxy { public static void main(String[] args) { Marry marry = new You(); MarryCompanyProxy proxy = new MarryCompanyProxy(marry); proxy.toMarry(); } }
动态代理
JDK动态代理
public interface Marry { public void toMarry(); }
public class You implements Marry { @Override public void toMarry() { System.out.println(" i am marry "); } }
//jdk动态代理类 public class JdkHanlder implements InvocationHandler { //目标对象,为可变对象 private Object target; //通过带参构造器传递目标对象 public JdkHanlder(Object target) { this.target = target; } public Object getProxy(){ Object object = Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); return object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //用户的增强行为 System.out.println("方法执行前"); //调用目标对象中的方法 Object object = method.invoke(target,args); System.out.println("方法执行后"); return object; } }
测试方法
public class StaticProxy { public static void main(String[] args) { You you = new You(); JdkHanlder jdkHanlder = new JdkHanlder(you); Marry target = (Marry) jdkHanlder.getProxy(); target.toMarry(); } }
运行结果
方法执行前 i am marry 方法执行后 Process finished with exit code 0
CGLIB动态代理
JDK动态代理机制只能代理实现了接口的类,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中的方法实现增强,但是因为采用的是继承,所以不能的对final修饰的类进行代理。
public class CglibInterceptor implements MethodInterceptor { //目标对象 private Object target; public CglibInterceptor(Object target) { this.target = target; } //获取代理对象 public Object getProxy(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } /** * 拦截器 1、目标对象的方法调用 2、行为增强 * @param o * @param method * @param objects 参数列表 * @param methodProxy * @return * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("方法执行前"); Object object = methodProxy.invoke(target,objects); System.out.println("方法执行后"); return object; } }
public class You1 { public void toMarry() { System.out.println(" i am marry "); } }
测试
public class StaticProxy { public static void main(String[] args) { You1 you = new You1(); CglibInterceptor cglibInterceptor = new CglibInterceptor(you); You1 you1 = (You1) cglibInterceptor.getProxy(); you1.toMarry(); } }
运行结果
方法执行前 Disconnected from the target VM, address: '127.0.0.1:57413', transport: 'socket' i am marry 方法执行后 Process finished with exit code 0