代理模式
Posted afei1759
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理模式相关的知识,希望对你有一定的参考价值。
Java有三种代理模式:静态代理、jdk动态代理、cglib代理
-
- 静态代理
目的是对目标类的功能进行扩展
//接口 public interface ISing) public void msg(); //目标类 public class Sing implements ISing public void msg() System.out.println("我在唱歌..."); //代理类 public class SingProxy implements ISing private Sing sing; public SingProxy( Sing s) this.sing=s; public void msg() //此处为额外添加的功能... this.sing.msg(); //此处为额外添加的功能... //主类 public class Main public static void main(String[] args) //目标对象 ISing sing=new Sing(); //代理对象 SingProxy singProxy=new SingProxy(sing); //本质是执行目标对象的方法 singProxy.msg();
- jdk动态代理
静态代理的缺点是要提前写出代理类,jdk动态代理则可以在运行时动态生成代理类,java底层封装了实现细节,所以代码非常简单,格式写法固定:调用Proxy类的静态方法newProxyInstance(),该方法会返回一个代理类的对象,该方法为static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )接收的三个参数依次为- ClassLoader loader:指定目标对象使用的类加载器,写法固定
- Class<?>[] interfaces:指定目标对象实现的接口,写法固定
- InvocationHandler h:事件处理接口,需传入一个实现类,一般直接使用匿名内部类
//代码写法固定 public class Test public static void main(String[] args) Sing target = new Sing(); ISing singProxy = (ISinger) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable System.out.println("此处为额外实现的功能..."); //执行目标对象方法 Object returnValue = method.invoke(target, args); System.out.println("此处为额外实现的功能..."); return returnValue; ); //调用后的本质是执行目标的msg方法 singProxy.msg();
静态代理和JDK代理类都必须实现一个或多个接口,若没有,则可以使用cglib代理。- cglib代理
cglib代理也叫作子类代理,它构建一个目标类的子类(作为代理类),进而添加额外的功能,在Spring的AOP中,如果加入容器的目标类有实现接口,用JDK代理,若没有实现接口,用cglib代理。cglib代理对目标类的要求:Spring的核心包中已经包括了cglib功能,需直接引入spring-core-3.2.5.jar;目标类不能为final修饰;目标类的对象方法如果为final/static,那么就不会被拦截,即不会执行额外的功能,此时cglib失效;//目标类(没有接口) public class Sing public void msg() System.out.println("我在唱歌..."); //Cglib工厂类 public class ProxyFactory implements MethodInterceptor // 维护目标对象 private Object target; public ProxyFactory(Object target) this.target = target; // 给目标对象创建一个子类对象(子类代理对象,子类做代理类) public Object getProxyInstance() //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建目标类的子类对象(子类代理对象) return en.create(); //代码写法固定 @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable System.out.println("此处为额外实现的功能..."); //执行目标对象的方法 Object returnValue = method.invoke(target, args); System.out.println("此处为额外实现的功能..."); return returnValue; //主类 public class Main public static void main(String[] args) //目标对象,没有接口 Sing target = new Sing(); //代理对象 Sing proxy = (Sing)new ProxyFactory(target).getProxyInstance(); proxy.msg();//执行子类代理对象的方法
- 静态代理
以上是关于代理模式的主要内容,如果未能解决你的问题,请参考以下文章
设计模式代理模式 ( 代理模式结构 | 客户端 | 主题对象 | 被代理对象 | 代理对象 )
设计模式 结构型模式 -- 代理模式(动态代理(CGLIB动态代理)三种代理的对比(静态代理动态代理(JDK代理和CGLIB代理)优缺点使用场景))