cglib应用

  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;
    }
原文地址:https://www.cnblogs.com/lnlvinso/p/4240350.html