动态代理不通过接口,CGLIB动态代理

Java的jdk为我们实现动态代理提供了invocationHandler接口,被代理的类必须实现相同的接口。但是很多时候我们拿到的类并没有这样的接口。那么这个时候要实现动态代理就要用到另外一种机制。那就是通过CGLIB来实现动态代理。下面就来看一个最简单的小例子。

首先,简单介绍一下CGLIB实现动态代理的原理。CGLIB通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用。由于是创建的子类,所以就免去了接口的实现,但是这样做也有一些缺陷,对于final修饰的方法无法进行代理。

因为我们要使用CGLIB所以必须先导入相应的包。在这里需要导入cglib.jar以及asm.jar两个包。这两个包随便在网上都能下载。至于怎样导入百度一下有教程,选中工程右键–>Build Path–>Add External Archivels。(注意:以上两个包一定要配套,否则有可能工程会无法正常运行)

下面就正式开始我们的代码编写了。首先我们写一个类,实现一个方法(这里就不再有接口了),在这个方法里面打印一些文字。

public class Helllo {
    public void fun()
    {
        System.out.println("In Hello doing fun()...");
    }

}

然后,实现代理类。CGLIB为我们提供了MethodInterceptor接口。创建CGLIBProxy类实现上面的接口,重写intercept()方法,在这里面对调用方法进行拦截。在这个类里还需要创建一个方法用来返回被代理类子类对象。在这里我创建了creatObject()方法

public class CGLIBProxy implements MethodInterceptor{

    private Object obj;

    public Object createObject(Object target)
    {
        this.obj = target;
        //加载需要创建子类的类
        Enhancer hancer = new Enhancer();
        hancer.setSuperclass(this.obj.getClass());//设置代理目标
        hancer.setCallback(this);//设置回调
        hancer.setClassLoader(target.getClass().getClassLoader());
        return hancer.create();//返回子类对象
    }

    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2,
            MethodProxy arg3) throws Throwable {
        Object result = null;
        System.out.println("Before....");//调用方法前
        result = arg3.invokeSuper(arg0, arg2);
        System.out.println("After....");//调用方法后


        return result;
    }

}

最后,创建一个测试类。

public class CGLIBMain {
    public static void main(String[] args)
    {
        HelloWord hello = new HelloWord();
        CGLIBProxy proxy = new CGLIBProxy();
        HelloWord helloword = (HelloWord) proxy.createObject(hello);
        helloword.sayHello();
    }

}

输出结果:

Before...
In Hello doing fun()...
After...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值