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 ...
随机推荐
- 09CSS高级定位
CSS高级定位 定位方式——position position:static|absolute|relative static表示为静态定位,是默认设置. absolute表示绝对定位,与下位置属 ...
- 04CSS文本字体及排版
CSS文本字体 字体——font-family font-family:字体1,字体2,字体3,……:应用font-family属性可以一次定义多个字体,而在浏览器读取字体时, 会按照定义的先后顺序来 ...
- 跳转QQ聊天窗口
1. 点击按钮跳转QQ聊天窗口,若不是好友,先加好友 <a href=" tencent://message/?uin=QQ号" target="_blank&qu ...
- 使用webpack搭建react项目 webpack-react-project
webpack-react-project 使用webpack搭建react项目 webpack搭建react项目 github源码 具体配置信息参照package.json和webpack.conf ...
- CF147B Smile House
题目大意:给定一个有向图,其中边有边权.求点数最少的正环的点数. 题解:建立矩阵,处理其二进制上每一位的状态.时间O(n^3*log(n)). 代码: #include<cstdio> # ...
- 解决mysql时区问题以及SSL问题
看了下网上的教程,觉得都太麻烦啦,这里推荐个简单的! 解决时区问题 只需要加上serverTimezone=UTC即可,如下: spring.datasource.url=jdbc:mysql://1 ...
- 分布式集群算法 memcached 如何实现分布式?
memcached 是一个”分布式缓存”,然后 memcached 并不像 mongoDB 那 样,允许配置多个节点,且节点之间”自动分配数据”. 就是说--memcached 节点之间,是不互相通信 ...
- [学习资料] Tiny210(S5PV210) u-boot移植
Tiny210(S5PV210) u-boot移植http://www.microoh.com/bbs/forum.php?mod=viewthread&tid=254&fromuid ...
- html css笔记 -度一
"""浏览器 shell 内核外表 内心 IE tridentFirefox Geckogoogle chrome webkit/blinksafari webkitop ...
- Zoj 3781(构造)
Zoj 3781(构造) Zoj 3781 As we all know, Coach Gao is a talented chef, because he is able to cook M dis ...