cglib 动态代理基础篇

CGlib是什么? 
CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。 
下面我们将通过一个具体的事例来看一下CGlib体验一下CGlib。 
cglib-nodep-2.2.2.jar

public class TableDAO {
public void create(){
System.out.println("create() is running !");
}
public void query(){
System.out.println("query() is running !");
}
public void update(){
System.out.println("update() is running !");
}
public void delete(){
System.out.println("delete() is running !");
}
}

OK,它就是一个javaBean,提供了CRUD方法的javaBean。 
下面我们创建一个DAO工厂,用来生成DAO实例。

public class TableDAOFactory {
private static TableDAO tDao = new TableDAO();
public static TableDAO getInstance(){
return tDao;
}
}

接下来我们创建客户端,用来调用CRUD方法。

public class Client {

    public static void main(String[] args) {
TableDAO tableDao = TableDAOFactory.getInstance();
doMethod(tableDao);
}
public static void doMethod(TableDAO dao){
dao.create();
dao.query();
dao.update();
dao.delete();
}
}

OK,完成了,CRUD方法完全被调用了。当然这里并没有CGlib的任何内容。问题不会这么简单的就结束,新的需求来临了。 
2. 变化随之而来,Boss告诉我们这些方法不能开放给用户,只有“张三”才有权使用。阿~!怎么办,难道我们要在每个方法上面进行判断吗? 
好像这么做也太那啥了吧,对了对了Proxy可能是最好的解决办法。jdk的代理就可以解决了。 好了我们来动手改造吧。等等jdk的代理需要实现接口,这样, 
我们的dao类需要改变了。既然不想改动dao又要使用代理,我们这就请出CGlib。 
我们只需新增一个权限验证的方法拦截器。

public class AuthProxy implements MethodInterceptor {
private String name ;
//传入用户名称
public AuthProxy(String name){
this.name = name;
}
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
//用户进行判断
if(!"张三".equals(name)){
System.out.println("你没有权限!");
return null;
}
return arg3.invokeSuper(arg0, arg2);
}
}

当然不能忘了对我们的dao工厂进行修改,我们提供一个使用代理的实例生成方法

public static TableDAO getAuthInstance(AuthProxy authProxy){
Enhancer en = new Enhancer();
//进行代理
en.setSuperclass(TableDAO.class);
en.setCallback(authProxy);
//生成代理实例
return (TableDAO)en.create();
}

OK,"张三"的正常执行,"李四"的没有执行。 
看到了吗?简单的aop就这样实现了 
难道就这样结束了么? 
3. Boss又来训话了,不行不行,现在除了"张三"其他人都用不了了,现在不可以这样。他们都来向我反映了,必须使用开放查询功能。 
哈哈,现在可难不倒我们了,因为我们使用了CGlib。当然最简单的方式是去修改我们的方法拦截器,不过这样会使逻辑变得复杂,且 
不利于维护。还好CGlib给我们提供了方法过滤器(CallbackFilter),CallbackFilte可以明确表明,被代理的类中不同的方法, 
被哪个拦截器所拦截。下面我们就来做个过滤器用来过滤query方法。

public class AuthProxyFilter implements CallbackFilter{
public int accept(Method arg0) {
if(!"query".equalsIgnoreCase(arg0.getName()))
return 0;
return 1;
} }

OK,可能大家会对return 0 or 1感到困惑,用到的时候就会讲解,当然下面就会用到了。 
我们在工场中新增一个使用了过滤器的实例生成方法。

public static TableDAO getAuthInstanceByFilter(AuthProxy authProxy){
Enhancer en = new Enhancer();
en.setSuperclass(TableDAO.class);
en.setCallbacks(new Callback[]{authProxy,NoOp.INSTANCE});
en.setCallbackFilter(new AuthProxyFilter());
return (TableDAO)en.create();
}

