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

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.  } 


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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值