美文网首页
动态代理浅析

动态代理浅析

作者: He_Yifeng | 来源:发表于2019-01-17 14:47 被阅读3次

    动态代理:为其它对象提供一种代理以控制对这个对象的访问。
    在程序运行期间,通过反射创建出来的代理类。

    JDK动态代理,顾名思义是jdk为我们提供的。jdk动态代理中必须了解的一个类和一个接口:Proxy类和InvocationHandler接口:

    先看InvocationHandler接口:

    public interface InvocationHandler {
      public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable;
    }
    

    该接口只有一个invoke方法,有三个参数:

    proxy:代理类对象
    method:被代理方法
    args:被代理方法的参数列表
    

    而Proxy类我们用到的方法便是newProxyInstance方法:

    public class Proxy implements java.io.Serializable {
            ... 
    
            public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
            throws IllegalArgumentException    
    
            ...
    }
    

    也是有三个参数:

    loader:类加载器
    interfaces:代理类实现的所有接口
    h:InvocationHandler接口的一个实例,此类中必须存在InvocationHandler接口实现类的引用
    

    例如:

    /**
    *  Engineer:类加载器,是一个接口
    *  handler:代理实例的代理程序
    */
    Engineer proxy = (Engineer) Proxy.newProxyInstance(Engineer.class.getClassLoader(), new Class[]{Engineer.class}, handler);
    

    通过Proxy的newProxyInstance方法创建出代理对象,再有代理对象的执行方法。

    jdk动态代理只支持委托类和代理类实现共同的接口的方式。如果实现共同的父类的情况,不能使用jdk动态代理,可以使用cglib动态代理。


    cglib动态代理:
    1.定义一个被代理的目标类(cglib不需要定义接口)

    public class HelloService {
    
        public void sayHello(){
            System.out.println("hello heyifeng");
        }
    }
    

    2.定义Proxy类,需要继承MethodInterceptor,实现intercept方法(MethodInterceptor类中只有intercept一个方法):
    该代理的目的实在被代理目标类方法前后加入切面方法。

    public class HelloMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("Before:"+method.getName());
            //目标类执行的方法
            Object object = methodProxy.invokeSuper(o, objects);
            System.out.println("After:"+method.getName());
            return object;
        }
    }
    

    3.Client测试:

    public class Client {
    
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(HelloService.class);  //继承被代理类
            enhancer.setCallback(new HelloMethodInterceptor());  //设置回调
            HelloService helloService = (HelloService) enhancer.create();  //增强的目标类,生成代理对象
            helloService.sayHello();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:动态代理浅析

          本文链接:https://www.haomeiwen.com/subject/mhwbdqtx.html