Spring重温(八)— — Cglib的类代理

前言:

        上一篇文章我们学习了jdk的动态代理。我们知道jdk的动态代理还是很有缺陷的。比如:jdk动态代理如果缺少接口,就不能进行了。这时,就出现了Cglib。cglib的EnHancer字节码增强器。方便为类做增强。

        spring底层在调用AOP时,会先判断这个类是否实现了接口,如果有接口就会调用jdk的动态代理,如果没有则用的是Cglib类代理。

贴代码。用代码来入门:
       第一步: 我们需要先准备要被代理的一个类,类中有相关方法。我们这里以书包拿东西和塞东西为例子,add方法只是对代表向书包里加东西。按照正常情况我们还需要检查一下书包里有没满吧?如果那样我们还需要增加一个检查方法,能不能有更好的方法,答案是用cglib来进行。
package com.test.aop;

public class Bag   {
    public void add() {
        System.out.println("往书包里塞东西");
    }
    public void delete() {
        System.out.println("往书包外取东西");
    }
}

       第二步: 我们开始准备cglib代理类,其中最重要的是getProxy()方法,方法前,我们构建了一个对象Enhancer类允许非接口型创建一个java代理。Enhancer动态创建了被代理类进行拦截的所有方法。
package com.test.aop;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author wen
 * cglib对象代理
 */
public class HandlerMethod implements MethodInterceptor {

        /*
        *  利用enhancer来创建代理类
        * */

    Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz) {
        /**
         * 将生成类作为将要扩展的类。原理不懂
         */
        enhancer.setSuperclass(clazz);
        //将当前类回调,为什么直接写个this? 因为MethodInterceptor这个接口继承自Callback接口,而Callback接口是个接口
        //我也不知道为什么这么设计。反正很牛的样子
        enhancer.setCallback(this);
        return enhancer.create();
    }


    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("开始调用method" + "可以在这里做点坏事哟");


        /**
         * 这里我们可以做一些操作,类似于AOP,前置增强
         *
         * 例如我在这里开启事务
         */

        //调用代理对象
        methodProxy.invokeSuper(o, objects);

        /**
         * 这里我们可以做一些操作,类似于AOP,后置增强
         * 完成后,没异常,可以提交事务了
         */

        System.out.println("调用结束" + "做完坏事要善后哟");

        return null;
    }
}

       第三步: 进行测试了,简单进行测试,看我们的cglib是否代理成功!
package com.test.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {


    public static void main(String[] args) {
        //多态,new一个真实的对象
        Bag bag = new Bag();
        //实例化代理类对象
        HandlerMethod handlerMethod = new HandlerMethod();
        //将被代理的类注入,被enhancer类创建代理
        Bag a = (Bag) handlerMethod.getProxy(bag.getClass());
        //调用原来的方法
        bag.add();
        System.out.println("——————完美的分割线——————");
        //调用被代理后的方法
        a.add();

    }
}
    测试结果:

        


总结:

        cglib和jdk的动态代理共同构成了spring的Aop。当然这仅仅只是核心部分,还有很多通知之类的也是很值得学习的。小编能力有限暂时先这样介绍。cglib的代理从宏观上看好像真的比jdk动态代理好很多很多,但是小编在查阅资料的时候知道,如果很大的请求量,会导致性能下降,当然,她的缺点是如果类被final标记了。那就不能动态生成代理了。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值