CGLIB动态代理

CGLIB动态代理

cglib是什么?

CGLIB(Code Generation Library)是一个开源项目!java

是一个强大的,高性能,高质量的Code生成类库,它能够在运行期扩展Java类与实现Java接口。spring

CGLIB是一个强大的高性能的代码生成包。它普遍的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其余机制实现的)。EasyMock和jMock是经过使用模仿(mock)对象来测试java代码的包。它们都经过使用CGLIB来为那些没有接口的类建立模仿(mock)对象。app

CGLIIB实现动态代理

先来个service 注意没有接口框架

public class CglibService {
    public CglibService() {
        System.out.println("CglibDao 构造方法");
    }

    /** * 该方法不能被子类覆盖,Cglib是没法代理final修饰的方法的 * @param name * @return */
    final public String sayOthers(String name){
        System.out.println("CglibDao final sayOthers:"+name);
        return null;
    }

    public void sayHello(){
        System.out.println("CglibDao:sayHello");
    }
}
复制代码

新建一个Interceptor实现org.springframework.cglib.proxy.MethodInterceptoride

public class MyMethodInterceptor implements MethodInterceptor {
    /** * * @param o 代理对象 * @param method 被代理的对象方法 * @param objects 方法入参 * @param methodProxy 代理方法 * @return * @throws Throwable */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("======插入前置通知======");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("======插入后置通知======");
        return object;
    }
}

复制代码

新建测试类工具

/** * cglib 动态代理测试 */
public class cglibAgentTest {

    @Test
    public void testCglibAgent(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(CglibService.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new MyMethodInterceptor());
        // 建立代理对象
        CglibService proxy= (CglibService)enhancer.create();
        // 经过代理对象调用目标方法
        proxy.sayHello();
        proxy.sayOthers("小明");
    }
}
复制代码

打印的值性能

CglibDao 构造方法
======插入前置通知======
CglibDao:sayHello
======插入后置通知======
CglibDao final sayOthers:小明
复制代码

能够看出来 会先执行他的构造方法 当调用sayHello时候会先调用他们的代理方法 若是当方法为final修饰时 没法实现代理测试

总结

Cglib与InvocationHandler实现的动态代理不一样是 cglib不用写接口spa

Spring中的aop也能够经过配置采用Cglib方式hibernate

除了CGLIB包,脚本语言例如Groovy和BeanShell,也是使用ASM来生成java的字节码。固然不鼓励直接使用ASM,

由于它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉,因此推荐用Cglib

5d0501353921378647
相关文章
相关标签/搜索