代理
代理是设计模式中的一种,分为静态代理和动态代理两种。
所谓静态代理就是在程序运行之前将要代理的类通过代码进行实现,而动态代理则是在程序运行时创建,代理类不会显示的在程序中实现出来,需要在运行时根据事先定义好的规则进行实现。根据定义静态代理适合一些需要单独生成代理类的场景,而动态代理则是用于一些统一处理的情况,这样做的好处是可以避免创建很多重复的代码,增强程序的可维护性和可读性。
Java动态代理
在Java中实现动态代理简单归纳为两种形式,一种是使用JDK的自身的代理技术来实现,另外一种是使用字节码增强技术。下面我们先对JDK实现技术进行介绍。
1.JDK代理
JDK代理是通过java.lang.reflect.Proxy类中newProxyInstance()方法生成代理类对象,我们先看一下方法定义的代码1
2
3
4
5
6
7
8
9public 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
8public 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
41public 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);
    }
}