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

 

posted @   大新博客  阅读(407)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示