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 ...
随机推荐
- 2.10.2 section元素
section元素 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> & ...
- 多线程之Java中的等待唤醒机制
多线程的问题中的经典问题是生产者和消费者的问题,就是如何让线程有序的进行执行,获取CPU执行时间片的过程是随机的,如何能够让线程有序的进行,Java中提供了等待唤醒机制很好的解决了这个问题! 生产者消 ...
- React入门介绍(1)-ReactDOM.render()等基础
React入门介绍-ReactDOM.render()等基础 首先,React是一个用于构建用户界面的Javascript库,但Peact并不是一套完整的MVC或MVVM的框架,它仅涵盖V-view视 ...
- 处理半连接SQL自动改写内连接SQL一例
昨天刚写了半连接改写系列,今天就遇到了此类型SQL: 优化前 耗时:28s 返回:0 SELECT D.DAILYAUDITNO, D.TRANSTOACC FROM PB_DOIC.MM_DAILY ...
- 一次偶遇 IOException
今天遇到了个挺有意思的事情,为了实现上传头像的功能,这是需要实现的功能,项目在本地跑起来且在本地 服务器(tomcat)也实现了头像上传,并把头像路径存入数据库,但是却在上传到线上服务器的时候死活存不 ...
- SpringMVC Controller的返回类型
Controller的三种返回类型中 ModelAndView类型 带数据带跳转页面 String 跳转页面不带数据 void 通常是ajax格式请求时使用 1返回ModelAndView contr ...
- Spring核心技术(六)——Spring中Bean的生命周期
前文已经描述了Bean的作用域,本文将描述Bean的一些生命周期作用,配置还有Bean的继承. 定制Bean 生命周期回调 开发者通过实现Spring的InitializeingBean和Dispos ...
- 竞赛Noi_Linux使用总结(vim)
刚换完Linux,趁着教练给的改题时间(T2确实猛)自己上网找了好多博客,发现很多跟竞赛有关的内容是碎片化的,从最基本的如何用vim写代码.编译.运行,再到怎么改设置使打代码时手感强一些,最后学对拍, ...
- POJ3107 树的重心
题解:只不过如果有求多个点,输出所有方案. #include<cstring> #include<cmath> #include<iostream> #includ ...
- socketserver模块使用 & websocket
socketserver: socketserver可用于实现并发通信. socketserver 模块简化了编写网络服务程序的任务:同时 SocketServer 模块也是 Python标准库中很多 ...