cglib应用

摘要:
增强器.setSuperclass(cls);publicMyCglibProxy(Stringname){this.name=name;}publicObjectgetDaoBean(Classcls){enhancer.setSuperclass(cls);returnenhancer.create();args);返回结果;

  JDK的动态代理,经常被用来动态地创建对象的代理。JDK的动态代理用起来非常简单,但是有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口,还可以使用cglib包来完成代理。

  cglib的底层通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的代理类。所以基于cglib开发时需要引入cglib的jar包和ASM的jar包。

       下面的例子是基于cglib-2.2.2.jar和asm-all-3.0.jar。

       

        先是一个普通的java类:

package cglib;

public class BookServiceBean {
    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 !");
    }
}

  下面的类将基于cglib为上面的类生成一个代理:

  这个类是重点,getDaoBean将返回一个代理,  enhancer.setSuperclass(cls);指明了为cls生成代理, enhancer.setCallback(this);指明MyCglibProxy为拦截器,
intercept方法将拦截cls中的方法并作处理。

package cglib;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyCglibProxy implements MethodInterceptor {
    
    public Enhancer enhancer = new Enhancer();
    
    private String name;
    
    public MyCglibProxy(String name) {
        this.name = name;
    }
    

    public Object getDaoBean(Class cls) {
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    
    @Override
    public Object intercept(Object object, Method method, Object [ ] args,
            MethodProxy methodProxy) throws Throwable {
        System.out.println("MyCglibProxy is running!");
        Object result = methodProxy.invokeSuper(object, args);        
        return result;
    }
}

  写一个简单的工厂:

package cglib;

public class BookServiceFactory {
    private BookServiceFactory() {
    }
    
    public static BookServiceBean getProxyInstance(MyCglibProxy myProxy){  
        return (BookServiceBean)myProxy.getDaoBean(BookServiceBean.class);  
    } 
}

  写一个模拟的测试:

package cglib;

public class Client {
    
    public static void main(String [ ] args) {        
        BookServiceBean service1 = BookServiceFactory.getProxyInstance(new MyCglibProxy("boss"));  
        service1.create();  
        BookServiceBean service2 = BookServiceFactory.getProxyInstance(new MyCglibProxy("john"));  
        service2.create(); 
        service2.query(); 
    }
}

  上面的例子,只是在调用方法前输出一句话,实际意义不大。

  现在希望只有用户名为boss时才有权限调用方法,否则告诉用户权限不够。

       将MyCglibProxy修改如下:

package cglib;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyCglibProxy implements MethodInterceptor {
    
    public Enhancer enhancer = new Enhancer();
    
    private String name;
    
    public MyCglibProxy(String name) {
        this.name = name;
    }
    

    public Object getDaoBean(Class cls) {
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    
    @Override
    public Object intercept(Object object, Method method, Object [ ] args,
            MethodProxy methodProxy) throws Throwable {
        //用户进行判断
        if (!"boss".equals(name) ) {
            System.out.println("你没有权限!");
            return null;
        }
        System.out.println("MyCglibProxy is running!");
        Object result = methodProxy.invokeSuper(object, args);        
        return result;
    }
}

  运行Client发现运行结果已经不同与上次。

  现在是boss和所有的人都有query方法的权限,可以将MyCglibProxy再做修改:

@Override
    public Object intercept(Object object, Method method, Object [ ] args,
            MethodProxy methodProxy) throws Throwable {
        //用户进行判断
        if (!"boss".equals(name) && !method.getName().equals("query")) {
            System.out.println("你没有权限!");
            return null;
        }
        System.out.println("MyCglibProxy is running!");
        Object result = methodProxy.invokeSuper(object, args);        
        return result;
    }

免责声明:文章转载自《cglib应用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[转]C/C++实现回调机制的几种方式(回调、槽、代理)CentOS7 监控网络流量下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vim 基本使用

vim 下基本命令 重新加载 .vimrc source ~/.vimrc 列出当前缓冲区的所有文档 ls 然后使用 b+编号 移至该文档 选中多行 v + shift 然后 j k 上下移动 缩进单行 >> << 当前行到结尾都缩进 >G 重复上次的修改(移动不算修改) ....

OGNL表达式入门

package com.scorpion.ognl; import java.util.ArrayList; import java.util.List; import ognl.Ognl; import ognl.OgnlContext; import ognl.OgnlException; public class OgnlTest {...

java Spring 使用thrift

  1.下载对应的thrift客户端 编写test.thrift参数   将客户端exe文件盒test.thrift文件放在同一个地方    生成service  (thrift-0.9.2.exe --gen java test.thrift)   ps 生成service过程   1.      2.   3.生成的列表         4.将生成的s...

SQL Server中行列转换 Pivot UnPivot 【转】

SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P 完整语法: table_source PIVOT( 聚合函数(value_column) FO...

yolov3输出检测图片位置信息

前言我们在进行图片识别后需要进行进一步的处理,该文章会介绍:1.怎样取消lables;2.输出并保存(.txt)标记框的位置信息 一.去掉label 在darknet/src/image.c 收索draw_detections_v3 .在该函数对应目录下进行修改。   二.目标定位(Object localization)框的数据信息 以图片左上角为(...

log4j(转)

让System.out.println回家种田,换句话说,就是该干嘛干嘛去。 您可能在想: System.out.println几乎在每个Java程序里都有那么几行,如何让他老人家回家种田呢? 我们怎么能少了这么重要的革命同志呢? doodoofish这里要说的是"该干嘛干嘛去",不是System.out.println管的就别让他管。想想,我们用Syst...