(转)Java动态代理与CGLib代理
- <br>public class UserDAOImpl{
- <br><br> public void save() {
- <br> // TODO Auto-generated method stub
- <br> System.out.println("user saved");
- <br> }
- <br>}
- <br>//相关配置,省略了一些不相关内容
- <br><bean id="userDAO" class="UserDAOImpl">
- <br><bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <br> <property name="target">
- <br> <ref local="userDAO" />
- <br> </property>
- <br></bean>
测试代码
- ApplicationContext ctx =
- <br> new FileSystemXmlApplicationContext("applicationContext.xml");
- <br> UserDAOImpl userDAOImpl =
- <br> (UserDAOImpl)ctx.getBean("userDAOProxy");
- <br> userDAOImpl.save();
上面这种情况下程序可以正常运行,但是如果UserDAOImpl实现了一个接口,其他不变
- public class UserDAOImpl implements UserDAO {
- <br>
- <br> public void save() {
- <br> // TODO Auto-generated method stub
- <br> System.out.println("user saved");
- <br> }
- <br>
- <br>}
这种情况下,程序将不能正常运行,会抛出java.lang.ClassCastException异常
理解上面这种情况产生的原因需要了解Spring AOP的实现原理。
Spring 实现AOP是依赖JDK动态代理和CGLIB代理实现的。
以下是JDK动态代理和CGLIB代理简单介绍
JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强。
Spring是依靠什么来判断采用哪种代理策略来生成AOP代理呢?以下代码就是Spring的判断逻辑
advisedSupport.isOptimize()与advisedSupport.isProxyTargetClass()默认返回都是false,所以在默认情况下目标对象有没有实现接口决定着Spring采取的策略,当然可以设置advisedSupport.isOptimize()或者advisedSupport.isProxyTargetClass()返回为true,这样无论目标对象有没有实现接口Spring都会选择使用CGLIB代理。所以在默认情况下,如果一个目标对象如果实现了接口Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出j ava.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现任何接口,Spring会选择CGLIB代理, 其生成的动态代理对象是目标类的子类。
以上说的是默认情况下,也可以手动配置一些选项使Spring采用CGLIB代理。
org.springframework.transaction.interceptor.TransactionProxyFactoryBean是org.springframework.aop.framework. ProxyConfig的子类,所以可以参照ProxyConfig里的一些设置如下所示,将optimize和proxyTargetClass任意一个设置为true都可以强制Spring采用CGLIB代理。
- //相关配置,省略了一些不相关内容
- <br><bean id="userDAO" class="UserDAOImpl">
- <br><bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <br> <property name="target">
- <br> <ref local="userDAO" />
- <br> </property>
- <br> <property name="optimize">
- <br> <value>true</value>
- <br> </property>
- <br> <property name="proxyTargetClass">
- <br> <value>true</value>
- <br> </property>
- <br></bean>
使用CGLIB代理也就不会出现前面提到的ClassCastException问题了,
也可以在性能上有所提高,但是也有它的弊端,Spring doc原文解释如下optimization will usually mean that advice changes won't take effect after a proxy has been created. For this reason, optimization is disabled by default。
(转)Java动态代理与CGLib代理的更多相关文章
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation ...
- Java动态代理和CGLib代理
本文参考 在上一篇"Netty + Spring + ZooKeeper搭建轻量级RPC框架"文章中涉及到了Java动态代理和CGLib代理,在这篇文章中对这两种代理方式做详解 下 ...
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理-转载
内容是摘抄的,不知最初的原作者,见谅 Java 动态代理.具体有如下四步骤: 通过实现 InvocationHandler 接口创建自己的调用处理器: 通过为 Proxy 类指定 ClassLoade ...
- java面试-java动态代理和cglib代理
代理模式就是为了提供额外或不同的操作,而插入的用来替代实际对象的对象,这些操作涉及到与实际对象的通信,因此代理通常充当中间人角色 一.java动态代理 java动态代理可以动态地创建代理并动态 ...
- IT忍者神龟之Java动态代理与CGLib代理
<br>public class UserDAOImpl{ <br><br> public void save() { <br> / ...
- java代理(静态代理和jdk动态代理以及cglib代理)
版权声明:本文为Fighter168原创文章,未经允许不得转载. 目录(?)[+] 说到代理,脑袋中浮现一大堆代理相关的名词,代理模式,静态代理,jdk代理,cglib代理等等. 记忆特别深刻 ...
- SpringAOP-JDK 动态代理和 CGLIB 代理
在 Spring 中 AOP 代理使用 JDK 动态代理和 CGLIB 代理来实现,默认如果目标对象是接口,则使用 JDK 动态代理,否则使用 CGLIB 来生成代理类. 1.JDK 动态代理 那么接 ...
- 静态代理、动态代理和cglib代理
转:https://www.cnblogs.com/cenyu/p/6289209.html 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处 ...
- 关于JDK动态代理与Cglib代理
关于JDK动态代理与Cglib代理 最近有时间学习一下SpringAOP源码,底层用到了代理,大概是这样的: 当需要被代理的类实现了接口,则使用JDK动态代理创建代理对象,增加增强操作执行目标方法 当 ...
随机推荐
- 上传文件(单文件)(FormData)(前端代码+.NET服务器端)
由于样式需要不能直接用file,只能用文本框+按钮 <form class="form-horizontal form-bordered form-row-strippe" ...
- 在VMware上安装Ubuntu14.04 , Docker
最近在公司做了一个关于 How to use Docker to deploy a java-based website 的KT,总结如下: 准备材料(Linux+64bit) 1. Tomcat安装 ...
- 处理BOM
[处理BOM]
- winfrom中DataGridView绑定数据控件中DataGridViewCheckBoxColumn怎么选中
; i < this.dataGridView1.Rows.Count; i++) { this.dataGridView1.Rows[i].Cells["CheckBoxCulums ...
- 纯手工打造(不使用IDE)java web 项目
必备环境 1.编译器:jdk 2.web服务器:tomcat 3.文本编辑器:sublime,编写java文件和jsp文件,没有的话用记事本也行. 一.建立工程目录结构,如下图 在操作系统下完成即可, ...
- 一个简单的SNTP客户端
借鉴于python网络编程攻略 #/usr/local/bin/python3.5 #coding:utf-8 import socket, struct, time NTP_server = &qu ...
- window的git extensions保存密码
git extensions每次pull与push均要输入密码,为解决该问题,执行以下操作: win+r,在运行中输入:%USERPROFILE% 找到其中的.gitconfig文件,找到[crede ...
- java 抽象类与接口的区别
在Java 语言中, abstract class 和interface 是支持抽象类 定义的两种机制.正是由于这两种机制的存在,才赋予 了Java强大的 面向对象能力.abstract class和 ...
- 2016---ios面试题
1.对数组中的元素去重复 例如: 1 2 3 NSArray *array = @[@"12-11", @"12-11", @"12-11&q ...
- 结合Apache和Tomcat实现集群和负载均衡
http://fableking.iteye.com/blog/360870 TomcatApacheJSP应用服务器Web 本文基本参考自 轻松实现Apache,Tomcat集群和负载均衡,经由实 ...