Java之jdk和CGLib實現(xiàn)動態(tài)代理

1 jdk實現(xiàn)動態(tài)代理源碼實現(xiàn)

這里需要用到InvocationHandler接口

    public interface Hello {
        public void sayHello();
    }

    public class HelloImpl implements Hello {
     
        @Override
        public void sayHello() {
            System.out.println("hello word");
        }
    }

 
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
     
    public class HelloInvocationHandler implements InvocationHandler{
        
        private Object object;
        
        PeopleInvocationHandler(Object object){
            this.object = object;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println("-------- start ---------");
            Object invoke = method.invoke(people, args);
            System.out.println("-------- end ---------");
            return invoke;
        }
    }

    import java.lang.reflect.Proxy;
     
    public class Test {
        public static void main(String[] args) {
            HelloImpl hello = new HelloImpl();
            HelloInvocationHandler invocationHandler = new HelloInvocationHandler(hello);
            Hello proxy = (Hello) Proxy.newProxyInstance(HelloImpl.getClass().getClassLoader(), HelloImpl.getClass().getInterfaces(), invocationHandler);
            proxy.sayHello();
        }
    }

 
2 CGLib實現(xiàn)動態(tài)代理源碼實現(xiàn)

這里需要用到MethodInterceptor接口和Enhancer

    public class Hello {
     
        public Hello() {
            System.out.println("Hello...");
        }
     
        public void print() {
            System.out.println("hello word");
        }
    }

    public class CglibProxyIntercepter implements MethodInterceptor {
        @Override
        public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            //對目標方法進行攔截處理
            System.out.println("before...");
            Object object = methodProxy.invokeSuper(sub, objects);
            System.out.println("after...");
            return object;
        }
    }

    public class Test {
        public static void main(String[] args) {
            //創(chuàng)建加強器,用來創(chuàng)建動態(tài)代理類
            Enhancer enhancer = new Enhancer();
            //為加強器指定要代理的業(yè)務類
            enhancer.setSuperclass(Hello.class);
            //設(shè)置回調(diào)
            enhancer.setCallback(new CglibProxyIntercepter());
            //創(chuàng)建代理對象
            Hello proxy= (Hello) enhancer.create();
            proxy.print();
        }
    }

 result

    before...
    hello word
    after...


 
3 對比jdk實現(xiàn)動態(tài)代理CGLib實現(xiàn)動態(tài)代理
1)、JDK

 內(nèi)部主要是通過反射來實現(xiàn)。

 
2)、CGLib

CGLib是依靠asm字節(jié)碼處理框架實現(xiàn)的高性能Code生成類庫,可以在運行時擴展Java類或者實現(xiàn)接口?當然可以,CGLib對用戶隱藏了asm復雜的內(nèi)部實現(xiàn),提供了Developer友好、面向特定功能的實現(xiàn),比如方法攔截(Interpreter)、懶加載(Lazyloader & Dispatcher)等,AOP中的方法攔截,Hibernate中的延遲加載都利用了CGLib

特點:可以不通過接口實現(xiàn)動態(tài)代理的優(yōu)點之外,還有處理速度快、效率高的優(yōu)點!因為生成代碼比Java反射的速度要快很多.




作者:chen.yu
深信服三年半工作經(jīng)驗,目前就職游戲廠商,希望能和大家交流和學習,
微信公眾號:編程入門到禿頭 或掃描下面二維碼
零基礎(chǔ)入門進階人工智能(鏈接)