原理
通过JDK的java.lang.reflect.Proxy类实现动态代理,使用其静态方法newProxyInstance(),依据目标对象,业务接口和业务逻辑增强三者动态生成代理对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/**
- @param loader the class loader to define the proxy class
- 目标类的类加载器,通过目标对象的发射可获取
- @param interfaces the list of interfaces for the proxy class
- to implement
- 目标类实现的接口数组,通过反射可获取
- @param h the invocation handler to dispatch method invocations to
- 业务增强逻辑,需要再定义
- @return a proxy instance with the specified invocation handler of a
- proxy class that is defined by the specified class loader
- and that implements the specified interfaces
*/
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
InvocationHandler是个接口,实现该接口的类用于增强目标类的主业务逻辑。接口中定义了一个invoke()方法,具体加强的代码逻辑定义在该方法中。程序在调用主业务逻辑时自动调用invoke()方法。
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/**
* @param proxy the proxy instance that the method was invoked on
* 生成的代理对象
* @param method the {@code Method} instance corresponding to
* the interface method invoked on the proxy instance. The declaring
* class of the {@code Method} object will be the interface that
* the method was declared in, which may be a superinterface of the
* proxy interface that the proxy class inherits the method through.
* 目标方法
* @param args an array of objects containing the values of the
* arguments passed in the method invocation on the proxy instance,
* or {@code null} if interface method takes no arguments.
* Arguments of primitive types are wrapped in instances of the
* appropriate primitive wrapper class, such as
* {@code java.lang.Integer} or {@code java.lang.Boolean}.
* 目标方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;由于该方法是由代理对象自动调用,所以三个参数不需程序员给出;
第二个参数Method类对象,该类中也有一个方法invoke(),可以 调用目标类的目标方法 ,该方法的具体作用是:调用执行obj对象所属类的方法。
实现
定义业务接口,简单的转账业务
1
2
3
4
5
6
7public interface IAccountService {
//主业务逻辑,转账
void transfer();
}
定义目标类,该类实现业务接口,并实现接口定义的目标方法(只实现主业务逻辑转账)
1
2
3
4
5
6
7
8
9
10
11
12
13public class AccountServiceImpl implements IAccountService {
//目标方法
public void transfer() {
System.out.println("完成转账功能");
}
}
定义主业务增强逻辑类,该类需实现InvokeHandler接口,在invoke()方法中增加增强业务的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class MyExtension implements InvocationHandler {
//目标对象
private Object target;
//将目标对象引入,以便在invoke()中调用目标对象的目标方法
public MyExtension(Object target) {
this.target = target;
}
public MyExtension() {
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强业务逻辑的代码
System.out.println("对转账人身份进行了验证!");
//无论主业务方法有无参数,有无返回值,下面的写法均可兼顾到
return method.invoke(target, args);
}
}
定义客户类
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
26public class Client {
public static void main(String[] args) {
//定义目标对象
IAccountService target = new AccountServiceImpl();
//创建代理对象,并使用目标对象对其初始化
IAccountService proxy = (IAccountService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new MyExtension(target)
);
//执行增强业务之后的方法
proxy.transfer();
}
}