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小记的更多相关文章

  1. 面经手册 · 第13篇《除了JDK、CGLIB,还有3种类代理方式?面试又卡住!》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 编程学习,先铺宽度还是挖深度? 其实技术宽度与技术深度是相辅相成的,你能了解多少技术 ...

  2. [原]Paste.deploy 与 WSGI, keystone 小记

    Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...

  3. MySql 小记

    MySql  简单 小记 以备查看 1.sql概述 1.什么是sql? 2.sql发展过程? 3.sql标准与方言的关系? 4.常用数据库? 5.MySql数据库安装? 2.关键概念 表结构----- ...

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

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

  5. cglib动态新增类方法

    <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> & ...

  6. Git小记

    Git简~介 Git是一个分布式版本控制系统,其他的版本控制系统我只用过SVN,但用的时间不长.大家都知道,分布式的好处多多,而且分布式已经包含了集中式的几乎所有功能.Linus创造Git的传奇经历就 ...

  7. 广州PostgreSQL用户会技术交流会小记 2015-9-19

    广州PostgreSQL用户会技术交流会小记 2015-9-19 今天去了广州PostgreSQL用户会组织的技术交流会 分别有两个session 第一个讲师介绍了他公司使用PostgreSQL-X2 ...

  8. 东哥读书小记 之 《MacTalk人生元编程》

         一直以来的自我感觉:自己是个记性偏弱的人.反正从小读书就喜欢做笔记(可自己的字写得巨丑无比,尼玛不科学呀),抄书这事儿真的就常发生俺的身上. 因为那时经常要背诵课文之类,反正为了怕自己忘记, ...

  9. Paypal支付小记

    Paypal支付小记 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impo ...

随机推荐

  1. JAVA基础——设计模式之单列模式

    一:单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 单例设计模式的特点: 单例类只能 ...

  2. 诊断:CLSRSC-400: A system reboot is required to continue installing.

    Linux7.5安装Grid Infrastructure 12.2.0.1时,在root.sh时会报错 2018/01/30 09:19:28 CLSRSC-330: Adding Clusterw ...

  3. 零基础入门学习Python(4)--改进我们的小游戏

    前言 在以前的博客中有做个一个小游戏,但是太简单了,所以这次就来对我们做的小游戏进行改进,改善从以下四个方面进行: 程序猜错的时候要给出提示,例如告诉用户输入的值是大了还是小了. 以前程序每运行一次只 ...

  4. 虚拟机Linux与本地虚拟网卡配置---NAT链接方式

    虚拟机Linux与本地虚拟网卡配置---NAT链接方式 **********这是我亲自尝试多次实践出来的结果,不是复制粘贴************************* 首先进行初始化,这样避免有 ...

  5. Buffer.from(str[, encoding])

    Buffer.from(str[, encoding]) Node.js FS模块方法速查 str {String} 需要编码的字符串 encoding {String} 编码时用到,默认:'utf8 ...

  6. c++基础_字符串对比

    #include <iostream> #include <string.h> #include <algorithm> using namespace std; ...

  7. LLVM 概览

    下面是 LLVM 首页对 LLVM 介绍的中文翻译. LLVM 项目是一系列模块化.可重用和工具链技术的集合.不必在意它的名称,LLVM 和之前的虚拟机基本没什么关系了,然而也确实提供了对构建这些虚拟 ...

  8. * SPOJ PGCD Primes in GCD Table (需要自己推线性筛函数,好题)

    题目大意: 给定n,m,求有多少组(a,b) 0<a<=n , 0<b<=m , 使得gcd(a,b)= p , p是一个素数 这里本来利用枚举一个个素数,然后利用莫比乌斯反演 ...

  9. [luoguP3402] 最长公共子序列(DP + 离散化 + 树状数组)

    传送门 比 P1439 排列LCS问题,难那么一点点,只不过有的元素不是两个串都有,还有数据范围变大,树状数组得打离散化. 不过如果用栈+二分的话还是一样的. ——代码 #include <cs ...

  10. Codeforces Round #261 (Div. 2) E (DP)

    E. Pashmak and Graph Pashmak's homework is a problem about graphs. Although he always tries to do hi ...