`

深入浅出CGlib-打造无入侵的类代理

    博客分类:
  • J2SE
阅读更多
CGlib是什么?
CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
当然这些实际的功能是asm所提供的,asm又是什么?Java字节码操控框架,具体是什么大家可以上网查一查,毕竟我们这里所要讨论的是cglib,
cglib就是封装了asm,简化了asm的操作,实现了在运行期动态生成新的class。
可能大家还感觉不到它的强大,现在就告诉你。
实际上CGlib为spring aop提供了底层的一种实现;为hibernate使用cglib动态生成VO/PO (接口层对象)。

下面我们将通过一个具体的事例来看一下CGlib体验一下CGlib。
* CGlib 2.13
* ASM 2.23
以一个实例在简单介绍下cglib的应用。
我们模拟一个虚拟的场景,模拟对表的操作。
1. 开始我们对表提供了CRUD方法。
我们现在创建一个对Table操作的DAO类。
public class TableDAO {
	public void create(){
		System.out.println("create() is running !");
	}
	public void query(){
		System.out.println("query() is running !");
	}
	public void update(){
		System.out.println("update() is running !");
	}
	public void delete(){
		System.out.println("delete() is running !");
	}
}

OK,它就是一个javaBean,提供了CRUD方法的javaBean。
下面我们创建一个DAO工厂,用来生成DAO实例。
public class TableDAOFactory {
	private static TableDAO tDao = new TableDAO();
	public static TableDAO getInstance(){
		return tDao;
	}
}

接下来我们创建客户端,用来调用CRUD方法。
public class Client {

	public static void main(String[] args) {
		TableDAO tableDao = TableDAOFactory.getInstance();
		doMethod(tableDao);
	}
	public static void doMethod(TableDAO dao){
		dao.create();
		dao.query();
		dao.update();
		dao.delete();
	}
}

OK,完成了,CRUD方法完全被调用了。当然这里并没有CGlib的任何内容。问题不会这么简单的就结束,新的需求来临了。
2. 变化随之而来,Boss告诉我们这些方法不能开放给用户,只有“张三”才有权使用。阿~!怎么办,难道我们要在每个方法上面进行判断吗?
好像这么做也太那啥了吧,对了对了Proxy可能是最好的解决办法。jdk的代理就可以解决了。 好了我们来动手改造吧。等等jdk的代理需要实现接口,这样,
我们的dao类需要改变了。既然不想改动dao又要使用代理,我们这就请出CGlib。
我们只需新增一个权限验证的方法拦截器。
public class AuthProxy implements MethodInterceptor {
	private String name ;
	//传入用户名称
	public AuthProxy(String name){
		this.name = name;
	}
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		//用户进行判断
		if(!"张三".equals(name)){
			System.out.println("你没有权限!");
			return null;
		}
		return arg3.invokeSuper(arg0, arg2);
	}
}

当然不能忘了对我们的dao工厂进行修改,我们提供一个使用代理的实例生成方法
public static TableDAO getAuthInstance(AuthProxy authProxy){
	Enhancer en = new Enhancer();
	//进行代理
	en.setSuperclass(TableDAO.class);
	en.setCallback(authProxy);
	//生成代理实例
	return (TableDAO)en.create();
}

我们这就可以看看客户端的实现了。添加了两个方法用来验证不同用户的权限。
public static void haveAuth(){
	TableDAO tDao = TableDAOFactory.getAuthInstance(new AuthProxy("张三"));
	doMethod(tDao);
}
public static void haveNoAuth(){
	TableDAO tDao = TableDAOFactory.getAuthInstance(new AuthProxy("李四"));
	doMethod(tDao);
}

OK,"张三"的正常执行,"李四"的没有执行。
看到了吗?简单的aop就这样实现了
难道就这样结束了么?
3. Boss又来训话了,不行不行,现在除了"张三"其他人都用不了了,现在不可以这样。他们都来向我反映了,必须使用开放查询功能。
哈哈,现在可难不倒我们了,因为我们使用了CGlib。当然最简单的方式是去修改我们的方法拦截器,不过这样会使逻辑变得复杂,且
不利于维护。还好CGlib给我们提供了方法过滤器(CallbackFilter),CallbackFilte可以明确表明,被代理的类中不同的方法,
被哪个拦截器所拦截。下面我们就来做个过滤器用来过滤query方法。
public class AuthProxyFilter implements CallbackFilter{
	public int accept(Method arg0) {
		if(!"query".equalsIgnoreCase(arg0.getName()))
			return 0;
		return 1;
	}

}

OK,可能大家会对return 0 or 1感到困惑,用到的时候就会讲解,当然下面就会用到了。
我们在工场中新增一个使用了过滤器的实例生成方法。
public static TableDAO getAuthInstanceByFilter(AuthProxy authProxy){
	Enhancer en = new Enhancer();
	en.setSuperclass(TableDAO.class);
	en.setCallbacks(new Callback[]{authProxy,NoOp.INSTANCE});
	en.setCallbackFilter(new AuthProxyFilter());
	return (TableDAO)en.create();
}

看到了吗setCallbacks中定义了所使用的拦截器,其中NoOp.INSTANCE是CGlib所提供的实际是一个没有任何操作的拦截器,
他们是有序的。一定要和CallbackFilter里面的顺序一致。明白了吗?上面return返回的就是返回的顺序。也就是说如果调用query方法就使用NoOp.INSTANCE进行拦截。
现在看一下客户端代码。
public static void haveAuthByFilter(){
	TableDAO tDao = TableDAOFactory.getAuthInstanceByFilter(new AuthProxy("张三"));
	doMethod(tDao);

	tDao = TableDAOFactory.getAuthInstanceByFilter(new AuthProxy("李四"));
	doMethod(tDao);
}

ok,现在"李四"也可以使用query方法了,其他方法仍然没有权限。
哈哈,当然这个代理的实现没有任何侵入性,无需强制让dao去实现接口。

如果大家对java的深入研究有兴趣
可以加入Q群:46176507 共同进步学习
分享到:
评论
17 楼 overshit 2016-09-20  
api更新了,一加filter就Callback filter returned an index that is too large: 1
16 楼 Bll 2013-07-24  
2. 变化随之而来,Boss告诉我们这些方法不能开放给用户,只有“张三”才有权使用。阿~!怎么办,难道我们要在每个方法上面进行判断吗?
好像这么做也太那啥了吧,对了对了Proxy可能是最好的解决办法。jdk的代理就可以解决了。 好了我们来动手改造吧。等等jdk的代理需要实现接口,这样,
我们的dao类需要改变了。既然不想改动dao又要使用代理,我们这就请出CGlib。
我们只需新增一个权限验证的方法拦截器。
15 楼 ziqiang99 2012-09-19  
灰常好。 
14 楼 jerry峰少 2012-09-13  
楼主威武
13 楼 medicine 2012-07-15  
good bady!
12 楼 zyb12qq 2011-10-03  
学习了 
11 楼 yangfuchao418 2011-08-25  
发现权限和这个多么类似。
10 楼 hyj1254 2011-06-06  
arg3.invokeSuper(arg0, arg2)

这句的返回值有问题,一直是null.改用arg1.invoke()就可以。
9 楼 385104182 2011-03-31  
呱唧呱唧,太好了讲的?    
8 楼 loginin 2011-02-16  
讲的太好了!理解了!
7 楼 zdjray 2010-11-19  
写的好,不过CallbackFilter的顺序应该可以说的更清楚一些
6 楼 9976 2010-11-08  
学习了,讲的挺好。
5 楼 cutesunshineriver 2010-11-04  
成功跑了楼主的示例,楼主讲的很好。
4 楼 putonyuer 2010-04-06  
垃圾垃圾垃圾垃圾垃圾垃圾垃圾垃圾垃圾垃圾
3 楼 dong717 2009-12-07  
讲的很好!
2 楼 tanglei198577 2009-08-07  
讲的不错
1 楼 zhouyaguo 2009-01-03  
非常好。

相关推荐

    深入浅出CGlib-打造无入侵的类代理 - llying - ITeye技术网站

    本文将深入探讨CGlib的工作原理及其在构建无入侵类代理中的应用。 首先,CGlib是一个基于ASM库的动态代理实现。ASM是一个字节码操作和分析框架,允许程序员生成和修改Java类和字节码。CGlib通过ASM在运行时创建新的...

    hhhhh安卓开发教程大全

    hhhhh安卓开发教程大全

    avem-labs_Avem_1740990015.zip

    avem-labs_Avem_1740990015.zip

    25883-mofangmall.com 微信群管理机器人系统网站.zip

    微信群机器人管理系统源码 微信群机器人管理系统源码 支持同登陆多个微信 源码类型: C/S 开发环境: VS2010 SQL2008R2 菜单功能 1、支持同时登录多个微信 2、支持机器人聊天(笑话,成语接龙、故事会、智力等等) 3、支持签到 4、可自定义回复 5、可自定义红包语 6、支持定期发送公告(如群规,广告)等 1、WeChatRobots后台配置web版 2、数据库在WeiChartGroup.Net/app_data中,附加即可

    https://upload.csdn.net/creation/uploadResources?spm=1003.2018.3001.4314

    https://upload.csdn.net/creation/uploadResources?spm=1003.2018.3001.4314

    名字微控制器_STM32_课程_DeepBlue_1740989720.zip

    名字微控制器_STM32_课程_DeepBlue_1740989720.zip

    S7-200Smart恒压供水程序示例与485通讯实践:操作指南与案例解析,S7-200 Smart可编程控制器恒压供水程序设计与实现,附带485通讯范例,S7-200Smart 恒压供水程序样例+4

    S7-200Smart恒压供水程序示例与485通讯实践:操作指南与案例解析,S7-200 Smart可编程控制器恒压供水程序设计与实现,附带485通讯范例,S7-200Smart 恒压供水程序样例+485通讯样例 ,S7-200Smart; 恒压供水程序样例; 485通讯样例,S7-200Smart程序样例:恒压供水及485通讯应用示例

    Java读写Mifare M1卡IC卡源码

    Java使用JNA、JNI两种不同方式调用DLL、SO动态库方式读写M1卡源码,支持读写M1卡扇区数据、修改IC卡扇区密钥、改写UID卡卡号等功能,支持Windows系统,同时支持龙芯Mips、LoongArch、海思麒麟鲲鹏飞腾Arm、海光兆芯x86_Amd64等架构平台的国产统信、麒麟等Linux系统,内有jna-4.5.0.jar包,vx13822155058 qq954486673

    UDP协议接收和发送数据示例JAVA

    UDP协议接收和发送数据示例JAVA

    VU-DBS项目:深脑刺激器的全程辅助

    本文介绍了范德堡大学深脑刺激器(DBS)项目,该项目旨在开发和临床评估一个系统,以辅助从规划到编程的整个过程。DBS是一种高频刺激治疗,用于治疗运动障碍,如帕金森病。由于目标区域在现有成像技术中可见性差,因此DBS电极的植入和编程过程复杂且耗时。项目涉及使用计算机辅助手术技术,以及一个定制的微定位平台(StarFix),该平台允许在术前进行图像采集和目标规划,提高了手术的精确性和效率。此外,文章还讨论了系统架构和各个模块的功能,以及如何通过中央数据库和网络接口实现信息共享。

    图像识别项目源码资源(Python和C++)

    图像识别”项目源码资源(Python和C++)

    虚拟同步电机与并电网模型的Simulink仿真参数配置与直接使用指南,虚拟同步电机与并电网模型的Simulink仿真:参数齐全,直接使用,同步电机simulink仿真 并电网模型仿真 参数设置好了

    虚拟同步电机与并电网模型的Simulink仿真参数配置与直接使用指南,虚拟同步电机与并电网模型的Simulink仿真:参数齐全,直接使用,同步电机simulink仿真 并电网模型仿真 参数设置好了,可直接使用 ,虚拟同步电机; simulink仿真; 并电网模型仿真; 参数设置; 使用,虚拟同步电机Simulink仿真与并电网模型参数化应用

    三菱FX3U与力士乐VFC-x610变频器通讯案例详解:PLC控制下的变频器操作与设置程序,含接线方式及昆仑通态触摸屏操作指南,三菱FX3U与力士乐VFC-x610变频器通讯案例详解:接线、设置与程序

    三菱FX3U与力士乐VFC-x610变频器通讯案例详解:PLC控制下的变频器操作与设置程序,含接线方式及昆仑通态触摸屏操作指南,三菱FX3U与力士乐VFC-x610变频器通讯案例详解:接线、设置与程序注解,实现频率设定、启停控制与实时数据读取功能。,三菱FX3U与力士乐VFC-x610变频器通讯程序三菱FX3U与力士乐VFC-x610变频器通讯案例程序,有注释。 并附送程序,有接线方式,设置。 器件:三菱FX3U的PLC,力士乐VFCx610变频器,昆仑通态,威纶通触摸屏。 功能:实现频率设定,启停控制,实际频率读取等。 ,三菱FX3U;力士乐VFC-x610变频器;通讯程序;案例程序;注释;接线方式;设置;频率设定;启停控制;实际频率读取;昆仑通态;威纶通触摸屏。,三菱FX3U与力士乐VFC-x610变频器通讯程序及案例:频率控制与读取实践

    xmselect测试用例~~~~~~~~~~~~~~

    xmselect测试用例~~~~~~~~~~~~~~

    Unity-游戏开发-模型资源-科幻武器

    总共包含 32 款 AAA 级科幻武器。四种武器类型,每种有 8 种不同的纹理变化! 所有内容均采用 PBR 材质,可直接用于开发游戏!

    python词云生成器,将txt文本自动分割生成词云图

    python词云生成器,将txt文本自动分割生成词云图

    基于物联网智能化平台的智慧园区解决方案PPT(28页).pptx

    智慧园区,作为现代城市发展的新形态,旨在通过高度集成的信息化系统,实现园区的智能化管理与服务。该方案提出,利用智能手环、定制APP、园区管理系统及物联网技术,将园区的各类设施与设备紧密相连,形成一个高效、便捷、安全的智能网络。从智慧社区到智慧酒店,从智慧景区到智慧康养,再到智慧生态,五大应用板块覆盖了园区的每一个角落,为居民、游客及工作人员提供了全方位、个性化的服务体验。例如,智能手环不仅能实现定位、支付、求助等功能,还能监测用户健康状况,让科技真正服务于生活。而智慧景区的建设,更是通过大数据分析、智能票务、电子围栏等先进技术,提升了游客的游玩体验,确保了景区的安全有序。 尤为值得一提的是,方案中的智慧康养服务,展现了科技对人文关怀的深刻体现。通过智慧手环与传感器,自动感知老人身体状态,及时通知家属或医疗机构,有效解决了“空巢老人”的照护难题。同时,智慧生态管理系统的应用,实现了对大气、水、植被等环境要素的实时监测与智能调控,为园区的绿色发展提供了有力保障。此外,方案还提出了建立全域旅游营销平台,整合区域旅游资源,推动旅游业与其他产业的深度融合,为区域经济的转型升级注入了新的活力。 总而言之,这份智慧园区建设方案以其前瞻性的理念、创新性的技术和人性化的服务设计,为我们展示了一个充满智慧与活力的未来园区图景。它不仅提升了园区的运营效率和服务质量,更让科技真正融入了人们的生活,带来了前所未有的便捷与舒适。对于正在规划或实施智慧园区建设的决策者而言,这份方案无疑提供了一份宝贵的参考与启示,激发了他们对于未来智慧生活的无限遐想与憧憬。

    使用 SignalR 在 .NET Core 8 最小 API 中构建实时通知

    使用 SignalR 在 .NET Core 8 最小 API 中构建实时通知,构建实时应用程序已成为现代 Web 开发中必不可少的部分,尤其是对于通知、聊天系统和实时更新等功能。SignalR 是 ASP.NET 的一个强大库,可实现服务器端代码和客户端 Web 应用程序之间的无缝实时通信。 参考文章:https://blog.csdn.net/hefeng_aspnet/article/details/145990801

    自适应网址导航网站发布页单页网页模板html源码

    自适应网址导航网站发布页单页网页模板html源码,超级好看自适应清新网址导航网站发布页单页网页模板html源码!无论电脑还是手机,这是一个网页单页源码!! 模板无后台模板,无需数据库,上传服务器直接能用。

    win11 win10的tga缩略图补丁,亲测可用

    不用花钱,不拐弯抹角。

Global site tag (gtag.js) - Google Analytics