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();

}

 

你可能感兴趣的:(cglib)