- 浏览: 496816 次
- 性别:
- 来自: OnePiece
文章分类
- 全部博客 (196)
- --------- 基础----------- (0)
- java 碎碎念 (12)
- java 并行编程 (11)
- java I/O (6)
- java Charset & Encoding (2)
- spring学习笔记 (8)
- 正则表达式 (5)
- web前端-javascript (11)
- web前端-jQuery (7)
- web前端-碎碎念 (1)
- mybatis (0)
- 数据库-通用 (8)
- 数据库-oracle (20)
- nosql-redis (11)
- nosql-mongoDB (1)
- xml (2)
- log4j (2)
- uml (3)
- web services: soap/wsdl (6)
- soa-tuscany (2)
- linux (6)
- ----------修养----------- (0)
- 深入理解java虚拟机 (7)
- java 设计模式 (9)
- 数据结构和算法 (2)
- 读书笔记--代码整洁之道 (2)
- 计算机基础 (1)
- -----------践行---------- (0)
- 重构(refactor) (7)
- jvm-诊断 (4)
- 数据库-让oracle跑得更快 (7)
- Nginx (6)
- ehcache (2)
- 短信开发 (1)
- Servlet+Filter+Listener (2)
- 运维 (6)
- 问题记录 (38)
- 杂七杂八 (12)
最新评论
-
zhanggang807:
第二种方法比较好
<spring> 定时任务每次都执行两次的问题,慎用new ClassPathXmlApplicationContext() -
assasszt:
谢谢分享,很清楚的讲明了原理。
字符集与字符编码简介 -
su0nils000:
难得的笔记
<进阶-2> 打造高效正则表达式 -
足至迹留:
mini188 写道用MD5来解决碰撞是不是也是可行的呢?个人 ...
Hash简介 -
mini188:
用MD5来解决碰撞是不是也是可行的呢?
Hash简介
1. 问题描述
使用cglib库进行动态生成代理类时调用了默认改造方法,enhancer.create(),为了省事,把目标类写成了内部类,导致错误:
源码:
2. 问题分析
报错显示创建的时候没有给构造方法参数,明显看上去Student1使用的是默认构造方法,不需要参数啊。为了看究竟,查看Student1的反射方法,构造方法果然有一个参数,类型是CglibTest... 原来是通过构造方法外部类被传入了内部类,这也是为什么内部类可以直接调用外部类的成员了。
详细参考:
http://www.2cto.com/kf/201402/281879.html
要点:
1 编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象的引用;
2 编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为1中添加的成员变量赋值;
3 在调用内部类的构造函数初始化内部类对象时, 会默认传入外部类的引用。
3. 问题解决
三种方法:
1. 把Student1定义成static 内部类
2. 把Student1拿到外面单独定义
3. cglib创建时传入外部类对象:
enhancer.create(new Class[]{CglibTest.class}, new Object[]{this});
使用cglib库进行动态生成代理类时调用了默认改造方法,enhancer.create(),为了省事,把目标类写成了内部类,导致错误:
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)
源码:
public class CglibTest { @Test public void createTest() { Student1 defaultProxy = (Student1)this.createCglibProxy(Student1.class); defaultProxy.print(); } private Object createCglibProxy(Class targetClass) { // 也可以使用Enhancer的静态create方法,不需要new 实例。但这样能更好的控制实例配置。 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetClass); enhancer.setCallback(NoOp.INSTANCE); return enhancer.create(); } public class Student1 { private int age; private String name; public int getAge() { return this.age; } public String getName() { return this.name; } public void print() { System.out.println("age:" + age + ", name:" + name); } } }
2. 问题分析
报错显示创建的时候没有给构造方法参数,明显看上去Student1使用的是默认构造方法,不需要参数啊。为了看究竟,查看Student1的反射方法,构造方法果然有一个参数,类型是CglibTest... 原来是通过构造方法外部类被传入了内部类,这也是为什么内部类可以直接调用外部类的成员了。
详细参考:
http://www.2cto.com/kf/201402/281879.html
要点:
1 编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象的引用;
2 编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为1中添加的成员变量赋值;
3 在调用内部类的构造函数初始化内部类对象时, 会默认传入外部类的引用。
3. 问题解决
三种方法:
1. 把Student1定义成static 内部类
2. 把Student1拿到外面单独定义
3. cglib创建时传入外部类对象:
enhancer.create(new Class[]{CglibTest.class}, new Object[]{this});
发表评论
-
修改第三方源码并重新打包
2017-02-14 17:05 29601.场景 很多时候需要下载第三方源码修改并重新编译打包,比如m ... -
super用在了匿名内部类里
2016-07-06 09:47 12901.问题描述 本来是重构时在父类里增加了一个protected ... -
<spring-expected at least 1 matching bean> 缺少bean定义
2016-03-04 10:37 14551. 问题描述 ... Error creating bean ... -
《IDEA 循环依赖》Annotation processing is not supported for module cycles.
2015-11-04 16:30 371761. 错误现象 Error:java: Annotation ... -
数据库小问题集合
2015-09-23 14:58 6971. mysql默认查询时,不区分字母大小写。 比如:sele ... -
slf4j 的MDC (附带主动获取方法堆栈)
2015-08-03 17:29 54021. 主动获取方法调用链 ... -
<spring-aop> BeanNotOfRequiredTypeException 切面异常
2015-07-24 17:59 67251. 问题描述 往工程里添加切面,定义了<aop:asp ... -
<Spring-Aspect> 切面类(@Aspect)首先必须是bean
2015-07-20 14:08 37331. 问题描述 今天发现老工程里有个日志切面但是总是也没有执行 ... -
<tomcat> 启动报错 Error listenerStart
2015-07-10 09:32 3417今天同事遇到一个tomcat启动失败的问题,日志信息很少,不知 ... -
Intellij IDEA--can't use subversion command line client : svn
2015-06-04 10:45 172501. 错误描述 初用IDEA,暂时感到的还是不适应。导入工程报 ... -
<myeclipse> 修改Source Folder
2015-04-27 16:25 1675MyEclipse工程里新增文件夹时有普通Folder和Sou ... -
<maven> 新工程打包遇到Access restriction
2015-04-27 16:17 11861、错误描述 Access restriction: The ... -
<线程池-定时任务> ScheduledExecutorService之shutdown引发的RejectedExecutionException问题
2015-03-20 21:32 5567一、 问题描述 先来看一下异常信息,启动tomcat时就报错: ... -
<windows, tomcat> tomcat安装为windows服务,查看windows服务器启动时间
2015-03-12 10:47 1652一、tomcat安装为windows服务 1.已经安装好的to ... -
<spring> 定时任务每次都执行两次的问题,慎用new ClassPathXmlApplicationContext()
2015-02-26 14:17 58131.问题描述 singleton的bean,spring配置定 ... -
<ajax> 给$.post()的回调方法传递多个参数
2015-01-16 14:10 38321.问题描述 想给$.post()的回调方法传递多个参数,如果 ... -
<js,jquery>正则表达式不需要用引号包围
2015-01-04 16:20 1126js或jquery里的正则表达式不能用"" ... -
<js,jquery> each里的continue和break效果
2015-01-04 16:17 753通常js或jquery里each比for用的更多,for循环里 ... -
chrome的粘贴带有样式
2014-12-28 22:02 12161.问题描述 页面div里的内容是带样式的,需要复制里面的纯文 ... -
<db> order by 时sqlserver认为null是最大值
2014-12-22 10:52 1210order by时sqlserver和oracle对null值 ...
相关推荐
springAOP等框架中,大量用到代理技术; 两类代理技术: 1,java动态代理,见JDK文档或相关java书;...2.cglib创建代理类,比第一种更加简单,代理类和背代理类不需要实现共同接口。本例子就是cglib代理的例子,很简单
在Java编程中,我们有时需要在运行时动态地创建或修改类,CGLib就是为此目的而设计的。它广泛应用于AOP(面向切面编程)框架,如Spring AOP,以及单元测试工具,如Mockito。 ### CGLib的工作原理 CGLib通过继承目标...
通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。 二、CGLIB原理 CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。...
3. `asm-2.2.3.jar`:ASM的基本库,提供了核心的字节码操作和分析功能,CGLib内部就是依赖这个库来实现对Java字节码的读取、修改和生成。 4. `asm-commons-2.2.3.jar`:ASM的通用库,包含了一些用于处理常见的字节...
通过创建目标类的子类,并在子类中拦截并增强方法调用,CGlib可以实现对无接口类的代理。 2. **AOP实现**:在Spring框架中,CGlib是实现AOP的重要组件。它能够生成代理对象,当方法被调用时,先执行切面逻辑,然后...
当一个类被代理时,CGLib会创建该类的一个子类,并在子类中覆盖方法,以此实现对目标类的拦截和增强。这种方法尤其适用于那些无法通过接口代理(如Java的InvocationHandler)的情况,比如需要代理的类没有实现任何...
CGLIB是基于ASM(一个底层的Java字节码操作和分析框架)来实现的,它允许开发者在运行时为Java类创建子类,而无需访问其源代码或重新编译。这种技术在许多场景下都非常有用,比如实现AOP(面向切面编程)中的动态...
8. **注意事项**:尽管Cglib提供了便捷的类生成能力,但生成的子类可能会增加内存占用,且对于final方法或final类,Cglib无法生成子类,这时需要考虑其他代理方案,如Java的动态代理。 总的来说,Cglib3.3.0作为一...
1. **创建代理类**:当需要对一个类进行动态代理时,CGLIB会生成一个新的子类,这个子类继承自原始类,并添加了额外的方法用于拦截和处理方法调用。 2. **方法拦截器**:CGLIB使用`Enhancer`类来创建代理对象,并...
1. **创建子类**: 当需要代理一个类时,CGlib会动态生成一个新的类,这个新类继承自原始类,并且添加了一个名为`Enhancer`的内部类。这个内部类包含了实际的增强逻辑。 2. **方法拦截**: 通过实现`...
CGLib的主要功能包括创建动态代理、动态创建子类以及在运行时修改类的行为。 【动态代理】 动态代理是Java编程中一个重要的概念,主要用于在不修改原有类代码的情况下,为类的方法添加额外的功能。CGLib通过创建...
CGlib允许开发者在运行时动态创建子类,从而实现对现有类的增强或代理功能。这个"cglib所有jar包"很可能是包含CGlib库不同版本或者不同模块的集合,方便开发者根据需求选择合适版本。 在Java中,动态代理是一种常见...
Cglib是一个强大的Java代码生成库,它在运行时动态创建子类,为现有类提供扩展功能。这个库被广泛用于实现AOP(面向切面编程)中的代理机制,特别是当无法通过接口代理时,例如Java标准库中的类。Cglib是Eclipse的...
CGLIB通过字节码技术创建一个目标类的子类,并在其中添加拦截器,实现动态代理。 2. **AOP(面向切面编程)**:CGLIB常被用于实现AOP框架,例如Spring AOP。在Spring中,如果没有使用接口,那么默认会使用CGLIB来...
- **Enhancer**:这个类负责创建增强的类实例,是CGLib的核心类。 - **MethodProxy**:用于代理方法调用,内部使用ASM实现。 深入研究CGLib的源码,你可以了解如何利用Java反射、字节码操作和代理机制来实现高效、...
CGlib常被用于创建动态代理,当目标类没有实现接口时,CGlib可以生成一个目标类的子类来实现代理。例如,在Spring AOP框架中,如果目标对象没有实现接口,Spring会使用CGlib来创建代理对象,以便在方法调用前后插入...
CGlib(Code Generation Library)是Java编程语言中的一个代码生成库,主要用于运行时动态创建对象和扩展类。在Java世界中,动态代理是一种强大的技术,它允许我们在运行时创建对象并实现特定接口或覆盖特定方法。...
在"cglib-src-2.2.jar"中,包含了CGLIB的源代码,开发者可以深入研究其内部实现,这对于理解其工作原理和进行定制化开发非常有帮助。源码中,我们可以看到CGLIB的核心类如Enhancer、MethodInterceptor、Callback等,...
CGLib的工作原理大致如下:首先,它会为需要代理的类生成一个子类,然后在这个子类中,针对每个方法创建一个增强方法,增强方法内部会调用MethodInterceptor的`intercept()`方法,最后在这个方法中进行实际的方法...