CGlib概述:
cglib(Code Generation
Library
)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
cglib封装了asm,可以在运行期动态生成新的class。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。
一个好的例子:
http://www.blogjava.net/stone2083/archive/2008/03/16/186615.html
一、JDK的动态代理类
-
public
interface
IService {
-
boolean
getService(String data);
-
}
public interface IService {
boolean getService(String data);
}
-
public
class
ServiceImpl
implements
IService {
-
-
public
boolean
getService(String data) {
-
if
(
"A"
.equals(data)) {
-
return
true
;
-
} else
{
-
return
false
;
-
}
-
}
-
-
}
public class ServiceImpl implements IService {
public boolean getService(String data) {
if ("A".equals(data)) {
return true;
} else {
return false;
}
}
}
-
import
java.lang.reflect.InvocationHandler;
-
import
java.lang.reflect.Method;
-
-
public
class
ServiceHandler
implements
InvocationHandler {
-
private
Object delegateObj;
-
-
public
ServiceHandler(Object delegateObj) {
-
this
.delegateObj = delegateObj;
-
}
-
-
public
Object invoke(Object proxy, Method method, Object[] args)
-
throws
Throwable {
-
System.out.println("Begin Transaction...."
);
-
boolean
rtn = (Boolean) method.invoke(delegateObj, args);
-
System.out.println("End Transaction...."
);
-
return
rtn;
-
}
-
-
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ServiceHandler implements InvocationHandler {
private Object delegateObj;
public ServiceHandler(Object delegateObj) {
this.delegateObj = delegateObj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Begin Transaction....");
boolean rtn = (Boolean) method.invoke(delegateObj, args);
System.out.println("End Transaction....");
return rtn;
}
}
-
import
java.lang.reflect.Proxy;
-
-
public
class
Test {
-
public
static
void
main(String args[]) {
-
ServiceImpl si = new
ServiceImpl();
-
-
ServiceHandler sh = new
ServiceHandler(si);
-
-
IService is = (IService) Proxy.newProxyInstance(si.getClass()
-
.getClassLoader(), si.getClass().getInterfaces(), sh);
-
-
is.getService("A"
);
-
}
-
}
import java.lang.reflect.Proxy;
public class Test {
public static void main(String args[]) {
ServiceImpl si = new ServiceImpl();
ServiceHandler sh = new ServiceHandler(si);
IService is = (IService) Proxy.newProxyInstance(si.getClass()
.getClassLoader(), si.getClass().getInterfaces(), sh);
is.getService("A");
}
}
二、CGLIB的动态代理类
Figure 1: CGLIB Library and
ASM Bytecode Framework
图一显示了和
CGLIB包和一些框架和语言的关系图。需要注意的是一些框架例如Spring
AOP和Hibernate,它们为了满足需要经常同时使用JDK的动态代理和CGLIB包。Hiberater使用JDK的动态代理实现一个专门为
WebShere应用服务器的事务管理适配器;Spring AOP,如果不强制使用CGLIB包,默认情况是使用JDK的动态代理来代理接口。
-
public
class
Target {
-
-
public
String execute() {
-
String message = "----------test()----------"
;
-
System.out.println(message);
-
return
message;
-
}
-
}
public class Target {
public String execute() {
String message = "----------test()----------";
System.out.println(message);
return message;
}
}
-
import
net.sf.cglib.proxy.MethodInterceptor;
-
import
net.sf.cglib.proxy.MethodProxy;
-
import
java.lang.reflect.Method;
-
-
public
class
MyMethodInterceptor
implements
MethodInterceptor {
-
-
public
Object intercept(Object object, Method method, Object[] args,
-
MethodProxy methodProxy) throws
Throwable {
-
System.out.println(">>>MethodInterceptor start..."
);
-
Object result = methodProxy.invokeSuper(object, args);
-
System.out.println(">>>MethodInterceptor ending..."
);
-
return
"hahahh"
;
-
}
-
}
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyMethodInterceptor implements MethodInterceptor {
public Object intercept(Object object, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
System.out.println(">>>MethodInterceptor start...");
Object result = methodProxy.invokeSuper(object, args);
System.out.println(">>>MethodInterceptor ending...");
return "hahahh";
}
}
-
import
net.sf.cglib.proxy.Enhancer;
-
-
public
class
TestCglibProxy {
-
public
static
void
main(String rags[]) {
-
Target target = new
Target();
-
TestCglibProxy test = new
TestCglibProxy();
-
Target proxyTarget = (Target) test.createProxy(Target.class
);
-
String res = proxyTarget.execute();
-
System.out.println(res);
-
}
-
-
public
Object createProxy(Class targetClass) {
-
Enhancer enhancer = new
Enhancer();
-
enhancer.setSuperclass(targetClass);
-
enhancer.setCallback(new
MyMethodInterceptor());
-
return
enhancer.create();
-
}
-
}
import net.sf.cglib.proxy.Enhancer;
public class TestCglibProxy {
public static void main(String rags[]) {
Target target = new Target();
TestCglibProxy test = new TestCglibProxy();
Target proxyTarget = (Target) test.createProxy(Target.class);
String res = proxyTarget.execute();
System.out.println(res);
}
public Object createProxy(Class targetClass) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
enhancer.setCallback(new MyMethodInterceptor());
return enhancer.create();
}
}
CGLIB包的基本代码很少,当学起来有一定的困难,主要是缺少文
档,这也是开源软件的一个不足之处。目前CGLIB的版本是(2.1.2),主要由一下部分组成:
net.sf.cglib.core
Low-level
bytecode manipulation classes; Most of them are related to ASM.
net.sf.cglib.transform
Classes
for class file transformations at runtime or build time
net.sf.cglib.proxy
Classes
for proxy creation and method interceptions
net.sf.cglib.reflect
Classes
for a faster reflection and C#-style delegates
net.sf.cglib.util
Collection
sorting utilities
net.sf.cglib.beans
JavaBean
related utilities
大多时候,仅仅为了动态地创建代理,你仅
需要使用到代理包中很少的一些API。
正如我们先前所讨论的,CGLIB包是在ASM之上的一个高级别的层。对代理那些没有实现接口的类
非常有用。本质上,它是通过动态的生成一个子类去覆盖所要代理类的不是final的方法,并设置好callback,则原有类的每个方法调用就会转变成调
用用户定义的拦截方法(interceptors),这比JDK动态代理方法快多了。
net.sf.cglib.proxy.MethodInterceptor
能够满足任何的拦截(interception
)需要,当对有些情况下可能过度。为了简化和提高性能,CGLIB包提供了一些专门的回调(callback)类型。例如:
net.sf.cglib.proxy.FixedValue
为
提高性能,FixedValue回调对强制某一特别方法返回固定值是有用的。
net.sf.cglib.proxy.NoOp
NoOp回
调把对方法调用直接委派到这个方法在父类中的实现。
net.sf.cglib.proxy.LazyLoader
当
实际的对象需要延迟装载时,可以使用LazyLoader回调。一旦实际对象被装载,它将被每一个调用代理对象的方法使用。
net.sf.cglib.proxy.Dispatcher
Dispathcer
回调和LazyLoader回调有相同的特点,不同的是,当代理方法
被调用时,装载对象的方法也总要被调用。
net.sf.cglib.proxy.ProxyRefDispatcher
ProxyRefDispatcher回调和
Dispatcher一样,不同的是,它可以把代理对象作为装载对象方法的一个参数传递。
代理类的所以方法经常会用到回调(callback),当是你
也可以使用net.sf.cglib.proxy.CallbackFilter
有选择的对一些方法使用回调(callback),这种考虑周详的控制特性在JDK的动态代理中是没有的。在JDK代理中,对
java.lang.reflect.InvocationHandler方法的调用对代理类的所以方法都有效。
Use a MethodInterceptor
为了更好的使用代理,我们可以使用自己定义的
MethodInterceptor
类型回调(
callback
)来代替
net.sf.cglib.proxy.NoOp
回调。当对代理中所有方法的调用时,都会转向
MethodInterceptor
类型的拦截(
intercept
)方法
,
在
拦截方法中再调用底层对象相应的方法。
Use a
CallbackFilter
小结 GLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。
它底层使用字节码处理框架ASM。其原理是,生产一个要代理类的子类,子类覆盖要代理的类的所有不是final的方法。
它比使用java反射的JDK动态代理要快。通常情况下,你可以使用JDK的动态代理创建代理,当你要代理的类没有实现接口
或者为了更好的性能,CGLIB是一个好的选择。
分享到:
相关推荐
CGLIB介绍与原理(部分节选自网络) 一、什么是CGLIB? CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要...
CGlib是Java开发中一个非常重要的库,它是一个强大的、高性能的代码生成库,主要用于创建子类,从而实现动态代理。在Java中,动态代理通常用于AOP(面向切面编程)或者为已有接口提供额外的功能,如日志、事务管理等...
本文将重点介绍使用CGLIB库实现的动态代理。 CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它在许多AOP(面向切面编程)框架中被广泛应用,如Spring AOP。CGLIB通过字节码技术生成代理类,...
CGlib是Java编程语言中的一个库,主要用于创建子类,也称为子类代理或动态代理。这个库在很多场合被广泛使用,特别是在那些需要在运行时动态创建对象或增强已有对象功能的场景下,比如Spring AOP(面向切面编程)...
1. **原理介绍** CGlib代理机制主要是通过动态创建一个目标类的子类,并重写其方法来实现代理。当调用代理对象的方法时,实际上是调用了子类的方法,从而可以在不修改原有代码的情况下对目标类的方法进行增强。 2....
《深入理解Hibernate-CGLIB-2.1_3在Java开发中的应用》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而CGLIB则是一个代码生成库,它允许开发者在运行时动态创建子类...
code generation library
**AOP(面向切面编程)** 面向切面编程(Aspect Oriented...以上就是关于"AOP、CGLIB"的知识点介绍,Spring框架中的AOP和CGLIB结合使用,为Java开发者提供了强大的代码组织和管理工具,让软件开发变得更加高效和灵活。
接下来将详细介绍三种常用的Java代理技术:JDK代理、CGLIB代理以及AspectJ代理,并对比它们各自的优缺点。 #### 二、静态代理实例 静态代理可以通过下面的例子进行说明: ```java public interface Calculator { ...
本文将详细介绍这两个jar包以及它们与Spring框架的关系。 首先,"spring-cglib-repack-3.1.jar"是一个针对CGLIB(Code Generation Library)的打包版本,用于在运行时动态创建Java类的子类。CGLIB是一个强大的代码...
本文将详细介绍这两个库以及它们在Spring框架中的作用。 **CGlib(Code Generation Library)** CGlib是一个强大的、高性能的代码生成库,主要用于在运行期扩展Java类与实现Java接口。在Spring框架中,CGlib主要被...
5. **API介绍**: - `Enhancer`:这是CGLIB的核心类,用于创建代理对象。通过设置`setSuperclass`指定要增强的类,`setCallback`指定回调函数,然后调用`create`方法即可生成代理对象。 - `MethodInterceptor`:这...
下面将详细介绍这些关键组件及其在SpringMVC 3.0中的作用。 1. **SpringMVC**:Spring MVC是Spring框架的一个模块,用于构建基于模型-视图-控制器(MVC)架构的Web应用。它提供了一个灵活的处理模型,允许开发者将...
下面将详细介绍CGLib的相关知识点。 1. **动态代理**: CGLib常用于为Java对象创建代理,以在方法调用前后添加额外的行为。比如,在Spring AOP框架中,CGLib被用来创建代理对象,实现在方法执行前后的拦截器逻辑,...
下面将详细介绍CGlib动态代理的工作原理、使用方法以及相关知识点。 **1. 动态代理概念** 动态代理是一种在运行时创建代理对象的技术,它可以让我们在不修改原有代码的基础上,为已有对象添加额外的功能。Java中的...
- CGLIB库的介绍和使用场景 - ASM库的作用和工作原理 - Enhancer类的配置与使用 - MethodInterceptor接口和intercept()方法的实现 - CGLIB代理对象的创建和调用过程 - 对比CGLIB和Java动态代理的优缺点 - 实战示例,...
以上就是关于静态代理、动态代理(JDK)和CGlib代理的基本介绍。它们在Java开发中都有广泛的应用,尤其是在AOP(面向切面编程)和框架设计中,如Spring AOP就使用了这两种代理技术。了解并熟练掌握这些代理机制,...
本文主要介绍 Java 中两种常见的动态代理方式:JDK 原生动态代理和 CGLIB 动态代理。 一、 代理模式 代理模式是指程序通过代理类来访问目标对象,以达到对目标对象的控制和增强。代理模式的优点是可以在不改变目标...