• 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();
    }
  • 相关阅读:
    JavaScript中get和set访问器的实现
    Vue render 函数和JSX语法的使用
    vue项目将第三方包以cdn的方式引入页面不显示
    今天帮忙HMF这位ui大神(傻)解决的小问题。
    SET
    webpack 折腾
    sass折腾
    gulp折腾
    css3
    js递归函数
  • 原文地址:https://www.cnblogs.com/daxin/p/3352901.html
Copyright © 2020-2023  润新知