天天看点

3.7 设计模式-代理模式1.简介

1.简介

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用

2.静态代理

2.1 概念

静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件。需要代理对象和目标对象实现一样的接口。

  • 优点:可以在不修改目标对象的前提下扩展目标对象的功能。
  • 缺点:冗余。由于代理对象要实现与目标对象一致的接口,会产生过多的代理类。不易维护。一旦接口增加方法,目标对象与代理对象都要进行修改。

2.2案例

public interface ITask {
    void dispatchTask();
}

/**
 * 老板
 */
public class Boss implements ITask {

    private static final String TAG = "Boss";


    @Override
    public void dispatchTask() {
        Log.d(TAG, "dispatchTask: ");
    }
}


/**
 * 秘书
 */
public class Secretary implements ITask {

    Boss  realObj;
    public Secretary( Boss  realObj) {
        this.realObj = realObj;
    }

    @Override
    public void dispatchTask() {

    }
}
 
           

调用

Boss boss = new  Boss();
        final Secretary proxyObj = new Secretary(boss);
        proxyObj.dispatchTask();
           

3.动态代理

动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。

JDK提供了代理对象:

  • java.lang.reflect Proxy,主要方法为
static Object    newProxyInstance(
	ClassLoader loader,  //指定当前目标对象的类加载器
	Class<?>[] interfaces,    //目标对象实现的接口的类型
	InvocationHandler h      //事件处理器
) 
//返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
           
  • java.lang.reflect InvocationHandler,主要方法为
Object  invoke(Object proxy, Method method, Object[] args) 
// 在代理实例上处理方法调用并返回结果。
           

3.1 案例

public interface IUserDao {
      void save();
}

public class UserDao implements IUserDao{

    @Override
    public void save() {
        System.out.println("保存数据");
    }
}

public class ProxyFactory {
    private Object target;// 维护一个目标对象

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

    // 为目标对象生成代理对象
    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 returnValue = method.invoke(target, args);

                        System.out.println("提交事务");
                        return null;
                    }
                });
    }
}
           
IUserDao target = new UserDao();
 System.out.println(target.getClass());  //输出目标对象信息
 IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
 System.out.println(proxy.getClass());  //输出代理对象信息
 proxy.save();  //执行代理方法