美文网首页
浅谈Java代理二:Cglib动态代理-MethodInterc

浅谈Java代理二:Cglib动态代理-MethodInterc

作者: 氨基钠 | 来源:发表于2019-11-17 14:22 被阅读0次

    CGLib动态代理特点:
    使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

    示例业务逻辑:
    1-有一个明星叫胡歌(class HuGe)

    3-找明星做事情需要经过助理(ProxyFactory )

    4-如果要找胡歌唱歌、演戏,需要先找助理,然后助理去找胡歌唱歌、演戏(class testProcyFactory)

    1-被代理类(没有实现任何接口)

    package com.huishe.testOfSpring.methodinterceptor;
    
    public class HuGe {
    
        public void sing(String song) {
            System.out.println("胡歌演唱: " + song);
        }
    
        public String act(String teleplay) {
            System.out.println("胡歌决定出演电视剧: " + teleplay);
            return "胡歌答应出演电视剧: " + teleplay;
        }
    }
    

    2-代理工厂(即创建代理的通用写法)

    package com.huishe.testOfSpring.methodinterceptor;
    
    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 ProxyFactory implements MethodInterceptor{
        //要代理的原始对象
        private Object object;
        
        //1-创建代理对象
        public Object createProcy(Object target){
            this.object = target;
            //1-Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展
            Enhancer enhancer=new Enhancer();  
            //2-将被代理类HuGe设置成父类
            enhancer.setSuperclass(this.object.getClass());  
            //3-设置拦截器
            enhancer.setCallback(this);  
            //4-动态生成一个代理类
            Object objProxy = enhancer.create();  
            
            return objProxy;
            
        }
        
        //2-实现MethodInterceptor的intercept方法
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("before: " + method);
            //调用proxy.invoke()方法,会报java.lang.StackOverflowError错误,原因是invoke()内部会一直被反复调用
            //Object object = proxy.invoke(obj, args);
            Object object = proxy.invokeSuper(obj, args);
            System.out.println("after: " + method);
            return object;
        }
    }
    

    3-进行测试

    package com.huishe.testOfSpring.methodinterceptor;
    
    import org.junit.Test;
    
    import net.sf.cglib.proxy.Enhancer;
    
    public class cglibMethodInterceptorTest {
    
        @Test
        public void testProcyFactory(){
            //1-实例化需要被代理的类
            HuGe huGe = new HuGe();
            //2-实例化代理工厂
            ProxyFactory cglibProxy = new ProxyFactory();
            //3-动态生成一个代理类,并从Object强制转型成父类型HuGe
            HuGe hg =(HuGe)cglibProxy.createProcy(huGe);
            
            //4-执行动态代理类的方法
            hg.sing("逍遥叹");
            hg.act("琅琊榜");
            
        }
        
    }
    

    4-测试结果

    日志输出:
    
    before: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
    胡歌演唱: 逍遥叹
    after: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
    before: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)
    胡歌决定出演电视剧: 琅琊榜
    after: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)
    

    相关文章

      网友评论

          本文标题:浅谈Java代理二:Cglib动态代理-MethodInterc

          本文链接:https://www.haomeiwen.com/subject/mbupictx.html