zoukankan      html  css  js  c++  java
  • Java动态代理 ----- jdk代理与cglib代理

    1、jdk代理

    针对接口进行代理,接口可以没有方法, InvocationHandler会拦截所有方法,不过好像意义不大....只能执行Object类的方法,执行结果有点奇怪...

    package test;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class TestJdkProxy {
    
        public static void main(String[] args) {
    
            //接口的实例对象,这里用的匿名对象
            Test test = new Test() {
            };
    
            //拦截类
            InvocationHandler invocationHandler = new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //proxy为实际创建的代理类, method为代理类执行的方法, args为方法调用对应的参数
    
                    System.out.println("代理前");
                    Object object = method.invoke(test, args);
                    System.out.println("代理后");
    
                    return object;
                }
            };
    
            Test proxy = (Test) Proxy.newProxyInstance(test.getClass().getClassLoader(),
                    test.getClass().getInterfaces(), invocationHandler);
    
            System.out.println("-------------------------------");
            System.out.println(proxy.equals(proxy));  // ? 有点奇怪,  是false
            System.out.println("-------------------------------");
            System.out.println(Integer.toHexString(proxy.hashCode()));
            System.out.println("-------------------------------");
            System.out.println(proxy.toString());  // Object类的toString方法调用了一次hashCode方法,  toString方法和hashCode方法只拦截了一次?
        }
    
        public interface Test {
    
        }
    
    }

    输出为:

    -------------------------------
    代理前
    代理后
    false
    -------------------------------
    代理前
    代理后
    61bbe9ba
    -------------------------------
    代理前
    代理后
    test.TestJdkProxy$1@61bbe9ba

    接口有方法情况:

    package test;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class TestJdkProxy {
    
        public static void main(String[] args) {
    
            //接口的实例对象,这里用的匿名对象
            Test test = new Test() {
                @Override
                public void test() {
                    System.out.println("执行代理的接口方法");
                }
            };
    
            //拦截类
            InvocationHandler invocationHandler = new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //proxy为实际创建的代理类, method为代理类执行的方法, args为方法调用对应的参数
    
                    System.out.println("代理前");
                    Object object = method.invoke(test, args);
                    System.out.println("代理后");
    
                    return object;
                }
            };
    
            Test proxy = (Test) Proxy.newProxyInstance(test.getClass().getClassLoader(),
                    test.getClass().getInterfaces(), invocationHandler);
            proxy.test();
        }
    
        public interface Test {
            void test();
        }
    
    }

    输出为

    代理前
    执行代理的接口方法
    代理后

    2、cglib代理

    代理类不能为final 类,

    maven引入jar包

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </dependency>
    package test;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class TestCglibProxy {
    
        public static void main(String[] args) throws Exception {
    
            MethodInterceptor handler = new MethodInterceptor() {
                @Override
                public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    //proxy为创建的代理类, 我的理解是对需要代理的类进行了继承(?), 所以需要代理的类不能为final类
    
                    System.out.println("代理前");
                    Object result = methodProxy.invokeSuper(proxy, objects);
                    System.out.println("代理后");
                    return result;
                }
            };
    
            Enhancer enhancer = new Enhancer();
            //设置需要代理的类,不能是final类
            enhancer.setSuperclass(Test.class);
            //设置方法拦截
            enhancer.setCallback(handler);
            //创建代理类,根据Test构造方法所需要的参数指定create参数, 如本例中Test类有String参数构造方法
            Test test = (Test) enhancer.create(new Class[]{String.class}, new Object[]{"Aa"});
            test.test();
            System.out.println("-------------------------------");
            test = (Test) enhancer.create();
            test.test();
            System.out.println("-------------------------------");
            //对代理类的方法都会进行拦截,  Object类的toString方法调用了一次hashCode方法,  toString方法和hashCode方法都进行了拦截
            System.out.println(test.toString());
            System.out.println("-------------------------------");
            System.out.println(test.equals(test));
        }
    
        public static class Test {
    
            private String str;
    
            public void test() {
                System.out.println("test : " + str);
            }
    
            public Test() {
    
            }
    
            public Test(String string) {
                str = string;
            }
    
        }
    
    }

    输出为

    代理前
    test : Aa
    代理后
    -------------------------------
    代理前
    test : null
    代理后
    -------------------------------
    代理前
    代理前
    代理后
    代理后
    test.TestCglibProxy$Test$$EnhancerByCGLIB$$d7a97ec4@7506e922
    -------------------------------
    代理前
    代理后
    true
  • 相关阅读:
    自考 exec 7 3
    画函数图像
    Exec68
    applet main共存 五角星和五面形
    jcheckbox 用例
    JList 单击 ,双击例
    web性能优化(一)弱请求处理
    web性能优化(二)优化思维图
    算法之道左右旋转字符串
    腾讯微信面试题实现时间复杂度为O(1)的栈 20130226
  • 原文地址:https://www.cnblogs.com/wushengwuxi/p/11897618.html
Copyright © 2011-2022 走看看