-
生成的代理类为public final,不能被继承
-
类名的格式为:“$ProxyN”
-
N 是逐一递增的数字,代表Proxy是被第N次动态代理生成的代理类
-
对于同一组接口,接口的排列顺序也相同,不会重复创建动态代理类,而是返回一个先前已经创建并缓存了的代理类对象,以此提高效率
synchronized (cache) {
/*
-
不必担心获取到清除掉弱引用的缓存
-
因为如果一个代理类已经被垃圾回收,代理类的类加载器也会被垃圾回收
-
所以获取到的缓存都是加载到缓存中的映射
*/
do {
Object value = cache.get(key);
if (value instanceof Reference) {
proxyClass = (Class) ((Reference) value).get();
if (proxyClass != null) {
/*
- 代理类已经生成,返回代理类
*/
return proxyClass;
} else if (value == pendingGenerationmarker) {
/*
- 代理类正在生成,等待代理类生成
*/
try {
cache.wait();
} catch (InterruptedException e) {
/*
- 等待生成的代理类有一个极小的限定的时间,因此可以忽略线程在这里的影响
*/
}
continue;
} else {
/*
-
如果没有这个接口列表已经生成或者正在生成的代理类
-
需要去生成这些接口的代理类,将这些接口标记为待生成
*/
cache.put(key, pendingGenerationMarker);
break;
}
}while (true);
}
- 类继承关系:
Proxy 类是父类,这个规则适用于所有由 Proxy 创建的动态代理类(这也导致Java动态代理的缺陷,由于Java不支持多继承,所以无法实现对 class 的动态代理,只能对于 Interface 进行代理),该类实现了所有代理的一组接口,所以 Proxy 类能够被安全地类型转换到其所代理的某接口
- 代理类的根类 java.lang.Object 中的 hashCode(),equals()和().toString 方法同样会被分派到调用处理器 invoke 方法执行
创建一个动态代理类
public class serviceProxy implements InvocationHandler {
private Object target;
/**
-
绑定委托对象并返回一个代理对象
-
@param target 真实对象
-
@return 代理对象
*/
public Object bind(Object target, Class[] interfaces) {
this.target = target;
// 取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
-
通过代理对象调用方法首先进入这个方法
-
@param proxy 代理对象
-
@param Method 方法,被调用方法
-
@param args 方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
- JDK动态代理
*/
Object result = null;
// 反射方法前调用
System.err.println(“–反射方法前执行的方法–”);
// 反射执行方法,相当于调用target.xXX()
result = method.invoke(target, args);
// 反射方法后调用
System.err.println(“–反射方法后执行的方法–”);
return result;
}
}
-
bind方法:
-
bind方法中的newProxyInstance方法,就是生成一个代理对象
-
第一个参数: 类加载器
-
第二个参数: 真实委托对象所实现的接口. 代理对象挂在那个接口下
-
第三个参数: this 代表当前 HelloServiceProxy 类, 也就是使用HelloServiceProxy作为对象的代理
-
invoke方法:
-
invoke方法有三个参数:
-
第一个 proxy 是代理对象
-
第二个是当前调用那个方法
-
第三个是方法的参数
ProxyTest
public class ProxyTest {
public static void main(String[] args) {
HelloServiceProxy proxy = new HelloServiceProxy();
HelloService service = new HelloServiceImpl();
// 绑定代理对象
service = (HelloService) proxy.bind(service, new Class[] {HelloService.class});
service.sayHello(“user”);
}
}