Java动态代理

来源:互联网 发布:手机测长度软件 编辑:程序博客网 时间:2024/06/06 13:07

github:https://github.com/changwensir/java-base/tree/master/reflection
创建动态代理
   •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