大话java之JDK动态代理和CGLIB动态代理

上一篇讲到了java的动态代理和JDK动态代理的使用和原理。这一篇要讲讲cglib代理,和jdk代理使用上的一个重要区别是jdk代理必须是以接口为委托类。那么在委托类不是接口的情况下,就可以使用gclib动态代理了。
gclib的实现代码如下:
1)委托类

public class TestImplement {

    @Override
    public void business() {
        try{
            System.out.println("do the busniess");
            Thread.sleep(200);
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

}

2)处理类


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 GclibLoggerInterceptor implements MethodInterceptor {

    private Object target;// 目标类

    public Object getInstance(Object target) {
        this.target = target;
         Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.target.getClass());  
        // 回调方法  
        enhancer.setCallback(this);  
        // 创建代理对象  
        return enhancer.create();  

    }

    //这是一个简单的日志处理类,会记录方法的执行时间和耗时
    @Override
    public Object intercept(Object obj, Method method, Object[] args,  
            MethodProxy proxy) throws Throwable {

        Long timeStart = System.currentTimeMillis();
        System.out.println("-- invoke start---timeStart="+timeStart);
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("-- invoke finish---takes="+(System.currentTimeMillis()-timeStart));//记录方法的调用耗时
        return result;

    }

}

3)测试代码:

        GclibLoggerInterceptor interceptor = new GclibLoggerInterceptor();
        TestImplement testImplement = (TestImplement)interceptor.getInstance(new TestImplement());
        testImplement.business();

输出结果:

– invoke start—timeStart=1504428278274
do the busniess
– invoke finish—takes=231

和jdk代理的区别,主要在于处理类的实现有些不同,委托类不限于接口。

2者的区别:

1.JDK动态代理
此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。

代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。

JDK动态代理只能针对实现了接口的类生成代理。

2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,

主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。

JDK动态代理和CGLIB代理生成的区别
JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。
因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。

动态代理的应用
AOP(Aspect-OrientedProgramming,面向切面编程),AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。

实现AOP的技术,主要分为两大类:

一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;

二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。

默认的策略是如果目标类是接口,则使用JDK动态代理技术,如果目标对象没有实现接口,则默认会采用CGLIB代理。

如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值