java 代理模式二:动态代理

    java动态代理:

java动态代理类位于java.lang.reflect包下,一般主要涉及两个类:  1.Interface InvocationHandler  

    该接口中仅定义了一个方法:Object invoke(Object proxy,Method method,Object[] args)

    第一个参数obj一般是代理类,method是被代理的方法,如上例中的request(),  args是该方法中的参数数组,无参是为null

    这个抽象方法在代理类中动态实现。

  2.Proxy

    protected  Proxy(InvocationHandler h): 构造函数,用于给内部的invocation handler赋值。

    static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) : loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

    static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)  :

                      返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类在Subject接口中声明过的方法)。

实例1:

  定义一个接口

/*
* 抽象角色类
* 定义一个接口
*/
public interface Subject {
public void request();
}

  定义真实角色类,实现接口

/*
* 真实角色类
*/
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("From real subject");
} }

  定义动态代理类,实现InvocationHandler接口,重写invoke方法

/*
* 动态代理类,实现InvocationHandler接口,重写invoke方法
*/
public class DynamicSubject implements InvocationHandler { //对真实类的对象的引用
private Object sub;
public DynamicSubject(Object obj){
this.sub = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Before calling " + method); //通过反射来调用方法
method.invoke(sub, args);
System.out.println("After calling " + method);
return null;
}
}

  测试

public class Client {

    public static void main(String[] args) {

        //真实类对象
RealSubject realSubject = new RealSubject(); //通过 动态类对象 获取类型
InvocationHandler handle = new DynamicSubject(realSubject);
Class<?> classType = handle.getClass(); //生成代理
//动态生成一个类 实现了指定的接口 生成类的对象 转换成接口类型 handle是动态代理类的一个对象
Subject subject = (Subject)Proxy.newProxyInstance(classType.getClassLoader(),
realSubject.getClass().getInterfaces(), handle); subject.request(); System.out.println(subject.getClass());
}
}

通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。

  

上一篇:MySQL高可用主从复制部署


下一篇:在ubuntu16.04+python3.5情况下安装nltk,以及gensim时pip3安装不成功的解决办法