- 浏览: 485438 次
- 性别:
- 来自: 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 28911.场景 很多时候需要下载第三方源码修改并重新编译打包,比如m ... -
super用在了匿名内部类里
2016-07-06 09:47 12311.问题描述 本来是重构时在父类里增加了一个protected ... -
<spring-expected at least 1 matching bean> 缺少bean定义
2016-03-04 10:37 13961. 问题描述 ... Error creating bean ... -
《IDEA 循环依赖》Annotation processing is not supported for module cycles.
2015-11-04 16:30 367421. 错误现象 Error:java: Annotation ... -
数据库小问题集合
2015-09-23 14:58 6481. mysql默认查询时,不区分字母大小写。 比如:sele ... -
slf4j 的MDC (附带主动获取方法堆栈)
2015-08-03 17:29 52931. 主动获取方法调用链 ... -
<spring-aop> BeanNotOfRequiredTypeException 切面异常
2015-07-24 17:59 66641. 问题描述 往工程里添加切面,定义了<aop:asp ... -
<Spring-Aspect> 切面类(@Aspect)首先必须是bean
2015-07-20 14:08 36771. 问题描述 今天发现老工程里有个日志切面但是总是也没有执行 ... -
<tomcat> 启动报错 Error listenerStart
2015-07-10 09:32 3360今天同事遇到一个tomcat启动失败的问题,日志信息很少,不知 ... -
Intellij IDEA--can't use subversion command line client : svn
2015-06-04 10:45 171501. 错误描述 初用IDEA,暂时感到的还是不适应。导入工程报 ... -
<myeclipse> 修改Source Folder
2015-04-27 16:25 1613MyEclipse工程里新增文件夹时有普通Folder和Sou ... -
<maven> 新工程打包遇到Access restriction
2015-04-27 16:17 11411、错误描述 Access restriction: The ... -
<线程池-定时任务> ScheduledExecutorService之shutdown引发的RejectedExecutionException问题
2015-03-20 21:32 5496一、 问题描述 先来看一下异常信息,启动tomcat时就报错: ... -
<windows, tomcat> tomcat安装为windows服务,查看windows服务器启动时间
2015-03-12 10:47 1591一、tomcat安装为windows服务 1.已经安装好的to ... -
<spring> 定时任务每次都执行两次的问题,慎用new ClassPathXmlApplicationContext()
2015-02-26 14:17 57151.问题描述 singleton的bean,spring配置定 ... -
<ajax> 给$.post()的回调方法传递多个参数
2015-01-16 14:10 37921.问题描述 想给$.post()的回调方法传递多个参数,如果 ... -
<js,jquery>正则表达式不需要用引号包围
2015-01-04 16:20 1047js或jquery里的正则表达式不能用"" ... -
<js,jquery> each里的continue和break效果
2015-01-04 16:17 703通常js或jquery里each比for用的更多,for循环里 ... -
chrome的粘贴带有样式
2014-12-28 22:02 11471.问题描述 页面div里的内容是带样式的,需要复制里面的纯文 ... -
<db> order by 时sqlserver认为null是最大值
2014-12-22 10:52 1161order by时sqlserver和oracle对null值 ...
相关推荐
springAOP等框架中,大量用到代理技术; 两类代理技术: 1,java动态代理,见JDK文档或相关java书;...2.cglib创建代理类,比第一种更加简单,代理类和背代理类不需要实现共同接口。本例子就是cglib代理的例子,很简单
cglib动态生成java类
CGLIB简介CGLIB简介CGLIB简介CGLIB简介CGLIB简介
通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。 二、CGLIB原理 CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。...
JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该...
使用CGLIB扩展对象行为的原理是:对目标对象进行继承扩展,为其生成相应的子类,而子类可以通过覆写来扩展父类的行为,只要将横切逻辑的实现放到子类中,然后让系统使用扩展后的目标对象的子类,就可以达到与代理...
cglib
cglib.zip
创建被代理类、创建代理类、代理类内部聚合被代理类 * 2.创建返回代理类实例方法 Enhancer.create(object.getClass(), this); * (1.创建工具类,2.设置工具类的父类为被代理类 3.设计监听回调为当前this 4.return ...
开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4开发工具 cglib-3.2.4...
赠送jar包:cglib-3.1.jar; 赠送原API文档:cglib-3.1-javadoc.jar; 赠送源代码:cglib-3.1-sources.jar; 赠送Maven依赖信息文件:cglib-3.1.pom; 包含翻译后的API文档:cglib-3.1-javadoc-API文档-中文(简体)版...
CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。...它们都通过使用CGLIB来为那些没有接口的类创建模仿(mock)对象。
JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现. Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的...
cglib 的jar包,用于做动态代理的,但是版本太高不知道会不会有影响
CGlib动态代理类jar包,一共两个jar包,模拟CGlib动态代理用得到。
jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,...
CGLIB-DOC,CGLIB说明文件.
基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)...
CGlib动态代理类jar包,一共四个jar包,模拟CGlib动态代理用得到。
在cglib需要的包,含有asm.jar asm_commons.jar asm-util.jar cglib-nodep.jar