if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { returnnull; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); returnnull; } }
// Create proxy here if we have a custom TargetSource. // Suppresses unnecessary default instantiation of the target bean: // The TargetSource will handle target instances in a custom fashion. TargetSourcetargetSource= getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Objectproxy= createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; }
try { if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; }
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool... target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // 获取目标对象目标方法的拦截器链
// Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. if (chain.isEmpty()) { // We can skip creating a MethodInvocation: just invoke the target directly. // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. // 如果拦截器为空,则通过反射方式执行目标方法 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); }
else { // 如果拦截器不空则创建ReflectiveMethodInvocation对象,执行它的 proceed 方法 // We need to create a method invocation... retVal = newReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain).proceed(); } return processReturnType(proxy, target, method, args, retVal); }
finally { if (target != null && !targetSource.isStatic()) { targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
/** * Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects * for the given method, based on this configuration. * @param method the proxied method * @param targetClass the target class * @return a List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers) */ public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) { // 创建目标方法的缓存 key List<Object> cachedInterceptors;
if (this.methodCache != null) { // Method-specific cache for method-specific pointcuts MethodCacheKeycacheKey=newMethodCacheKey(method);
cachedInterceptors = this.methodCache.get(cacheKey); // 第一次,未缓存,创建缓存 if (cachedInterceptors == null) { // cachedInterceptors = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cachedInterceptors); } } else { // Shared cache since there are no method-specific advisors (see below). cachedInterceptors = this.cachedInterceptors; if (cachedInterceptors == null) { cachedInterceptors = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.cachedInterceptors = cachedInterceptors; } } return cachedInterceptors; }