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. 递归删除N天前的文件夹及子文件夹下的特定文件

    @echo offrem 设置被删除文件夹路径set SrcDir=D:\tmp\test\rem 设置文件保存天数set Days=2rem /p指定搜索文件的路径 /s 在子目录中搜索 /m 指定 ...

  2. Java 序列化Serializable详解(附详细例子)

    Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...

  3. 原生js上传图片

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Hihocoder #1938 最大权闭合子图模板

    这里的讲解很不错,适合作为入坑题: Hihocoder#1938 代码: #include<algorithm> #include<iostream> #include< ...

  5. <Redis> 入门四 Jedis操作Redis

    pom依赖 <dependencies> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> < ...

  6. Python Pandas库的学习(一)

    今天我们来学习一下Pandas库,前面我们讲了Numpy库的学习 接下来我们学习一下比较重要的库Pandas库,这个库比Numpy库还重要 Pandas库是在Numpy库上进行了封装,相当于高级Num ...

  7. Django 模版语法 一

    创建项目 django_template 和 app django-admin startproject django_template python manage.py startapp app01 ...

  8. C语言学习7

    结构体数组:实现简易通讯录 #include <stdio.h> #include <stdlib.h> #define NUM 3 struct person { ]; ]; ...

  9. 74-A/D指标,Accumulation/Distribution,积累/派发线,离散指标.(2015.7.1)

    A/D指标,Accumulation/Distribution 积累/派发线,离散指标 观井映天 2015.7.1

  10. pcb中几个层的解释

    阻焊层(Solder Mask):又称为绿油层,是PCB的非布线层,用于制成丝网漏印板,将不需要焊接的地方涂一层阻焊物质,防止焊接PCB时焊锡在高温下的流动性.在阻焊层上预留的焊盘大小,要比实际焊盘大 ...