cglib简介

cglib是啥?

首先上一段官方介绍

Byte Code Generation Library is high level API to generate and transform Java byte code. It is used by AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access.

简单一点说cglib是一个字节码的操作库,能够动态的更改Java的class文件

那它能干什么呢,其实能干的事情又很多,随处可见的AOP(Aspect Oriented Programming)就用到了cglib来进行方法拦截,还有我们用的自动化测试框架EasyMock和jMock,也用它进行来进行代理,包括一些DAO层框架(Hibernate)也用到了他,所以我们的JAVA EE项目基本上大量的使用了它

简单使用

先写一个目标类,是我们需要代理的对象

public class HelloWorld  {
    public void say(){
        System.out.println("hello world");
    }
}

然后写一个代理类,是我们对目标类的代理,进行方法的拦截,在目标类invoke的前后,干一些额外的工作

public class Proxy implements MethodInterceptor {

	public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

		System.out.println("do something before invoke, like log...");

		methodProxy.invokeSuper(object, args);

		System.out.println("do something after invoke, like log...");

		return null;
	}
}

最后写一个测试类,对我们的实现进行调用

    public static void main(String[] args) {

        Enhancer enhancer = new Enhancer();

        //代理类需要继承目标类,(使用的是extend实现代理)
        enhancer.setSuperclass(HelloWorld.class);

        //加强类设置代理类,当拦截到目标类的方法调用,用这个代理的intercept方法对原方法加强
        enhancer.setCallback(new Proxy());

        //创建代理对象(这里的helloWorld才叫做代理对象)
        HelloWorld helloWorld = (HelloWorld) enhancer.create();

        helloWorld.say();

    }

最后看一下输出

do something before invoke, like log...
hello world
do something after invoke, like log...

源码参见附录1

总结

可以看到,我们的代理对象是没有接口的,这个是cglib相对于原生的jdk动态代理的区别,原生的动态代理只能进行有接口的类代理

同时我们看到enhancer的setSuperclass方法,是通过继承的方式,进行代理的,所以我们无法代理一个final的类或者方法。

  1. 本文源码链接 



Published

25 March 2017

Tags