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. How to forcefully delete a daemonset or a pod in kubernetes cluster

    I have setup a kubernetes cluster which is working fine. I created deployment with type as daemonset ...

  2. Ubuntu用户root密码设置

    我们在安装Ubuntu后发现个问题,就是不像Linux系统那样会在安装过程中设置root的密码,那以后如果需要root的权限时该如何操作呢? Ubuntu里有个命令叫sudo,是以管理员的身份运行命令 ...

  3. [Python]网络爬虫(五):urllib2的使用细节与抓站技巧(转)

    1.Proxy 的设置 urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy. 如果想在程序中明确控制 Proxy 而不受环境变量的影响,可以使用代理. 新建test ...

  4. SpringBoot优化内嵌的Tomcat ---设置MaxConnections

    使用kill -9杀掉springboot应用后,立马java -jar重启,会报错,需要等待一段时间才能启动成功,报错的原因是:/tmp/tomcat-docbase.474979491043437 ...

  5. 理解over()函数

    1.1.两个order by的执行时机分析函数(以及与其配合的开窗函数over())是在整个sql查询结束后(sql语句中的order by的执行比较特殊)再进行的操作, 也就是说sql语句中的ord ...

  6. 【转】一个对 Dijkstra 的采访视频

    一个对 Dijkstra 的采访视频 (也可以访问 YouTube 或者从源地址下载 MPEG1,300M) 之前在微博上推荐了一个对 Dijkstra 的采访视频,看了两遍之后觉得实在很好,所以再正 ...

  7. HDU 5092 DP

    DP水题 求从上到下走完,使所取得权值最小,并输出路径,若有多个满足,则输出靠右的 #include "stdio.h" #include "string.h" ...

  8. PHP利用MySQL保存session(php5.4之前的处理)

    简介 使用MySQL保存session,需要保存三个关键性的数据:session id.session数据.session生命期. 考虑到session的使用方式,没必要使用InnoDB引擎,MyIS ...

  9. 在为shader program pass uniform之前一定要先use program。

    在为shader program pass uniform之前一定要先use program.

  10. 使用配置hadoop中常用的Linux(ubuntu)命令

    生成key: $ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa $ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized ...