Spring框架学习[创建AOP代理对象并对目标对象切面拦截](七)

2014-11-24 03:05:49 · 作者: · 浏览: 2
public Object getProxy() { return getProxy(ClassUtils.getDefaultClassLoader()); } //创建AOP代理对象 public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } //获取AOPBeanFactory中配置的代理接口 Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); //查找代理目标的接口中是否定义equals()和hashCode()方法 findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); //使用JDK的动态代理机制创建AOP代理对象 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } //查找给定类或接口中是否定义了equals()和hashCode()方法 private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) { //遍历给定的类/接口数组 for (Class proxiedInterface : proxiedInterfaces) { //或者给定类/接口中所有声明的方法 Method[] methods = proxiedInterface.getDeclaredMethods(); //遍历类/接口中的声明的方法 for (Method method : methods) { //如果方法是equals()方法,则设置当前对象equalsDefined属性 if (AopUtils.isEqualsMethod(method)) { this.equalsDefined = true; } //如果方法是hashCode()方法,则设置当前对象hashCodeDefined属性 if (AopUtils.isHashCodeMethod(method)) { this.hashCodeDefined = true; } if (this.equalsDefined && this.hashCodeDefined) { return; } } } } //AOP代理对象的回调方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; //获取通知的目标源 TargetSource targetSource = this.advised.targetSource; Class targetClass = null; Object target = null; try { //如果代理目标对象的接口中没有定义equals()方法,且当前调用的方法 //是equals()方法,即目标对象没有自己实现equals()方法 if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { return equals(args[0]); } //如果代理目标对象的接口中没有定义hashCode()方法,且当前调用的方法 //是hashCode()方法,即目标对象没有自己实现hashCode()方法 if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { return hashCode(); } //如果AOP配置了通知,使用反射机制调用通知的同名方法 if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; //如果当前通知暴露了代理,则将当前代理使用currentProxy()方法变为可用代理 if (this.advised.exposeProxy) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } //获取目标对象 target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } //获取目标对象方法配置的拦截器(通知器)链 List
chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //如果没有配置任何通知 if (chain.isEmpty()) { //没有配置通知,使用反射直接调用目标对象的方法,并获取方法返回值 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } //如果配置了通知 else { //为目标对象创建方法回调对象,需要在调用通知之后才调用目标对象的方法 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); //调用通知链,沿着通知器链调用所有配置的通知 retVal = invocation.proceed(); } //如果方法有返回值,则将代理对象最为方法返回 if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { retVal = proxy; } return retVal; } finally { if (target != null && !targetSource.isStatic()) { //释放目标对象 targetSource.releaseTarget(target); } if (setProxyContext) { //存储代理对象 AopContext.setCurrentProxy(oldProxy); } } } …… }