Java动态代理

   • Proxy 提供用于创建动态代理类和代理对象的静态方法 , 它也是所有动态代理类的父类 .
   • Proxy 提供了两个方法来创建动态代理类和动态代理实例
使用动态代理实现 AOP
    • AOP(Aspect OrientProgram, 面向切面编程 )


public class ProxyTest {

    @Test
    public void testProxy() {
        final IArithmeticCalculator arithmeticCalculator = new ArithemeticCalculatorImpl();
        /**
         * Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
         *
         * ClassLoader: 由动态代理产生的对象由哪个类加载器来加载,通常情况下和被代理对象使用一样的类加载器
         * Class<?>[]: 由动态代理产生的对象必须需要实现的接口的Class 数组
         * InvocationHandler: 当具体调用代理对象的方法时,将产生什么行为
         */
        IArithmeticCalculator proxy1 =
                (IArithmeticCalculator) Proxy.newProxyInstance(
                        arithmeticCalculator.getClass().getClassLoader(),
                        new Class[]{IArithmeticCalculator.class},
                        new InvocationHandler() {
                            /**
                             * @param proxy
                             * @param method 正在被调用的方法
                             * @param args 调用方法时传入的参数
                             *   Arrays.asList()将一个数组转化为一个List对象,这个方法会返回一个ArrayList类型的对象,
                            这个ArrayList类并非java.util.ArrayList类,而是Arrays类的静态内部类!
                            用这个对象对列表进行添加删除更新操作,就会报UnsupportedOperationException异常。
                             */
 //                           @Override
                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                System.out.println("The method " + method.getName() + " begins with " + Arrays.asList(args));
                                //调用被代理类的目标方法
                                Object result = method.invoke(arithmeticCalculator, args);

                                System.out.println("The method " + method.getName() + " ends with " + result);
                                return result;
                            }

                        });

        proxy1.mul(1, 2);  //he method mul ends with null 原因是Mul没有返回值
 //       int result = proxy1.add(2, 5);
 //       System.out.println(result);
    }

    /**
     * 关于动态代理的细节
     * 1、需要一个被代理的对象
     * 2、类加载器通常是和被代理对象使用相同的类加载器
     * 3、一般的,Proxy.newInstance()的返回值是一个被代理对象实现的接口的类型;当然也可以是其它的接口的类型
     *   注意:第二个参数,必须是一个接口类型的数组
     *   提示:若代理对象不需要额外实现被代理对象实现的接口以外的接口,可以使用target.getClass().getInterfaces(),
     *
     * 4、InvocationHandler通常使用匿名内部类的方式:被代理对象需要是final类型的,定义常量,可能方法实现完了,但对象还在被使用
     * 5、InvocationHandler的invoke方法中的第一个参数Object类型的proxy
     *    指的是正下被返回的那个代理对象,一般情况下不使用
     */
    @Test
    public void testProxy2() {
        //1、创建一个被代理的对象
        final IArithmeticCalculator target = new ArithemeticCalculatorImpl();
        System.out.println(Arrays.asList(target.getClass().getInterfaces())); //[interface com.changwen.java.dynamicProxy.IArithmeticCalculator]

        Object proxy1 = Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                // new Class[]{IArithmeticCalculator.class, Validator.class},
                target.getClass().getInterfaces(),
                new InvocationHandler() {
 //                   @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        return method.invoke(target,args);
                    }
                });

        IArithmeticCalculator proxy2 = (IArithmeticCalculator) proxy1;
        proxy2.mul(5, 2);

    }
}



















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值