CGlib小记
CGlib是一个强大的代码生成包。常被用于各种AOP框架,提供“拦截”功能。
JDK本身就为控制要訪问的对象提供了一
种途径,动态代理Proxy。
可是被代理的累必须实现一个或多个接口。假设想摆脱这个限制。为没有实现接口的类代
理的话。能够使用CGlib。
以下是一个入门学习的小样例。
需求:InfoManager类有四个方法,query、del、create、update。
要对这些方法进行訪问控制。仅仅有end用户可
以訪问全部方法。而其它用户仅仅能query。
<span style="font-size:18px;">public class InfoManager
{
public void query()
{
System.out.println("query method...");
} public void del()
{
System.out.println("del method...");
} public void create()
{
System.out.println("create method...");
} public void update()
{
System.out.println("update method...");
}
}
</span>
InfoManagerFactory类,用来生成InfoManager实例。
<span style="font-size:18px;">public class InfoManagerFactory
{
public static InfoManager getInstance(UserProxy proxy)
{
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(InfoManager.class);//被代理的类
enhancer.setCallbacks(new Callback[]{proxy, NoOp.INSTANCE});//两个callBack,第二个实则为空限制,实现某些方法的无限制訪问
enhancer.setCallbackFilter(new UserProxyFilter());//CallBack过滤器
return (InfoManager) enhancer.create();//创建带有拦截过滤功能的InfoManager的子类实例
}
}
</span>
UserProxy实现MethodInterceptor接口,用来拦截。
<span style="font-size:18px;">public class UserProxy implements MethodInterceptor
{
private String name; public UserProxy(String name)
{
super();
this.name = name;
} @Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable
{
if(!"end".equals(this.name))//非end用户。不能訪问
{
System.out.println(name + "没有权限訪问方法:" + method.getName());
return null;
}
return proxy.invokeSuper(object, args);//通过拦截,则反射调用InfoManager的相应方法。
} }</span>
UserProxyFilter实现CallbackFilter。制定规则,决定採用前面的哪个CallBack。
<span style="font-size:18px;">public class UserProxyFilter implements CallbackFilter
{
public static final int USER_NEED = 0; public static final int USER_NOT_NEED = 1; @Override
public int accept(Method method)
{
if("query".equals(method.getName()))
{
return USER_NOT_NEED;
}
return USER_NEED;
} }
</span>
这里要解释一下,accept方法返回值是int,就是这个值决定了採用哪个拦截器。看之前的这句代码:
<span style="font-size:18px;"><span style="font-size:18px;">enhancer.setCallbacks(new Callback[]{proxy, NoOp.INSTANCE});</span></span>
Enhancer设置了一个callBack数组,第一个为我们写的用户权限的拦截器。第二个为一个空的拦截器。当accept方法
发现被用户操作调用的方法是query时。应该都同意,所以返回值是1,所以採用了callBack数组下标为1的拦截器:空
拦截器,不进行验证拦截;当用户操作调用的方法是不query时。须要验证用户权限进行拦截,所以返回值是0,採用
callBack数组下标为0的拦截器:UserProxy。
而UserProxy中,我们仅仅同意end用户訪问InfoManager类方法。
至此,
我们就实现了需求中的功能。
InfoManagerFactory中。我们看到创建实例的方法中用到了Enhance。最后return了enhancer.create()的返回值。那么
在设置了各种属性后,enhancer.create()究竟做了什么呢,使得InfoManager实例,依照我们的规则被调用和拒绝。
在文章最開始。我们说到CGlib是一个动态生成代码的包。上面的小样例。原理事实上是这种:cglib在代码执行期间
,依据UserProxyFilter的accept方法返回值。选择了对应的MethodInterceptor拦截器。然后动态生成了一个InfoMana
ger的子类。并在子类中覆写了InfoManager中的各个方法,去调用拦截器的intercept方法。所以。Factory得到是cglib
生成的子类,调用里面的方法时。都会去拦截器里进行验证。
CGlib小记的更多相关文章
- 面经手册 · 第13篇《除了JDK、CGLIB,还有3种类代理方式?面试又卡住!》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 编程学习,先铺宽度还是挖深度? 其实技术宽度与技术深度是相辅相成的,你能了解多少技术 ...
- [原]Paste.deploy 与 WSGI, keystone 小记
Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...
- MySql 小记
MySql 简单 小记 以备查看 1.sql概述 1.什么是sql? 2.sql发展过程? 3.sql标准与方言的关系? 4.常用数据库? 5.MySql数据库安装? 2.关键概念 表结构----- ...
- 基于Spring AOP的JDK动态代理和CGLIB代理
一.AOP的概念 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...
- cglib动态新增类方法
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> & ...
- Git小记
Git简~介 Git是一个分布式版本控制系统,其他的版本控制系统我只用过SVN,但用的时间不长.大家都知道,分布式的好处多多,而且分布式已经包含了集中式的几乎所有功能.Linus创造Git的传奇经历就 ...
- 广州PostgreSQL用户会技术交流会小记 2015-9-19
广州PostgreSQL用户会技术交流会小记 2015-9-19 今天去了广州PostgreSQL用户会组织的技术交流会 分别有两个session 第一个讲师介绍了他公司使用PostgreSQL-X2 ...
- 东哥读书小记 之 《MacTalk人生元编程》
一直以来的自我感觉:自己是个记性偏弱的人.反正从小读书就喜欢做笔记(可自己的字写得巨丑无比,尼玛不科学呀),抄书这事儿真的就常发生俺的身上. 因为那时经常要背诵课文之类,反正为了怕自己忘记, ...
- Paypal支付小记
Paypal支付小记 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impo ...
随机推荐
- vue中滚动页面,改变样式&&导航栏滚动时,样式透明度修改
vue中滚动页面,改变样式&&导航栏滚动时,样式透明度修改.vue <div class="commonHeader" v-bind:class=" ...
- flatpickr插件的使用
flatpickr功能强大的日期时间选择器插件 日期格式化 <input class=flatpickr data-date-format="d-m-Y"> <i ...
- 模板—trie图
做了某题之后发现trie的AC自动机太垃圾了,动不动就TLE,然后我就去学了trie图. #include<iostream> #include<cstdio> using n ...
- CocoaPods 命令和使用
CocoaPods 命令 pod init 在新建的项目根目录下运行该命令,为当前项目新建podfile文件. pod install 下载和配置 podfile里定义的项目依赖(不包括已经下载和配置 ...
- python 获取路径
获取目录路径和文件路径 import osfor root, dirs, files in os.walk(".", topdown=False): # ‘.’为获取脚本所在路径下 ...
- java中引用对比C++指针
前置知识地址:https://blog.csdn.net/wangfei8348/article/details/51383805 重点在后面的引用对比实验(测试出内存地址,我很开心哈哈哈,客观给个好 ...
- 笔试算法题(57):基于堆的优先级队列实现和性能分析(Priority Queue based on Heap)
议题:基于堆的优先级队列(最大堆实现) 分析: 堆有序(Heap-Ordered):每个节点的键值大于等于该节点的所有孩子节点中的键值(如果有的话),而堆数据结构的所有节点都按照完全有序二叉树 排.当 ...
- python3.x Day5 面向对象
类:类是指:对具有相同属性的事物的抽象.蓝图.原型.在类中定义了这些事物都具备的属性和共同的方法. 对象:一个对象就是一个类实例化以后的实例,一个类必须经过实例化后才能在程序中被使用,一个类可以实例化 ...
- 592. Fraction Addition and Subtraction
Problem statement: Given a string representing an expression of fraction addition and subtraction, y ...
- Bzoj3060 [Poi2012]Tour de Byteotia
3060: [Poi2012]Tour de Byteotia Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 251 Solved: 161 Des ...