cglib 动态代理基础篇的更多相关文章

  1. 【Java入门提高篇】Day12 Java代理——Cglib动态代理

    今天来介绍另一种更为强大的代理——Cglib动态代理. 什么是Cglib动态代理? 我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样 ...

  2. Java基础-CGLIB动态代理

    JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继 ...

  3. jdk动态代理和cglib动态代理底层实现原理详细解析(cglib动态代理篇)

    代理模式是一种很常见的模式,本文主要分析cglib动态代理的过程 1. 举例 使用cglib代理需要引入两个包,maven的话包引入如下 <!-- https://mvnrepository.c ...

  4. Spring源码剖析5:JDK和cglib动态代理原理详解

    AOP的基础是Java动态代理,了解和使用两种动态代理能让我们更好地理解 AOP,在讲解AOP之前,让我们先来看看Java动态代理的使用方式以及底层实现原理. 转自https://www.jiansh ...

  5. CGLib动态代理原理及实现

    JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了.CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采 ...

  6. CGLIB 动态代理的实现

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp92  JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类 ...

  7. Java Proxy和CGLIB动态代理原理

    动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询.测试框架的后端mock.RPC,Java注解对象获取等.静态代理的代理关系在编译时就确定了,而动态代理的代理关 ...

  8. 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

  9. SSM-Spring-10:Spring中cglib动态代理

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 何为动态代理,就不扯皮了,上一篇博客刚刚提到,那cglib动态代理又怎么写,我拿个和上个例子相似的案例来写 具 ...

随机推荐

  1. Erlang中atom的实现

    Erlang的原子(atom)在匹配中有着重要作用,它兼顾了可读性和运行效率. 通过atom,可以实现很多灵活高效的应用. atom可以看作是给字符串生成了一个ID,内部使用的是ID值,必要时可以取出 ...

  2. 微信小程序 HelloWorld

    本篇文章由:http://xinpure.com/micro-applet-helloworld/ 微信官方文档及工具已经开放!!! https://mp.weixin.qq.com/debug/wx ...

  3. 关于ftpshell脚本中mget中去除多余交互式提示的方法

    默认情况下ftp里面的交互式提示是开启的,平常如果下载多个文件时,这种提示很让人烦,如果是在shell脚本里面要从ftp服务器上一次mget多个文件,写个交互式很麻烦,最好是把这个交互式提示关掉. 进 ...

  4. linux内核线程,进程,线程

    http://blog.csdn.net/dyllove98/article/details/8917197 Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起.( ...

  5. 检测到 Mac 文件格式: 请将源文件转换为 DOS 格式或 UNIX 格式

    非常简单可以解决: 方法一,用editplus打开,再复制回VS 方法二:在VS中,点文件->高级保存选项,然后在行尾选项中选择windows(CR LF),重新编译,ok

  6. usb端点(endpoint)知识详解

    stsw-stm32121库中: 把数据copy到对应端点的发送缓冲区后,使能发送状态编码STAT_TX=VALID,这时候usb的该端点就可以发送数据了 ----->即先调用usb_sil.c ...

  7. Maven install 报错: Failed to execute goalorg.apache.maven.plugins:maven-gpg-plugin:1.4:sign (sign-art

    执行 Maven install 时报错: Failed to execute goalorg.apache.maven.plugins:maven-gpg-plugin:1.4:sign (sign ...

  8. JavaScript:零星知识

    1. 关于document.write() 如果在文档已完成加载后执行 document.write,整个HTML 页面将被覆盖. 2. 对代码行进行折行 您可以在文本字符串中使用反斜杠对代码行进行换 ...

  9. 初学 Haskell 练习:算24点

    其中用到了 Monad 做不确定性计算.运行速度很快. -- woodfox, Oct 10, 2014 import Control.Applicative import Control.Monad ...

  10. mysql不重启修改参数变量

    分享下mysql不重启的情况下修改参数变量的方法. 通常来说,更新mysql配置my.cnf需要重启mysql才能生效,但是有些时候mysql在线上,不一定允许你重启,这时候应该怎么办呢? 例子: m ...