zoukankan      html  css  js  c++  java
  • cglib 动态代理基础篇

    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();
    }
  • 相关阅读:
    多重背包POJ1276不要求恰好装满 poj1014多重背包恰好装满
    哈理工1053完全背包
    求最小公倍数与最大公约数的函数
    Bus Pass ZOJ 2913 BFS 最大中取最小的
    POJ 3624 charm bracelet 01背包 不要求装满
    HavelHakimi定理(判断一个序列是否可图)
    z0j1008Gnome Tetravex
    ZOJ 1136 Multiple BFS 取模 POJ 1465
    01背包 擎天柱 恰好装满 zjut(浙江工业大学OJ) 1355
    zoj 2412 水田灌溉,求连通分支个数
  • 原文地址:https://www.cnblogs.com/daxin/p/3352901.html
Copyright © 2011-2022 走看看