【动态代理】——cglib与jdk动态代理

来源:互联网 发布:美国公务员 知乎 编辑:程序博客网 时间:2024/06/07 02:06

1、什么是动态代理

    

  说到动态代理,首先要清楚什么是静态代理。在程序运行之前,已经由程序员或工具自动生成源代码,然后再进行编译,类的class文件就已经


存在了。而代理存在的意义就是在程序运行之前并没有具体的源代码出现,也没有类的class文件,在程序运行时通过反射机制动态创建类。那今


天具体介绍两个动态代理的方式。


2、jdk的动态代理

    在jdk中和动态代理的类相关的有两个:

   (1)InvocationHandler

       Object invoke(Object proxy,Method method,Object[] args)

      介绍下各参数的作用:

       Object:生成的代理类。

       Method:代理类中的方法。

       Object:方法的参数。

   (2)Proxy

Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)

      介绍下各参数的作用:

  ClassLoader:类加载器(这是一块很重要的知识,大家可以下去做功课哦)。

  Interface:被代理类的接口。

  h:invocationHandler类中的invoke方法。


下面具体介绍个列子:


client类:

    public static void main(String[] args) {        Dog tatget = new GunDog();        Dog dog = (Dog) MyProxyFactory.getProxy(tatget);        dog.info();        dog.run();    }


代理类的具体实现:

package com.company;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Collection;import java.util.Collections;/** * Created by Tong on 2016/8/14. */public class MyInvokationHandler implements InvocationHandler {    private Object target;    public void setTarget(Object target){        this.target=target;    }    public Object invoke(Object proxy,Method method,Object[] args) throws Exception    {        DogUtil du=new DogUtil();        du.method1();        Object result=method.invoke(target,args);        du.method2();        return result;    }}



生成代理类:

package com.company;import java.lang.reflect.Proxy;/** * Created by Tong on 2016/8/14. */public class MyProxyFactory {    public  static Object getProxy(Object target){        MyInvokationHandler handler=new MyInvokationHandler();        handler.setTarget(target);        Object ProxyObje;        ProxyObje= Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);        return ProxyObje;    }}



Dog类:

package com.company;/** * Created by Tong on 2016/8/14. */public interface Dog {    void info();    void run();}



DogUtil类:

<pre name="code" class="java">package com.company;/** * Created by Tong on 2016/8/14. */public class DogUtil {    public void method1(){        System.out.print("模拟第一个通用方法");    }    public void method2(){        System.out.print("模拟第二个通用方法");    }}



GunDog:

<pre name="code" class="java">package com.company;/** * Created by Tong on 2016/8/14. */public class GunDog implements Dog {    public void info(){        System.out.print("我是一只猎狗");    }    public void run(){        System.out.print("我奔跑迅速");    }}




运行结果:



这个列子是在原本猎狗奔跑的基础上,加了一个场景,有一天,猎狗奔跑,下雨了,看到输出的结果,调用了两次代理类,因为在最开始的Dog类


中有两个方法。




下面比较着jdk的动态代理说下cglib


1、cglib动态代理用到的是继承,而jdk的动态代理用到的接口,而且被代理的类必须有接口。

2、cglib用到的是MethodInterceptor这个接口

    1. public Object intercept(Object object, Method method, Object[] args,  
    2.    MethodProxy methodProxy)


           3、在创建类的时候,cglib用了enhancer


    1.  public Object getDaoBean(Class cls) {  
    2.   enhancer.setSuperclass(cls);  
    3.   enhancer.setCallback(this);  
    4.   return enhancer.create();  
    5.  } 


以上就是动态代理实现的基本原理。

0 0
原创粉丝点击