工作读框架的代码时常遇到cglib的东东,初看会有点摸不着头脑,打断点debug才发觉得cglib很强大。
回到家把源码下下来,呵呵,还带有sample code,下载地址见cglib sourceforge
。
下面是sample code:
1. Bean.java
package samples;
import java.beans.*;
/**
*
* @author baliuka
*/
public abstract class Bean implements java.io.Serializable{
String sampleProperty;
abstract public void addPropertyChangeListener(PropertyChangeListener listener);
abstract public void removePropertyChangeListener(PropertyChangeListener listener);
public String getSampleProperty(){
return sampleProperty;
}
public void setSampleProperty(String value){
this.sampleProperty = value;
}
public String toString(){
return "sampleProperty is " + sampleProperty;
}
}
2. Beans.java
package samples;
import java.beans.*;
import java.lang.reflect.*;
import net.sf.cglib.proxy.*;
/**
*
* @author baliuka
*/
public class Beans implements MethodInterceptor {
private PropertyChangeSupport propertySupport;
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertySupport.removePropertyChangeListener(listener);
}
public static Object newInstance( Class clazz ){
try{
Beans interceptor = new Beans();
Enhancer e = new Enhancer();
e.setSuperclass(clazz);
e.setCallback(interceptor);
Object bean = e.create();
interceptor.propertySupport = new PropertyChangeSupport( bean );
return bean;
}catch( Throwable e ){
e.printStackTrace();
throw new Error(e.getMessage());
}
}
static final Class C[] = new Class[0];
static final Object emptyArgs [] = new Object[0];
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Object retValFromSuper = null;
try {
if (!Modifier.isAbstract(method.getModifiers())) {
retValFromSuper = proxy.invokeSuper(obj, args);
}
} finally {
String name = method.getName();
if( name.equals("addPropertyChangeListener")) {
addPropertyChangeListener((PropertyChangeListener)args[0]);
}else if ( name.equals( "removePropertyChangeListener" ) ){
removePropertyChangeListener((PropertyChangeListener)args[0]);
}
if( name.startsWith("set") &&
args.length == 1 &&
method.getReturnType() == Void.TYPE ){
char propName[] = name.substring("set".length()).toCharArray();
propName[0] = Character.toLowerCase( propName[0] );
propertySupport.firePropertyChange( new String( propName ) , null , args[0]);
}
}
return retValFromSuper;
}
public static void main( String args[] ){
Bean bean = (Bean)newInstance( Bean.class );
bean.addPropertyChangeListener(
new PropertyChangeListener(){
public void propertyChange(PropertyChangeEvent evt){
System.out.println(evt);
}
}
);
bean.setSampleProperty("TEST");
}
}
javac然后java下,执行结果如下:
java.beans.PropertyChangeEvent[source=sampleProperty is TEST]
没想到能够正确跑起来呀,可是samples.Bean明明不是abstract么?呵呵。。。挺有意思,看来cglib会自己帮你实现一些方法。
使用cglib很大一点不就是希望能够对方法进行截拦么,可是目前samples.Bean是使用默认的构造器,那么就不能避免其他的同学直接new samples.Bean(),这样的话,还是达不到截拦的效果。ok,于是乎我把samples.Bean的构建器显示的声明为private,仅仅对samples.Bean.java做如下调整:
public abstract class Bean implements java.io.Serializable{
private Bean() { }
/**
* ... ...
*/
}
经过这么一调整,再次javac,发现没啥问题,接着进行javac samples.Beans,哦哦发现报错罗:
java.lang.IllegalArgumentException: No visible constructors in class samples.Bean
at net.sf.cglib.proxy.Enhancer.filterConstructors(Enhancer.java:531)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:448)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at samples.Beans.newInstance(Beans.java:33)
at samples.Beans.main(Beans.java:76)
Exception in thread "main" java.lang.Error: No visible constructors in class samples.Bean
at samples.Beans.newInstance(Beans.java:38)
at samples.Beans.main(Beans.java:76)
嘻嘻。。。看到了么,No visible constructors in class samples.Bean...
看来构建器不能声明为private呀,samples.Bean的构建器应该至少让samples.Beans可见吧。
好的,难道一定需要参数为空的默认构建器么,再修改下看看:
public abstract class Bean implements java.io.Serializable{
public Bean(Object arg) { }
/**
* ...
*/
}
这把再执行下,又出现Error罗,呵呵...
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at samples.Beans.newInstance(Beans.java:33)
at samples.Beans.main(Beans.java:76)
Exception in thread "main" java.lang.Error: Superclass has no null constructors but no arguments were given
at samples.Beans.newInstance(Beans.java:38)
at samples.Beans.main(Beans.java:76)
看来必须得给一个参数为空的默认构建器才行呀~
初次学习cglib,总结下下:
1. 对于被代理的类可以声明为abstract,cglib会帮你实现abstract方法,这个看起来很智能呀,呵呵。。。后续再看个究竟;
2. 对于被代理的类,必须要给出一个参数为空的构建器(即默认的constractor);
3. 该默认的constractor建议不要声明为private,毕竟,按照刚刚的方式来操作是会抛Error的哦;
对于第3点,把samples.Beans放在samples.Bean里面作为一个内部类,不知会是啥情况呀,呵呵。。。有点晚了,明儿再试试看~睡觉去罗
分享到:
相关推荐
标题中的"AOP-CGLIB学习-实现简单的注解权限系统"指的是使用Spring的面向切面编程(AOP)特性,结合CGLIB库来创建一个基于注解的权限控制系统。在这个系统中,通过CGLIB动态代理技术,可以对带有特定注解的方法进行...
CGLib,全称为Code Generation Library,是一个强大的Java代码生成库,广泛用于动态代理、AOP...这个“cglib.zip”压缩包提供的内容,无论是源码还是文档,都值得我们去研究和学习,以便更好地利用CGLib解决实际问题。
CGLib,全称为Code Generation Library,是一个强大的高性能的代码生成库,它在Java世界中被广泛应用,尤其...通过深入学习CGLIB的源码,开发者可以更好地掌握Java的动态代理机制,提高自己的编程技巧和问题解决能力。
9. **源码学习价值**:CGLIB的源码是一个很好的学习字节码操作和代理技术的实例。通过阅读源码,可以深入理解Java字节码的生成过程,以及AOP的实现原理。 总的来说,CGLIB 3.1源码不仅为我们提供了实现动态代理的...
CGLIB 的基本代码量虽然不多,但由于缺乏充分的文档支持,学习起来可能会有一定难度。以下列出了 CGLIB 的主要组件: - **net.sf.cglib.core:** 提供低级别的字节码操作类;大部分与 ASM 相关。 - **...
**CGLIB(Code Generation Library)** 是一个强大的高性能的代码生成库,它可以在运行期扩展Java类与实现Java接口。...通过深入学习和理解CGLIB的工作机制,开发者可以更好地利用它来解决实际问题。
CGLIB,全称为Code Generation Library,是一种代码生成库,主要用在Java应用程序中,尤其在需要进行动态代理或者运行时织...通过学习和熟练使用CGLIB,开发者可以更好地应对需要动态生成代码或增强已有类功能的挑战。
CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它可以在运行期扩展Java类与实现...在学习和测试CGLIB时,可以尝试创建自己的拦截器,观察和理解其动态生成的字节码,以加深对其工作原理的理解。
通过这些示例,你可以学习如何使用ASM和CGlib进行字节码操作,理解它们的工作原理,并将这些技术应用到实际项目中,提高代码的灵活性和可维护性。同时,掌握这两种工具也有助于深入理解Java的运行机制,提升作为Java...
Cglib是一个强大的高性能的代码生成库,它在Java运行时动态地为一个类创建子类,从而实现对这个类的功能扩展。...对于想要深入理解Java运行机制以及提升开发技能的程序员来说,学习和掌握这两个库是十分必要的。
**正文** CGlib代理,全称为Code Generation Library,是一个强大的高性能的代码生成库,它在...同时,它也是许多流行框架的底层技术支撑,学习和掌握CGlib的使用,无疑能够提高我们的技术水平和解决实际问题的能力。
CGLib,全称为Code Generation Library,是一款Java平台上的代码生成库,...通过阅读和实践CGLib相关的博客文章,如给出的链接(可能需要登录访问),我们可以深入学习其工作原理和最佳实践,提高自己的Java编程技能。
总的来说,CGLIB是一个强大的字节码操作工具,对于理解和实现Spring AOP以及深入学习Java字节码技术具有重要意义。通过阅读和分析`cglib.jar`的源码,开发者可以更深入地理解CGLIB的工作原理,从而更好地利用它来...
动态代理和CGLIB在Java开发中扮演着重要的角色,特别是在实现面向切面编程...在学习和应用这些技术时,理解其原理和使用场景至关重要。通过实践和"study",我们可以更深入地掌握这些工具的使用,提高我们的编程能力。
CGLIB和ASM是Java开发中两个非常重要的库,主要用于字节码操作和动态代理技术。在Java中,字节码操作允许开发者在运行时...在学习和使用这两个库时,需要理解Java字节码的基础知识,以及如何利用它们实现特定的需求。
这个文件包含了Cglib的源代码,开发者可以查看和学习其内部实现,有助于理解Cglib的工作原理,也可以方便地进行调试和自定义修改。 **ASM:** ASM是一个Java字节码操控和分析框架,它可以用来动态生成类或者增强已...
CgLib是一个强大的Java字节码库,它允许开发者在运行时动态地创建新的类或增强现有的类。在Java世界中,动态代理是一种常见的...因此,学习和使用CgLib不仅能提升开发效率,也能加深对面向切面编程和设计模式的理解。
1. `cglib-src-2.2.3.jar`:这个文件包含了CGLIB库的源代码,开发者可以查看源码来了解其内部工作原理,这对于学习和调试是非常有用的。 2. `cglib-docs-2.2.3.jar`:这是CGLIB的文档文件,可能包含了API文档和其他...
这个文件包含CGLIB 2.2.2的源代码,对于开发者来说非常有价值,因为可以直接查看和学习其内部实现,有助于调试和定制。通过源代码,开发者可以深入理解CGLIB的工作原理,以及如何自定义其行为。 4. **cglib-docs-...
通过阅读和分析源码,我们可以了解到字节码生成的具体步骤,学习到如何利用ASM进行字节码操作,以及如何在Java中实现高效动态代理。总的来说,CGlib是Java开发中的一个强大工具,对于理解和实现复杂的企业级功能至关...