• 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;
        }
  • 相关阅读:
    面试官本拿求素数搞我,但被我用素数筛优雅的“回击“了
    手写玩具
    【LeetCode】5638.吃苹果的最大数目
    【LeetCode】290.单词规律(双映射)
    【LeetCode】42.接雨水
    【LeetCode】84.柱状图中最大的矩形
    【LeetCode】135.分发糖果
    【Leetcode】746.使用最小花费爬楼梯
    【LeetCode】316.去除重复字母
    【LeetCode】三题解决常见异或运算题
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/4240350.html
Copyright © 2020-2023  润新知