`
zhangxiaofei13
  • 浏览: 4063 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

CGLIB解析

阅读更多

cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。

cglib封装了asm,可以在运行期动态生成新的class。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

这里必须说一下ASM

 

 

ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
与 BCEL 和 SERL 不同,ASM 提供了更为现代的编程模型。对于 ASM 来说,Java class 被描述为一棵树;使用 “Visitor” 模式遍历整个二进制结构;事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而不必了解 Java 类文件格式的所有细节:ASM 框架提供了默认的 “response taker”处理这一切。
为什么要动态生成 Java 类?
动态生成 Java 类与 AOP 密切相关的。AOP 的初衷在于软件设计世界中存在这么一类代码,零散而又耦合:零散是由于一些公有的功能(诸如著名的 log 例子)分散在所有模块之中;同时改变 log 功能又会影响到所有的模块。出现这样的缺陷,很大程度上是由于传统的 面向对象编程注重以继承关系为代表的“纵向”关系,而对于拥有相同功能或者说方面 (Aspect)的模块之间的“横向”关系不能很好地表达。例如,目前有一个既有的银行管理系统,包括 Bank、Customer、Account、Invoice 等对象,现在要加入一个安全检查模块, 对已有类的所有操作之前都必须进行一次安全检查。

ASM 能够通过改造既有类,直接生成需要的代码。增强的代码是硬编码在新生成的类文件内部的,没有反射带来性能上的付出。同时,ASM 与 Proxy 编程不同,不需要为增强代码而新定义一个接口,生成的代码可以覆盖原来的类,或者是原始类的子类。它是一个普通的 Java 类而不是 proxy 类,甚至可以在应用程序的类框架中拥有自己的位置,派生自己的子类。
相比于其他流行的 Java 字节码操纵工具,ASM 更小更快。ASM 具有类似于 BCEL 或者 SERP 的功能,而只有 33k 大小,而后者分别有 350k 和 150k。同时,同样类转换的负载,如果 ASM 是 60% 的话,BCEL 需要 700%,而 SERP 需要 1100% 或者更多。
ASM 已经被广泛应用于一系列 Java 项目:AspectWerkz、AspectJ、BEA WebLogic、IBM AUS、OracleBerkleyDB、Oracle TopLink、Terracotta、RIFE、EclipseME、Proactive、Speedo、Fractal、EasyBeans、BeanShell、Groovy、Jamaica、CGLIB、dynaop、Cobertura、JDBCPersistence、JiP、SonarJ、Substance L&F、Retrotranslator 等。Hibernate 和 Spring 也通过 cglib,另一个更高层一些的自动代码生成工具使用了 ASM。

 

 下面看一个简单的例子,具体的体会一下CGLIB的实现方式:

   Option操作类含义基本的操作类型增删改查 

package cglib;

import java.io.Serializable;

/**
 * 操作集合实现类
 * @author zhangjuwei
 *
 */
public class Option implements Serializable {

	public  void  add(){
		System.out.println(" add opt");
	}
	
	public  void  update(){
		System.out.println(" update opt");
	}
	
	public  void  query(){
		System.out.println(" query opt");
	}
	
	public  void  del(){
		System.out.println(" del opt");
	}
	
	
}

 

 操作工厂类,单例的获取操作对象
package cglib;

import net.sf.cglib.proxy.Enhancer;

/**
* 操作工厂类
* @author zhangjuwei
*
*/
public class OptionFactory {

private static Option option = new Option();

public static Option getInstance() {
return option;
}

}

 

  这时 基本上可以满足常见的需求了。即调用操作类中的四个方法。

详见 Client 的 7 8 行。 

 

但如果要实现比较复杂的需求如:某些方法某些人的访问权限的限制。

看下面的代码:OptionFactory4Auth 

   

package cglib;

import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;

/**
 * 操作工厂类
 * @author zhangjuwei
 *
 */
public class OptionFactory4Auth {

	 public static Option getAuthInstance(AuthOptProxy auth) {
		 	System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C://temp");  //这里将生成的class文件输出至指定的文件夹下,方便查看。
	        Enhancer enhancer = new Enhancer();  //底层是ASM
	        enhancer.setSuperclass(Option.class);
//	        enhancer.setCallback(auth);
	        
	        enhancer.setCallbacks(new Callback[] { auth, NoOp.INSTANCE });
	        enhancer.setCallbackFilter(new AuthProxyFilter());    
	        return (Option) enhancer.create();
	        
	        
	    }
	
}

 

 

package cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.CallbackFilter;

public class AuthProxyFilter implements CallbackFilter {

	private static final int AUTH_NEED = 0;
	private static final int AUTH_NOT_NEED = 1;

	@Override
	public int accept(Method method) {
		if ("query".equals(method.getName())) {
			return AUTH_NOT_NEED;
		}
		return AUTH_NEED;
	}

}

 

package cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 用户权限校验类
 * @author zhangjuwei
 *
 */
public class AuthOptProxy implements MethodInterceptor{

	private String name;
	
	public AuthOptProxy(String name) {
		super();
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
	 
		 if (!"maurice".equals(this.name)) {
	            System.out.println("AuthProxy:you have no permits to do manager!");
	            return null;
	        }
	        return proxy.invokeSuper(obj, args);
	}
	
}

 

package cglib;


public class Client {

	public static void main(String[] args) {
		Client c = new Client();
		// c.optManage();
		c.haveNoAuthManager();
		c.haveAuthManager();
	}

	/**
	 * 模拟:登录会员没有权限
	 * 
	 */
	public void haveNoAuthManager() {
		System.out.println("the loginer's name is not maurice,so have no permits do manager");
		Option noAuthManager = OptionFactory4Auth.getAuthInstance(new AuthOptProxy("maurice1"));
		doCRUD(noAuthManager);
	}

	/**
	 * 模拟:登录会员有权限
	 */
	public void haveAuthManager() {
		System.out
				.println("the loginer's name is  maurice,so have  permits do manager");
		Option noAuthManager = OptionFactory4Auth
				.getAuthInstance(new AuthOptProxy("maurice"));
		doCRUD(noAuthManager);
	}

	public void optManage() {
		System.out.println("any one can do manager");
		Option option = OptionFactory.getInstance();
		doCRUD(option);
	}

	public void doCRUD(Option opt) {
		opt.add();
		opt.update();
		opt.del();
		opt.query();
	}

}

 cglib在代码运行期,动态生成了Option的子类,并且根据CallbackFilter的accept方法,覆写了Option中的所有方法--去执行相应的MethodInterceptor的intercept方法。

分享到:
评论

相关推荐

    cglib.jar以及cglib-src.jar

    这种方法比使用Java反射性能更高,因为反射在运行时解析类和方法会带来一定的开销。 在"cglib-src-2.2.jar"中,包含了CGLIB的源代码,开发者可以深入研究其内部实现,这对于理解其工作原理和进行定制化开发非常有...

    cglib必需的包

    在CGlib中,ASM主要用于生成和解析Java字节码,构建新的类或修改现有类的方法,从而实现动态代理和AOP的底层支持。 `asm-commons-2.2.3.jar`是ASM的公共模块,包含了一些用于处理类、方法和注解的工具类。这些工具...

    Cglib的jar文件 Cglib.zip

    ASM-commons和ASM-tree分别是ASM的辅助模块,它们提供了更高级别的API,简化了对字节码的操作和解析。具体来说,ASM-commons包含了一些实用工具类,而ASM-tree则将字节码转换为抽象语法树(AST),便于进行更复杂的...

    cglib代理模式要使用的相关jar包

    4. asm-tree.jar:这个库包含了一些解析和操作ASM字节码的树结构的类,对于理解及操作字节码非常有帮助。 使用CGLIB的基本步骤如下: 1. 引入必要的依赖库:确保项目中已经包含了上述提到的四个jar包。 2. 创建...

    cglib-3.3.0.jar,asm-7.0.jar

    CGLIB之所以依赖ASM,是因为CGLIB在生成代理类的字节码时,需要ASM提供的低级别API来解析和操作Java字节码。ASM的高效性能和灵活性使得CGLIB能够轻松地生成和优化代理类。 总结来说,"cglib-3.3.0.jar"和"asm-7.0....

    转载:cglib动态代理介绍(一)

    CGlib是Java编程语言中的一个库,主要用于创建子类,也称为子类代理或动态代理。这个库在很多场合被广泛使用,特别是在那些需要在运行时动态创建对象或增强已有对象功能的场景下,比如Spring AOP(面向切面编程)...

    CGLIB入门实例.doc

    这种代理方式比Java的内置反射机制更高效,因为它在运行时生成字节码,而不是在运行时解析类。CGLIB通过`Enhancer`类来实现动态代理,`Enhancer`允许我们设置一个回调对象,这个回调对象通常是实现了`...

    CGLib代理jar包

    而`asm.jar`则是ASM库,它是CGLib依赖的基础字节码操作库,用于生成和解析Java字节码,实现对类的动态增强。 使用CGLib代理的基本步骤如下: 1. 引入依赖:首先,你需要将这两个jar包引入到你的项目中,无论是...

    cglib.jar和cglib代理必备的asm所有jar

    Cglib的核心是ASM库,ASM是一个Java字节码操控和分析框架,它可以直接生成和解析Java类的字节码。ASM提供了一种方式,让我们可以在运行时动态创建类或者增强已有类的功能,这对于很多框架和库来说是必不可少的工具。...

    cglib动态代理用到的两个包

    CGLib通过ASM解析类的字节码,然后在原有字节码的基础上插入新的字节码以实现动态增强。ASM的使用使得CGLib能够在运行时高效地创建和修改类,而无需重新编译源代码。 CGLib动态代理的使用步骤通常包括以下几点: - ...

    java cglib和反射demo

    在这个ProxyDemo中,`CglibProxy`和`ReflectionProxy`都实现了对目标方法调用的拦截,但CGLib在性能上通常优于反射,因为它创建的是子类对象,而反射则需要在运行时解析类信息。然而,反射提供了更大的灵活性,可以...

    cglib和asm jar包

    ASM的使用则更为灵活,因为其提供了一套完整的字节码生成和解析的API,开发者可以精确地控制字节码的生成过程。然而,这也意味着使用ASM需要更多的编码工作,适合对字节码有深入理解的开发者。 总的来说,CGLIB和...

    Cglib和asm的jar包

    2. **代码分析**:ASM可以解析类的字节码,帮助理解类的结构和行为,这对于调试、测试和性能分析非常有用。 3. **字节码优化**:通过ASM,开发者可以对字节码进行优化,例如去除无用代码、减少指令冗余等。 4. **...

    Cglib动态代理需要用到的jar包

    ASM提供了一种方式来解析和生成Java类的字节码,这对于Cglib在运行时创建子类至关重要。在提供的文件列表中,`cglib-3.2.5.jar`是Cglib的主要库,而`asm-5.2.jar`则是ASM的版本,这两个jar包组合在一起,使得Cglib...

    java_cglib_lib.rar

    4. **asm-tree.jar**:ASM Tree API提供了将字节码解析为抽象语法树(AST)的工具,使得开发者可以更方便地遍历和修改类结构。CGlib在生成子类或处理方法时会用到这个库。 CGlib的使用步骤通常包括以下几个部分: ...

    cglib代理的依赖jar包

    **ASM库解析** 1. **功能概述** ASM是一个Java字节码操纵和分析框架,它可以直接生成和加载Java类。ASM提供了低级别的API,可以精确地控制类或接口的生成,使得开发者能够构建自己的编译器、反编译器或者代码分析...

    Cglib&ASM;打包合集

    ASM是另一个强大的字节码操纵和分析框架,它可以直接生成和解析Java字节码。ASM提供了对Java类文件和字节码的低级别访问,允许开发者精确地控制类和方法的创建。ASM的灵活性使得它不仅可用于代码生成,还可以用于...

    cglib.jar和asm.jar

    ASM可以直接生成和解析.class文件,这使得开发者可以深入到JVM的内部工作原理中去。ASM的灵活性和效率使其在许多场合下成为首选的字节码处理工具,包括代码分析、性能优化、动态语言实现等。 代理模式是一种设计...

    CGlib动态代理类的jar包

    3. `asm-2.2.3.jar`:这是ASM的核心库,包含了用于生成和解析Java字节码的类和接口。 4. `asm-commons-2.2.3.jar`:ASM的通用模块,提供了一些通用的字节码处理工具和API,比如注解处理器和类适应器。 使用CGlib...

Global site tag (gtag.js) - Google Analytics