Java动态代理

代理
代理是设计模式中的一种,分为静态代理和动态代理两种。
所谓静态代理就是在程序运行之前将要代理的类通过代码进行实现,而动态代理则是在程序运行时创建,代理类不会显示的在程序中实现出来,需要在运行时根据事先定义好的规则进行实现。根据定义静态代理适合一些需要单独生成代理类的场景,而动态代理则是用于一些统一处理的情况,这样做的好处是可以避免创建很多重复的代码,增强程序的可维护性和可读性。

Java动态代理
在Java中实现动态代理简单归纳为两种形式,一种是使用JDK的自身的代理技术来实现,另外一种是使用字节码增强技术。下面我们先对JDK实现技术进行介绍。
1.JDK代理
JDK代理是通过java.lang.reflect.Proxy类中newProxyInstance()方法生成代理类对象,我们先看一下方法定义的代码

1
2
3
4
5
6
7
8
9
public class Proxy implements java.io.Serializable {

/**
* loader 类加载器
* interfaces 要代理的接口
* h 代理类处理器
*/

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

这其中代理类处理器InvocationHandler只有一个方法invoke()方法

1
2
3
4
5
6
7
8
public interface InvocationHandler { 
/**
* proxy 代理类对象
* method 标识了我们具体调用的代理类的哪个方法
* args 为这个方法的参数
*/

Object invoke(Object proxy, Method method, Object[] 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
32
33
34
35
36
37
38
39
40
41
public class JDKDynamicProxy {
public static void main(String[] args) {
FruitProxy fruitProxy = new FruitProxy(new Apple());
Fruit appleProxy = (Fruit) fruitProxy.getInstance();
System.out.println(appleProxy.taste("好吃"));
}
}

interface Fruit {
public String taste(String flavor);
}

class Apple implements Fruit {

@Override
public String taste(String flavor) {
return flavor;
}
}

class FruitProxy implements InvocationHandler {

private Object object;

public FruitProxy(Object object) {
this.object = object;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
System.out.println("这是催熟的苹果");
args = new String[]{"不好吃"};
return method.invoke(object, args);
}

public Object getInstance(){
//生成代理对象
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
}