设计模式之代理模式

2019-05-03  本文已影响0人  古月沧澜

动态代理

含义:

动态代理是个通用框架,主要处理审计的问题,就是面向切面编程,在不改变代码结构的基础上,增加和控制对象的行为。

类图:

通用类:

1.抽象主题:动态代理只能代理接口,必须有实现类.

/**抽象主题
 * Created by Administrator on 2019/5/2.
 */
public interface Subject {
    void doSomething();
}

2.具体主题

/**真实主题
 * Created by Administrator on 2019/5/2.
 */
public class RealSubject implements Subject {
    @Override
    public void doSomething() {

    }
}

3.请求处理器

/**请求处理器
 * Created by Administrator on 2019/5/2.
 */
public class MynvocationHandler implements InvocationHandler {
    private Object obj;

    public MynvocationHandler(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(obj, args);
        return result;
    }
}

4.动态代理类

/**动态代理
 * Created by Administrator on 2019/5/2.
 */
public class DynamicProxy<T> {

    /**<T> 用来申明这是一个泛型方法,跟编译器说T是一个泛型占位符,我存什么类型,他就是什么类型,而不是其他的东西,比如类名,T可能是别的类的类名。
     * */
    public static <T> T newInstance(ClassLoader classLoader,Class<?>[] interfaces ,
    InvocationHandler invocationHandler){
        if(true){
            IAdvice advice=new Advice();
            advice.advice();
        }
        return (T)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }
}
/**
 * Created by Administrator on 2019/5/3.
 */
public class SubjectDynamicProxy extends DynamicProxy {

    /**<T> ,只是泛型声明,用来申明这是一个泛型方法,跟编译器说T是一个泛型占位符,我存什么类型,他就是什么类型,而不是其他的东西,比如类名,T可能是别的类的类名。
     * */
    public static <T> T newInstance(Subject subject){
        ClassLoader classLoader = subject.getClass().getClassLoader();
        Class<?>[] interfaces = subject.getClass().getInterfaces();
        InvocationHandler invocationHandler=new MynvocationHandler(subject);
        return (T) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }

}

5.通知接口

/**通知接口,织入进来
 * Created by Administrator on 2019/5/2.
 */
public interface IAdvice {
    void advice();
}

6.具体通知

/**通知实现接口
 * Created by Administrator on 2019/5/2.
 */
public class Advice implements IAdvice {
    @Override
    public void advice() {
        System.out.println("前置通知");
    }
}

相关资料整理

1.相关类
一.相关类及其方法:

java.lang.reflect.Proxy,

Proxy 提供用于创建动态代理类和实例的静态方法.

newProxyInstance()

返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序

(详见api文档)

java.lang.reflect.InvocationHandler,

InvocationHandler 是代理实例的调用处理程序 实现的接口。

invoke()

在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。

(详见api文档)
2.Proxy源码:
1.  public static Object newProxyInstance(ClassLoader loader,  
2.  Class<?>[] interfaces,  
3.  InvocationHandler h)  
4.  throws IllegalArgumentException  
5.  {  
6.  if (h == null) {  
7.  throw new NullPointerException();  
8.  }  

10.  /* 
11.  * Look up or generate the designated proxy class. 
12.  */  
13.  Class cl = getProxyClass(loader, interfaces);  

15.  /* 
16.  * Invoke its constructor with the designated invocation handler. 
17.  */  
18.  try {  
19.  /* 
20.  * Proxy源码开始有这样的定义: 
21.  * private final static Class[] constructorParams = { InvocationHandler.class }; 
22.  * cons即是形参为InvocationHandler类型的构造方法 
23.  */  
24.  Constructor cons = cl.getConstructor(constructorParams);  
25.  return (Object) cons.newInstance(new Object[] { h });  
26.  } catch (NoSuchMethodException e) {  
27.  throw new InternalError(e.toString());  
28.  } catch (IllegalAccessException e) {  
29.  throw new InternalError(e.toString());  
30.  } catch (InstantiationException e) {  
31.  throw new InternalError(e.toString());  
32.  } catch (InvocationTargetException e) {  
33.  throw new InternalError(e.toString());  
34.  }  
35.  }  

 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下几件事. 
        (1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy0.$Proxy0类 实现了interfaces的接口,并继承了Proxy类. 
        (2)实例化$Proxy0并在构造方法中把DynamicSubject传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下: 

Java代码  [图片上传失败...(image-c01aff-1556796566845)] 

1.  class Proxy{  
2.  InvocationHandler h=null;  
3.  protected Proxy(InvocationHandler h) {  
4.  this.h = h;  
5.  }  
6.  ...  
7.  }

3.$Proxy源码:
import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.lang.reflect.UndeclaredThrowableException;

 

public final class $Proxy0 extends Proxy implements IGamePlayer{

 

private static Method m1;

private static Method m0;

private static Method m3;

private static Method m2;

 

static {

   try {

    m1 = Class.forName("java.lang.Object").getMethod("equals",

      new Class[] { Class.forName("java.lang.Object") });

    m0 = Class.forName("java.lang.Object").getMethod("hashCode",

      new Class[0]);

    m3 = Class.forName("com.ml.test.GamePlayer").getMethod("login",

      new Class[0]);

    m2 = Class.forName("java.lang.Object").getMethod("toString",

      new Class[0]);

   } catch (NoSuchMethodException nosuchmethodexception) {

    throw new NoSuchMethodError(nosuchmethodexception.getMessage());

   } catch (ClassNotFoundException classnotfoundexception) {

    throw new NoClassDefFoundError(classnotfoundexception.getMessage());

   }

}

 

public $Proxy0(InvocationHandler invocationhandler) {

   super(invocationhandler);

}

 

@Override

public final boolean equals(Object obj) {

   try {

    return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))

      .booleanValue();

   } catch (Throwable throwable) {

    throw new UndeclaredThrowableException(throwable);

   }

}

 

@Override

public final int hashCode() {

   try {

    return ((Integer) super.h.invoke(this, m0, null)).intValue();

   } catch (Throwable throwable) {

    throw new UndeclaredThrowableException(throwable);

   }

}

 

public final void login() {

   try {

    super.h.invoke(this, m3, null);

    return;

   } catch (Error e) {

   } catch (Throwable throwable) {

    throw new UndeclaredThrowableException(throwable);

   }

}

 

@Override

public final String toString() {

   try {

    return (String) super.h.invoke(this, m2, null);

   } catch (Throwable throwable) {

    throw new UndeclaredThrowableException(throwable);

   }

}

}
上一篇 下一篇

猜你喜欢

热点阅读