Java动态代理

静态代理的优点:拓展函数功能。

静态代理的缺点:如果接口中加了方法,既需要对目标对象类进行维护又要对代理对象类维护,维护工作较多,不过灵活,另外代理类一多,就需要建立很多类。

动态代理以一代多,灵活处理。

1、创建ComInterface 接口

package cn.ecut.test.utils;

public interface ComInterface {
    void sayHi();
}

  

2、创建代理工厂类

package cn.ecut.test.utils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class ProxyFactory {

    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     * 返回一个指定接口的代理类实例
     * @return
     */
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @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;
                    }
                });
    }
}

 说明:代理工厂类必须要有一个Object 属性来接收目标对象,一个getProxyInstance()返回代理对象实例的方法。

其中的  InvocationHandler 是一个接口,此处是利用匿名内部函数的好处(当只需要创建一个对象的时候使用匿名内部函数),new InvocationHandler(){...} 是一个匿名函数的使用

返回的是一个实例化InvocationHandler接口的对象。这就是为什么能在这个接口面前使用new关键字。

3、目标对象

package cn.ecut.test.utils;

public class TargetObject implements ComInterface{
    @Override
    public void sayHi() {
        System.out.println("-----很高兴见到你!-----");
    }
}

4、调试类

package cn.ecut.test.utils;

public class ProxyTest {
    public static void main(String[] args) {
        ComInterface target = new TargetObject();
        ComInterface proxy = (ComInterface) new ProxyFactory(target).getProxyInstance();
        proxy.sayHi();
    }
}

  

5、测试结果

Java动态代理

6、总结:

  通过创建代理工厂来管理所有的代理类,减少代码冗余,当哪个类中哪个方法需要拓展功能就可以通过这种方法来解决了。

在创建动态工厂的时候需要注意:1、必须要一个接收目标对象的属性 Object  target

                                                2、一个返回代理对象的方法 getProxyInstance()