java dynamic proxy
核心java.lang.reflect.Proxy类
// 根据给定接口和ClassLoader获取Class对象
// 使用Class.forName动态加载Class
public static Class<?> getProxyClass(ClassLoader loader, Class<?> interfaces);
// 创建代理对象
// 通过反射的Constructor创建代理对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
// 判断是否是代理Class
public static boolean isProxyClass(Class<?> cl);
// 获得代理对象的InvocationHandler
public static InvocationHandler getInvocationHandler(Object proxy)
java.lang.reflect.InvocationHandler接口
// 反射调用代理类方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
org.springframework.aop.framework.JdkDynamicAopProxy
springframeworkAOP特性实现的基础之一,通过动态代理实现
1 package org.springframework.aop.framework;
2
3 final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
4
5 /** 代理的配置信息 */
6 private final AdvisedSupport advised;
7
8 public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
9 Assert.notNull(config, "AdvisedSupport must not be null");
10 if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
11 throw new AopConfigException("No advisors and no TargetSource specified");
12 }
13 this.advised = config;
14 }
15
16
17 public Object getProxy() {
18 return getProxy(ClassUtils.getDefaultClassLoader());
19 }
20
21 // 获取代理对象
22 public Object getProxy(ClassLoader classLoader) {
23 if (logger.isDebugEnabled()) {
24 logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
25 }
26 Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
27 findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
28 // 使用了Proxy动态代理创建代理对象
29 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
30 }
31
32
33 // 回调代理对象
34 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
35 MethodInvocation invocation;
36 Object oldProxy = null;
37 boolean setProxyContext = false;
38
39 TargetSource targetSource = this.advised.targetSource;
40 Class targetClass = null;
41 Object target = null;
42
43 try {
44 if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
45 // The target does not implement the equals(Object) method itself.
46 return equals(args[0]);
47 }
48 if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
49 // The target does not implement the hashCode() method itself.
50 return hashCode();
51 }
52 if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
53 method.getDeclaringClass().isAssignableFrom(Advised.class)) {
54 // Service invocations on ProxyConfig with the proxy config
55 return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
56 }
57
58 Object retVal;
59
60 if (this.advised.exposeProxy) {
61 // Make invocation available if necessary.
62 oldProxy = AopContext.setCurrentProxy(proxy);
63 setProxyContext = true;
64 }
65
66 // May be null. Get as late as possible to minimize the time we "own" the target,
67 // in case it comes from a pool.
68 target = targetSource.getTarget();
69 if (target != null) {
70 targetClass = target.getClass();
71 }
72
73 // Get the interception chain for this method.
74 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
75
76 if (chain.isEmpty()) {
77 // 如果拦截链是空的,直接通过反射调用target对象的方法
78 // method.invoke(target, args);
79 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
80 }else {
81 // 如果拦截链不为空,包装一个反射方法调用
82 // 先调用织入的拦截器,最后仍然是反射调用target对象的方法
83 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
84 // Proceed to the joinpoint through the interceptor chain.
85 retVal = invocation.proceed();
86 }
87
88 // Massage return value if necessary.
89 if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
90 !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
91 // Special case: it returned "this" and the return type of the method
92 // is type-compatible. Note that we can't help if the target sets
93 // a reference to itself in another returned object.
94 retVal = proxy;
95 }
96 return retVal;
97 }
98 finally {
99 if (target != null && !targetSource.isStatic()) {
100 // Must have come from TargetSource.
101 targetSource.releaseTarget(target);
102 }
103 if (setProxyContext) {
104 // Restore old proxy.
105 AopContext.setCurrentProxy(oldProxy);
106 }
107 }
108 }
109 }
110
posted on 2011-04-06 10:58
liucs 阅读(1301)
评论(0) 编辑 收藏 所属分类:
Java