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
先来个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