CGlib和JDK动态代理
一、CGlib动态代理
JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的1:字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用2:方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
字节码技术:参考:http://note.youdao.com/noteshare?id=13453e8d815d3102938a02881b6f418f&sub=E56D1E6223FC4CA8BF072CD045301EFA
CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。
这是一个需要被代理的类,也就是父类,通过字节码技术创建这个类的子类,实现动态代理。
[java] view plain copy
3. System.out.println("hello everyone");
该类实现了创建子类的方法与代理的方法。getProxy(SuperClass.class)方法通过入参即父类的字节码,通过扩展父类的class来创建代理对象。intercept()方法拦截所有目标类方法的调用,obj表示目标类的实例,method为目标类方法的反射对象,args为方法的动态入参,proxy为代理类实例。proxy.invokeSuper(obj, args)通过代理类调用父类中的方法。
[java] view plain copy
1. public class CglibProxy implements MethodInterceptor{
2. private Enhancer enhancer = new Enhancer();
3. public Object getProxy(Class clazz){
5. enhancer.setSuperclass(clazz);
6. enhancer.setCallback(this);
11.
public Object intercept(Object obj, Method method, Object[] args,
12.
MethodProxy proxy) throws Throwable {
13.
System.out.println("前置代理");
15.
Object result = proxy.invokeSuper(obj, args);
16.
System.out.println("后置代理");
[java] view plain copy
2. public static void main(String[] args) {
3. CglibProxy proxy = new CglibProxy();
5. SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);
[plain] view plain copy
1.通过实现InvocationHandler接口来自定义自己的InvocationHandler;
2.通过Proxy.getProxyClass获得动态代理类
3.通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
4.通过构造函数,获得代理对象,并将自定义的InvocationHandler实例对象传为参数传入
public
class ObjectProxy implements
InvocationHandler {
List<BeforeAdvice> beforeList = new ArrayList<BeforeAdvice>();
List<AfterAdvice> afterList = new ArrayList<AfterAdvice>();
// TODO Auto-generated constructor stub
public ObjectProxy(Object target) {
//解析advice.xml中所有的前置通知--得到class的值--->通过反射得到类的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse("src//advice.xml");
NodeList beforeNodeList = doc.getElementsByTagName("beforeAdvice");
for(int i=0;i<beforeNodeList.getLength();i++){
Element beforeElement =(Element) beforeNodeList.item(i);
String classValue = beforeElement.getAttribute("class"); //类的完整路径
Class clz = Class.forName(classValue);
BeforeAdvice obj = (BeforeAdvice)clz.newInstance();
NodeList afterNodeList = doc.getElementsByTagName("afterAdvice");
for(int i=0;i<afterNodeList.getLength();i++){
Element afterElement =(Element) afterNodeList.item(i);
String classValue = afterElement.getAttribute("class"); //类的完整路径
Class clz = Class.forName(classValue);
AfterAdvice obj = (AfterAdvice)clz.newInstance();
public Object invoke(Object proxy, Method method, Object[] args)
for(BeforeAdvice bf:beforeList){
Object result = method.invoke(target, args);
for(AfterAdvice af:afterList){
public
static Object getProxyBean(Object obj){
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),new ObjectProxy(obj));
public
static
void main(String[] args) {
Idog dog = (Idog)ObjectProxy.getProxyBean(new Dog());
CGlib和JDK动态代理的更多相关文章
- 学习CGLIB与JDK动态代理的区别
动态代理 代理模式是Java中常见的一种模式.代理又分为静态代理和动态代理.静态代理就是显式指定的代理,静态代理的优点是由程序员自行指定代理类并进行编译和运行,缺点是一个代理类只能对一个接口的实现类进 ...
- Cglib 与 JDK动态代理的运行性能比较
都说 Cglib 创建的动态代理的运行性能比 JDK 动态代理能高出大概 10 倍,今日抱着怀疑精神验证了一下,发现情况有所不同,遂贴出实验结果,以供参考和讨论. 代码很简单,首先,定义一个 Test ...
- Cglib 与 JDK动态代理
作者:xiaolyuh 时间:2019/09/20 09:58 AOP 代理的两种实现: jdk是代理接口,私有方法必然不会存在在接口里,所以就不会被拦截到: cglib是子类,private的方法照 ...
- 面试造火箭系列,栽在了cglib和jdk动态代理
"喂,你好,我是XX巴巴公司的技术面试官,请问你是张小帅吗".声音是从电话那头传来的 "是的,你好".小帅暗喜,大厂终于找上我了. "下面我们来进行一 ...
- 输出cglib以及jdk动态代理产生的class文件
--该设置用于输出jdk动态代理产生的类 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles&q ...
- spring cglib 与 jdk 动态代理
1. 概述 JDK动态代理是利用java反射机制 生成一个实现接口的匿名类, 在调用具体方法前调用InvocationHandler来处理 Cglib动态代理是 利用asm开源包 把被代理类的clas ...
- 有点深度的聊聊JDK动态代理
在接触SpringAOP的时候,大家一定会被这神奇的功能所折服,想知道其中的奥秘,底层到底是如何实现的.于是,大家会通过搜索引擎,知道了一个陌生的名词:动态代理,慢慢的又知道了动态代理有多种实现方式, ...
- java学习笔记(中级篇)—JDK动态代理
一.什么是代理模式 相信大家都知道代理商这个概念,在商业中,代理商无处不在.假设你要去买东西,你不可能去找真正的厂家去买,也不可能直接跟厂家提出需求,代理商就是这中间的一桥梁,连接买家和厂商.你要买或 ...
- AOP学习心得&jdk动态代理与cglib比较
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
随机推荐
- hdu 1232:畅通工程(数据结构,树,并查集)
畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 1520(简单树形dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 思路:dp[u][0]表示不取u的最大价值,dp[u][1]表示取u的最大价值,于是有dp[u] ...
- ANSI、ASCII、GB2312、GBK
ASCII 在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a.b.c.d这样的52个字母(包括大写).以及0.1等数字还有一些常用的符号 ...
- -pie can only be used when targeting iOS 4.2 or later
网上下载的demo,执行报错-pie can only be used when targeting iOS 4.2 or later 解决的方法:选择target==>改动developmen ...
- Hibernate_day01--Hibernate配置文件详解_核心api
Hibernate映射配置文件(重点) 1 映射配置文件名称和位置没有固定要求 2 映射配置文件中,标签name属性值写实体类相关内容 (1)class标签name属性值实体类全路径 (2)id标签和 ...
- Effective C++ Item 10,11 Have assignment operators return a reference to *this Handle assignment to self in operator =
If you want to concatenate assignment like this int x, y, z; x = y = z = 15; The convention is to ma ...
- spring的@Transactional注解详细用法(转载)
概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性.Spring Framework对事务管理提供了一致的抽象,其特点如下: 为不同的事务API提供一致的编程模型, ...
- c#修改cpu主频
并不是真正能修改硬件,只是一个数据,能骗过部分程序检测,如英雄联盟必须达到3.0的主频才能使用录像功能,通过修改可以达到要求. 下面是代码: public enum RegValueKind { // ...
- linux 将同后缀名的文件统一移至另一个文件夹
w
- ROS 笔记
ros的编程范式 - ros认为,linux平台下,机器人的软件由一个个小程序组成,这些小程序称为node,每个小程序负责一部分功能 - ros实现的框架就是,小程序的并发执行+相互通信,程序(进程) ...