JDK动态代理机制

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * JDK动态代理
 */
public class JdkProxyTest {
    //定义一个接口
    public interface Hello {
        public void sayHello();
    }
    //接口实现
    public static class HelloImpl implements Hello {
        public void sayHello() {
            System.out.println("Hello world!!");
        }
    }
    //第一种采用构造方法模式
    public static class JdkInvocationHandler1 implements InvocationHandler {
        //真实对象
        private Object target;
        public JdkInvocationHandler1(Object target) {
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("------进入代理之前-------------");
            Object obj = method.invoke(target, args);
            System.out.println("------进入代理之后-------------");
            return obj;
        }
    }
    //第二种采用普通方法模式
    public static class JdkInvocationHandler2 implements InvocationHandler {
        //真实对象
        private Object target;
        /**
         * 第一步:建立代理对象与真实对象的代理关系,并返回代理对象
         * @param target 真实对象
         * @return 代理对象
         */
        public Object bind(Object target) {
            this.target = target;
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(), this);

         /***

通过 Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), this);建立了代理对象与真实对象的关系,第一个参数是类加载器,这里我们传入的就是HelloImpl的类加载器,第二个参数是动态代理对象下挂那些接口,这里就是Hello接口,这个参数的类型是Class<?>[],第三个参数是实现代理方法逻辑的实现类,也就是invoke方法的实现类,所以这里就是this。

通过invoke(Object proxy, Method method, Object[] args)实现了代理逻辑,第一个参数是代理对象,也就是bind方法返回的对象,第二个参数是当前调度的方法,args是调度方法的参数。这里其实是用到了JAVA反射方法的机制,实现代理对象到真实对象方法的调用。

       */
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("------进入代理之前-------------");
            Object obj = method.invoke(target, args);
            System.out.println("------进入代理之后-------------");
            return obj;
        }
    }
    public static void main(String[] args) {
        /**
         *     1.通过实现InvocationHandler接口来自定义自己的InvocationHandler;
            2.通过Proxy.getProxyClass获得动态代理类
            3.通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
            4.通过构造函数获得代理对象并将自定义的InvocationHandler实例对象传为参数传入
            5.通过代理对象调用目标方法
         */
        //生成动态代理类
        Class<?> clazz = Proxy.getProxyClass(Hello.class.getClassLoader(), Hello.class);
        try {
            //获得代理类的构造函数,并传入参数类型InvocationHandler.class
            Constructor<?> constructor = clazz.getConstructor(InvocationHandler.class);
            //通过构造函数来创建动态代理对象,将自定义的InvocationHandler实例传入
            Hello hello = (Hello) constructor.newInstance(new JdkInvocationHandler1(new HelloImpl()));
            //通过代理对象调用目标方法
            hello.sayHello();
        } catch (Exception e) {
            e.printStackTrace();
        }
        /**
         * Proxy类中还有个将2~4步骤封装好的简便方法来创建动态代理对象,
         * 其方法签名为:newProxyInstance(ClassLoader loader,
         *             Class<?>[] instance, InvocationHandler h)
         */
        Hello helloImpl1=(Hello)Proxy.newProxyInstance(HelloImpl.class.getClassLoader(), HelloImpl.class.getInterfaces(), new JdkInvocationHandler1(new HelloImpl()));
        //通过代理对象调用目标方法
        helloImpl1.sayHello();
        /**---------------------------------------------------------------------*/
        JdkInvocationHandler2 jdkInvocationHandler2=new JdkInvocationHandler2();
        Hello helloImpl=(Hello) jdkInvocationHandler2.bind(new HelloImpl());
        //通过代理对象调用目标方法
        helloImpl.sayHello();
    }
}

输出------进入代理之前-------------
Hello world!!
------进入代理之后-------------
------进入代理之前-------------
Hello world!!
------进入代理之后-------------
------进入代理之前-------------
Hello world!!
------进入代理之后-------------

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值