动态代理

动态代理


动态代理简介

在解释动态代理之前,我们先了解什么是代理,所谓代理,就类似生活当中的中介,例如,房产中介,其作用就是充当购房者与房地产商之间的桥梁。将这种思想应用到编程中便是我们所熟知的代理模式,而动态代理可以理解为代理模式下的一种具体的实现,即在实际的调用者与目标对象之间,存在着一个代理对象,这个代理对象可以在调用者访问目标对象时进行一些处理。在某些情况下,我们可能不希望某个对象直接去访问另一个对象,那么这个时候就可以使用代理对象去解决,动态代理的特点就是我们无需自己手动的创建代理对象,值得注意的是动态代理对象必须与目标对象实现相同的接口。


动态代理简单实现

在Java的API中有一个Proxy类(java.lang.reflect.Proxy),这个类中提供了一个可以获取动态代理对象的方法:

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

这个方法可以返回一个指定接口的代理类实例,也即是说这个方法可以根据所传的参数动态的返回某个类的代理类实例。为了演示这个过程,我先创建一个目标类:

被代理类
1
2
3
4
5
6
7
8
9
10
package com.my.proxy;

public class Target implements TestInterface {

@Override
public void test() {
System.out.println("Target is running...");
}

}
被代理类实现的接口
1
2
3
4
5
6
7
package com.my.proxy;

public interface TestInterface {

void test();

}

测试代码如下:

测试类
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
package com.my.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.junit.Test;

public class TargetTest {

/**
* 通过动态代理对象访问Target类中的方法
*/
@Test
public void test1() {
// 获取动态代理对象---在运行时在内存中动态地为Target创建一个虚拟的代理对象
// 参数:loader:与被代理类相同的类加载器;interfaces:被代理类所实现的接口的字节码对象数组
// dynamicProxy就是代理对象,由参数确定dynamicProxy是谁的代理对象
// 由于要调用被代理类中的方法,需要强制转换
TestInterface dynamicProxy = (TestInterface) Proxy.newProxyInstance(Target.class.getClassLoader()
, new Class[]{TestInterface.class}
, new InvocationHandler() {
// invoke表示执行代理对象的方法
// method表示的是目标对象的方法字节码对象
// args表示的是目标对象相应方法的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 执行目标对象的方法
method.invoke(new Target(), args);
// 此处的返回值可以是执行invoke方法返回的值
return null;
}
});
// 调用test()实际上执行的是invoke(),而invoke()又去调用目标对象的相应的方法
dynamicProxy.test();
}
}

如果您觉得我的文章对您有帮助,请随意赞赏,您的支持将鼓励我继续创作!
0%