为什么80%的码农都做不了架构师?>>>   

最近又继续回来死磕Spring源码,以前看的也忘得差不多了,这次先把Spring使用的动态代理cglib看了一下,打好基础知识。 cglib使用上特别简单,而且也不像Java要实现动态代理一样必须有接口,看一下cglib的wiki可以很容易上手。

实现前的准备

我们先准备测试用到的类和接口,简单的写一个test,假设是我们平常写的简单的dao

public interface TestDao {public String test();
}

然后写一个实现

public class TestDaoImpl implements TestDao {public String test() {System.out.println("test dao impl");return "test";}
}

里面就是简单的crud操作,现在如果我们需要对dao开启事务控制,我们当然可以直接在dao实现类中来做这个操作,不过对代码的侵入性很强,需要硬编码到Dao类中,而且重复代码会分布到每个类中。如果用代理来实现,那就会很优雅完美

Java动态代理的实现

首先来定义代理要实现的功能

public class Aop implements InvocationHandler {Object target;public Aop(Object o){this.target = o;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("java dynamic before");Object re = method.invoke(target, args);System.out.println("java dynamic after");return re;}
}

然后写一个生成代理类的工厂:

public class JavaDynamicObjectFactory {public static <T> T getProxiedObject(Class clazz){Aop aop = null;try {aop = new Aop(clazz.newInstance());T proxied = (T) Proxy.newProxyInstance(JavaDynamicObjectFactory.class.getClassLoader(), clazz.getInterfaces(), aop);return proxied;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return null;}public static void main(String[] args) {TestDao testDao = JavaDynamicObjectFactory.getProxiedObject(TestDaoImpl.class);testDao.test();}
}

测试后输出:

java dynamic before

test dao impl

java dynamic after

Cglib代理实现

cglib也需要实现一个接口

public class Aop implements MethodInterceptor {public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("cglib before");Object re = methodProxy.invokeSuper(o, objects);System.out.println("cglib after");return re;}
}

实现cglib工厂

public class CglibObjectFactory {public static TestDao getTestService(){return new TestDaoImpl();}public static <T> T getProxiedObject(Class clazz){Enhancer enhancer = new Enhancer();enhancer.setSuperclass(clazz);enhancer.setCallback(new Aop());T proxied = (T) enhancer.create();return proxied;}public static void main(String[] args) {TestDao testDao = CglibObjectFactory.getProxiedObject(TestDaoImpl.class);testDao.test();}
}

执行后输出:

cglib before

test dao impl

cglib after

当然cglib不仅仅这点功能,还提供了Bean generator ,Bean copier,Bean map等工具类功能,不过核心还是代码生成的

总结对比

cglib是直接操作字节码生成的代理类,底层依赖了ASM,Java的dynamic是在运行期增强,而且速度也一直受人诟病,平常如果有需要的话使用cglib还是很不错的,简单易上手。

废话几句

昨天在stackoverflow上看到一个关于代理框架的讨论,发现cglib有很多问题,很长时间没有更新,现在放到了GitHub上,然而更新解决问题依然很慢,不建议使用了。大家可以去尝试一下Javaassist,ASM等框架。ASM以前自己折腾过,不过看到后面全是byte code头晕,就放弃了,后面找机会再入坑

参考资料

github上的cglib tutorial

stackoverflow上的讨论Are there alternatives to cglib?

转载于:https://my.oschina.net/liufq/blog/1186463

Java动态代理与Cglib代理相关推荐

  1. Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)

    第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation ...

  2. Java静态代理、动态代理与CGLib代理

    java的动态代理举足轻重,它同反射原理一直是许多框架的底层实现.今天唠一下. 一.代理模式 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标 ...

  3. java代理(静态代理和jdk动态代理以及cglib代理)

    说到代理,脑袋中浮现一大堆代理相关的名词,代理模式,静态代理,jdk代理,cglib代理等等. 记忆特别深刻的是,一次面试中,一位面试官问我,spring的AOP核心采用的设计模式是什么什么模式,阅读 ...

  4. 静态代理,JDK动态代理和CGLIB代理入门学习

    之前面试时面试官问我:"你知道spring中有哪几种代理吗?" 啊?代理?啥子代理?VPN代理吗?嘿嘿,面试官你要种子直说啊......被刷下来了.好吧,入门学习下代理. 为什么需 ...

  5. 设计模式-代理模式(静态代理、动态代理、cglib代理)

    文章目录 代理模式 静态代理 动态代理 cglib代理 应用 代理模式 代理模式(Proxy Pattern)是一种结构性模式.代理模式为一个对象提供了一个替身,以控制对这个对象的访问.即通过代理对象 ...

  6. java 笔记(3) —— 动态代理,静态代理,cglib代理

    0.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口. 代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存 ...

  7. Java动态代理和Cglib动态代理最强王者阵容

    Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨黎杜 来源丨非科班的科班(LDCldc1230 ...

  8. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  9. 动态代理:JDK动态代理和CGLIB代理的区别

    代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法.实际执行的是被代理类的方法. 而AOP,是通过动态代理实现的. 一.简单来说: JD ...

最新文章

  1. python写一个聊天程序_python实现一个简单的网络聊天程序
  2. 计算机第一课 教案 纪律,信息技术开学第一课-纪律
  3. html地区三级联下拉列表,JS-三级联下拉列表
  4. java 日期 区间_如何实现时间区间的分割??
  5. Activiti绩效对决
  6. SSKeychain
  7. ublox Android 定位超时,[RK3288] [Android 7.1] u-blox GPS调试
  8. python并发编程4-线程
  9. .net 中应用 ValidationAttribute
  10. Python文件读写——使用“with open ... as f”进行文件打开的操作
  11. java推送到 钉钉用户_javaweb利用钉钉机器人向钉钉群推送消息(解决中文乱码)...
  12. linux之切换用户su(switch user)
  13. 命令式编程面向算法vs声明式编程面向描述
  14. cocos2d-x学习之旅(十一):制作TXM游戏地图,并加载到游戏场景中
  15. 字母缩写对应的世界各国家及其官方语言java工具类
  16. Android中的Activity
  17. python -不敢表白,不好意思说出来,没关系,7行代码完成自动打印文字
  18. java用一张一元票换一分,把一元纸币换成一分、二分、五分硬币(每种至少一枚),有多少种换法?使用递归...
  19. 微信为什么打不开html,微信打不开怎么回事_手机微信打不开怎么办【图文】-太平洋电脑网PConline-太平洋电脑网...
  20. 搜索编程的艺术之C#实现微信小程序包解密

热门文章

  1. Android深度探索第四章
  2. Traffic Ccontrol(流量控制)
  3. 【转】【UNITY3D 游戏开发之五】Google-protobuf与FlatBuffers数据的序列化和反序列化...
  4. Openstack 小知识点
  5. AIR 配置文件(*-app.xml)说明(转)
  6. 三层交换机实现VLAN互通实例
  7. AOC的显示器真的很烂
  8. ubuntu创建vim php文件,在ubuntu 上配置vim的php开发环境
  9. java hellowordk_Rhythmk 一步一步学 JAVA(4):Spring3 MVC 之 Hello Word
  10. java中可以改变引用的指向吗_java中引用传递问题,在函数中修改引用的指向,会不会影响实参?...