代理模式是Java常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。

静态代理

接口实现类

  1. public interface Subject {
  2. void visit();
  3. }

Subject接口的两个类

RealSubject

  1. public class RealSubject implements Subject{
  2. String name = "bying";
  3. @Override
  4. public void visit() {
  5. System.out.println(name);
  6. }
  7. }

ProxySubject

  1. public class ProxySubject implements Subject {
  2. private Subject subject;
  3. public ProxySubject(Subject subject) {
  4. this.subject = subject;
  5. }
  6. @Override
  7. public void visit() {
  8. subject.visit();
  9. }
  10. }

Client

  1. public class Client {
  2. public static void main(String[] args) {
  3. ProxySubject proxySubject = new ProxySubject(new RealSubject());
  4. proxySubject.visit();
  5. }
  6. }

动态代理

  1. 动态代理有别于静态代理,是根据代理的对象,动态创建代理类。这样,就可以避免静态代理中代理类接口过多的问题。动态代理是实现方式,是通过反射来实现的,借助Java自带的java.lang.reflect.Proxy,通过固定的规则生成。
  2. 其步骤如下:
  3. 编写一个委托类的接口,即静态代理的(Subject接口)
  4. 实现一个真正的委托类,即静态代理的(RealSubject类)
  5. 创建一个动态代理类,实现InvocationHandler接口,并重写该invoke方法
  6. 在测试类中,生成动态代理的对象。

案例
接口实现类

  1. public interface Subject {
  2. void visit();
  3. }

Subject接口的两个类

RealSubject

  1. public class RealSubject implements Subject{
  2. String name = "bying";
  3. @Override
  4. public void visit() {
  5. System.out.println(name);
  6. }
  7. }

DynamicProxy

  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. public class DynamicProxy implements InvocationHandler {
  4. private Object object;
  5. public DynamicProxy(Object object) {
  6. this.object = object;
  7. }
  8. @Override
  9. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  10. Object result = method.invoke(object, args);
  11. return result;
  12. }
  13. }

Client

  1. public class Client {
  2. public static void main(String[] args) {
  3. Subject realSubject = new RealSubject();
  4. DynamicProxy proxy = new DynamicProxy(realSubject);
  5. ClassLoader classLoader = realSubject.getClass().getClassLoader();
  6. Subject subject = (Subject)Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, proxy);
  7. subject.visit();
  8. }
  9. }
  1. 创建动态代理的对象,需要借助Proxy.newProxyInstance。该方法的三个参数分别是:
  2. ClassLoader loader表示当前使用到的appClassloader
  3. Class<?>[] interfaces表示目标对象实现的一组接口。
  4. InvocationHandler h表示当前的InvocationHandler实现实例对象