zoukankan      html  css  js  c++  java
  • 重学JAVA基础(三):动态代理

    1.接口

    public interface Hello {
    
        public void sayHello();
    }

    2.实例类

    public class Hello2 {
        public void sayHello() {
            System.out.println("hello world2!");
        }
    }
    public class Hello3 extends Hello2{
        
    }
    public class HelloImpl implements Hello{
    
        @Override
        public void sayHello() {
            System.out.println("hello world!");
        }
    }

    3.JDK动态代理

    ublic class JdkTest implements InvocationHandler{
        
        private Object object;
        
        @SuppressWarnings("unchecked")
        public <T> T bind(Object obj){
            this.object = obj;
            return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println("before sayHello");
            method.invoke(object, null);
            System.out.println("after sayHello");
            return null;
        }
        
        public static void main(String[] args) {
            JdkTest test = new JdkTest();
            Hello hello = test.bind(new HelloImpl());
            hello.sayHello();
        }
    
    }

    4.cglib动态代理

    public class CglibTest implements MethodInterceptor{
        
        private Object obj;
        
        /**
         * 普通接口类代理
         * @author tomsnail
         * @date 2015年4月2日 上午10:36:10
         */
        public <T> T instance(T obj){
            this.obj = obj;
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(this.obj.getClass());
            enhancer.setCallback(this);
            return (T)enhancer.create();
        }
    
        @Override
        public Object intercept(Object arg0, Method arg1, Object[] arg2,
                MethodProxy arg3) throws Throwable {
            System.out.println("before sayHello");
            arg3.invoke(obj, arg2);
            System.out.println("after sayHello");
            return null;
        }
        
        /**
         * 无接口类代理
         * @author tomsnail
         * @date 2015年4月2日 上午10:35:58
         */
        public <T> T instanceObject(T obj){
            T t = (T)Enhancer.create(obj.getClass(),new MethodInterceptor(){
    
                @Override
                public Object intercept(Object arg0, Method arg1, Object[] arg2,
                        MethodProxy arg3) throws Throwable {
                    System.out.println("hello2 proxy");
                    return arg3.invokeSuper(arg0, arg2);
                }
                
            });
            return t;
            
        }
        
        /**
         * 无接口类代理
         * @author tomsnail
         * @date 2015年4月2日 上午10:35:58
         */
        public <T> T instanceSuperObject(T obj){
            T t = (T)Enhancer.create(obj.getClass(),NoOp.INSTANCE);//无任何代理时,调用父类方法实现
            return t;
            
        }
        
        public static void main(String[] args) {
            CglibTest test = new CglibTest();
            Hello hello = test.instance(new HelloImpl());
            hello.sayHello();
            Hello2 hello2 = test.instanceObject(new Hello2());//无接口类的动态代理
            hello2.sayHello();
            
            Hello2 hello3 = test.instanceSuperObject(new Hello3());//子类没有重写父类方法的动态代理
            hello3.sayHello();
            
        }
    
    }

    5.小小总结一下

    JDK的动态代理只能通过接口进行处理,如果没有接口的,会很难处理。cglib没有这一限制。

    还有就是性能,我看见一篇网上已经有了对比,在jdk7/8与cglib相比,反而jdk的性能很好,见http://www.cnblogs.com/haiq/p/4304615.html

  • 相关阅读:
    使用virtualenv搭建python3的环境
    Linux/unix inode
    转:进程间通信方式
    保研复试上机——数据库
    转:mysql grant
    mysql 查询结果创建表
    279. Perfect Squares
    Mybatis中javaType和jdbcType对应和CRUD例子
    mysql explain
    91. Decode Ways
  • 原文地址:https://www.cnblogs.com/TomSnail/p/4386566.html
Copyright © 2011-2022 走看看