CGLib实现动态代理

一、概述

        上一节介绍了JDK动态代理,下面说一下使用CGLib实现动态代理。Cglib是一个强大的,高性能的Code生成类库,它可以在运行期间扩展Java类和实现Java接口,它封装了Asm,所以使用Cglib前需要引入Asm的jar。

      JDK实现动态代理需要实现类通过接口定义业务方法,被代理的类必须实现接口;使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率更高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑,由于是继承,因此使用CGLIB代理的类不能是final类。

二、代码实现

下面是CGLib实现动态代理的代码实现:

被代理类:

package static_proxy_package;

/**
 * 委托类,真正要送礼物的人,实现了接口
 * @author lsh
 *
 */
public class RealSubject  {

          public void giveGift(String name) {
		
          System.out.println(name + "送给了您一份礼物");
    }
}

CGLib动态代理:

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibDynamicProxy implements MethodInterceptor { 

    public static CGLibDynamicProxy instance= new CGLibDynamicProxy();
 
    public CGLibDynamicProxy(){ }
 
    public static CGLibDynamicProxy getInstance(){
            return instance;
    }
 
   //创建代理类
  @SuppressWarnings("unchecked")
  public <T>T getProxy(Class<T> cls){
        return (T)Enhancer.create(cls,this);
  }
 
   @Override
   public Object intercept(Object target,Method method, Object[] args,MethodProxy proxy)throws Throwable{
         Object sub= null;  
         System.out.println("送礼物之前");  
         Object result =proxy.invokeSuper(target,args);
         System.out.println("送礼物之后");
         return result;
   } 

}

客户端:

public class Client {	
   public static void mian(String[] args){
	RealSubject realSubject=CGLibDynamicProxy.getInstance().getProxy(RealSubject.class);
	realSubject.giveGift("huazi");
   }
}

三、浅析:

1、 CGLib实现动态代理的过程:

    (1)   Enhancer现将被代理类设置成父类,然后设置拦截器类,最后执行性enhancer.create()动态生成一个代理类;

    (2)   回调MethodInterceptor接口的拦截方法intercept来实现代理逻辑,其中调用代理类实例上的proxy方法的父类方法proxy.invokeSuper(obj,arg).

2、解析intercept(Object obj, Method method,Object[] args,MethodProxy proxy)的参数:

   (1)   Object为由CGLib动态生成的代理类的实例;

   (2)   Method为调用被代理方法的引用

   (3)   Object[]为被调用代理方法的参数列表

   (4)   MethodProxy为生成的代理类对方法的代理引用。

四、区别:

 

 注:红色字代表CGLib动态代理,黑色字代表JDK动态代理

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值