Java_动态代理(22)

JDK 动态代理

首先来看一个静态代理的例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Test {
  public static void main(String[] args) {
    IService serviceImpl = new ServiceImpl();
    serviceImpl.print(); //ServiceImpl
    IService proxyService = new StaticProxy(serviceImpl);
    proxyService.print();
    //StaticProxy before
    //ServiceImpl
    //StaticProxy after
  }
}

interface IService {
  void print();
}

class ServiceImpl implements IService {
  @Override
  public void print() {
    System.out.println("ServiceImpl");
  }
}

class StaticProxy implements IService {
  private IService serviceImpl;
  public StaticProxy(IService serviceImpl) {
    this.serviceImpl = serviceImpl;
  }
  @Override
  public void print() {
    System.out.println("StaticProxy before");
    serviceImpl.print();
    System.out.println("StaticProxy after");
  }
}

为了不修改 ServiceImpl 实现类,定义了 StaticProxy 代理类,但是如果有很多类似 ServiceImpl 的类需要在不做修改的基础上添加一些方法,就需要给每个类都定义对应的代理类,十分繁琐

可以通过 java.lang.reflect 包下 Proxy 类的 newProxyInstance 静态方法来创建代理对象

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

loader 表示类加载器,在 JVM 章节中再进行讨论

interfaces 表示代理类要实现的接口列表

返回值 Object 可以强制转换为 interfaces 数组中的一个接口的类型

h 的类型为 InvocationHandler 接口,其中只声明了 invoke 一个方法,负责处理方法的调用

1
2
3
4
public interface InvocationHandler { 
  public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;
}

proxy 表示代理对象本身,不是被代理的对象,好像没啥用

method 表示将要被调用的方法,args 表示传入将要被调用的方法的参数

所以将上面静态代理的例子改造为 JDK 动态代理后为

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Test {
  public static void main(String[] args) {
    IService serviceImpl = new ServiceImpl();
    IService proxyServiceImpl = (IService) Proxy.newProxyInstance(
      IService.class.getClassLoader(),
      //内部类的方式
      new Class<?>[] { IService.class },
      new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
          throws Exception {
          System.out.println("InvocationHandler before");
          Object result = method.invoke(serviceImpl, args);
          System.out.println("InvocationHandler after");
          return result;
        }
      });
    proxyServiceImpl.print();
  }
}

interface IService {
  void print();
}

class ServiceImpl implements IService {
  @Override
  public void print() {
    System.out.println("ServiceImpl");
  }
}

上面通过 newProxyInstance 静态方法创建代理对象的过程,可以拆分为下面三步

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Test {
  public static void main(String[] args) throws Exception {
    IService serviceImpl = new ServiceImpl();
    //通过Proxy.getProxyClass创建代理类的Class对象
    Class<?> proxyClazz = Proxy.getProxyClass(
      IService.class.getClassLoader(), IService.class);
    //创建一个方法入参为InvocationHandler类型的代理类的构造器
    Constructor<?> proxyCons = proxyClazz
      .getConstructor(InvocationHandler.class);
    //创建InvocationHandler实现类对象
    InvocationHandler handler = new InvocationHandlerImpl(serviceImpl);
    //创建代理对象
    IService proxyServiceImpl = (IService) proxyCons.newInstance(handler);
    proxyServiceImpl.print();
  }
}

interface IService {
  void print();
}

class ServiceImpl implements IService {
  @Override
  public void print() {
    System.out.println("ServiceImpl");
  }
}

class InvocationHandlerImpl implements InvocationHandler {
  private IService serviceImpl;
  public InvocationHandlerImpl(IService serviceImpl) {
    this.serviceImpl = serviceImpl;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
    throws Exception {
    System.out.println("InvocationHandler before");
    Object result = method.invoke(serviceImpl, args);
    System.out.println("InvocationHandler after");
    return result;
  }
}

cglib 动态代理

JDK 动态代理只能为接口创建代理,如果需要动态代理非接口中定义的方法就不行了,这种情况就可以采用第三方的 cglib ,cglib 是通过继承实现的,即创建出来的代理类是被代理类的子类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Test {
  public static void main(String[] args) {
    Enhancer enhancer = new Enhancer();
    //cglib的Enhancer类通过setSuperclass方法设置要代理的类
    enhancer.setSuperclass(Service.class);
    //setCallback方法设置被代理类的方法被调用时的处理类
    enhancer.setCallback(new MethodInterceptorImpl());
    //创建代理对象
    Service proxyService = (Service) enhancer.create();
    proxyService.print();
  }
}

class Service {
  public void print() {
    System.out.println("Service");
  }
}

//与InvocationHandler类似
class MethodInterceptorImpl implements MethodInterceptor {
  @Override
  public Object intercept(Object object, Method method,
                          Object[] args, MethodProxy proxy) throws Throwable {
    System.out.println("MethodInterceptor before");
    Object result = proxy.invokeSuper(object, args);
    System.out.println("MethodInterceptor after");
    return result;
  }
}

以上内容是玉山整理的笔记,如有错误还请指出