【spring源码分析(四)】AOP源码分析---AbstractAutoProxyCreator类为Bean生成代理的过程

xiaoxiao2025-09-17  42

上篇文章,分析了解析<aop:config>内容并存储到BeanDefinition的过程。本篇文章,接着分析AspectJAwareAdvisorAutoProxyCreator类为Bean生成代理类的过程。

AspectJAwareAdvisorAutoProxyCreator类的继承体系

找到需要生成代理的bean

通过之前分析spring ioc过程,先进入到AbstractApplicationContext类的核心方法refresh(),找到finishBeanFactoryInitialization方法,接着进入该方法一直往下找,首先找到AbstractAutowireCapableBeanFactory类的createBean方法,方法源码:

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. // 处理方法覆盖 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //给BeanPostProcessors一个创建代理对象的机会,如果代理对象返回不为空则createBean就直接返回了,后面的目标对象就不再实例化了。 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { // 完成Bean实例的创建(实例化、填充属性、初始化) Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }

分析上述代码,resolveBeforeInstantiation方法是给BeanPostProcessors类一个机会,让它创建代理对象。接着进入resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiation方法,方法源码:

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }

第5行代码,本质调用的是AbstractAutoProxyCreator类的postProcessBeforeInstantiation方法,源码如下:

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } // 1. 有些对象是不可以被代理的,基类:Advices, Advisors and AopInfrastructureBeans; 带有aop注解类: @Aspect // 2. 子类可以复写该类,如果一些情况不需要被代理, shouldSkip返回true if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } ///获取targetSource, 如果存在则直接在对象初始化之前进行创建代理, 避免了目标对象不必要的实例化 TargetSource targetSource = getCustomTargetSource(beanClass, beanName); //如果有自定义targetSource就要这里创建代理对象 //这样做的好处是被代理的对象可以动态改变,而不是只针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象) if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } //获取Advisors, 这个是交给子类实现的 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); //返回代理的对象 return proxy; } return null; }

postProcessBeforeInstantiation中如果获取到自定义的TargetSource则直接创建代理对象,创建代理对象之前先调用getAdvicesAndAdvisorsForBean获取拦截对象Advisors,然后调用createProxy创建代理对象。

如果没有自定义TargetSource,则走到postProcessAfterInitialization方法创建代理,逻辑跟上面一样,唯一不同的是创建了个默认的TargetSource (SingletonTargetSource),方法postProcessAfterInitialization在哪呢?回头再次看AbstractAutowireCapableBeanFactory的createBean方法,找到doCreateBean方法,进入后,找到initializeBean方法,如下:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //应用BeanPostProcessor的postProcessBeforeInitializationf方法,这里首先会对 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //执行初始化方法(先调用InitializingBean的afterPropertiesSet,再调用init-method属性指定的初始化方法) invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //应用BeanPostProcessor的postProcessAfterInitialization方法(AOP代理对象生成) wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

分析以上代码,通过注释可以知道,aop生成代理对象的核心逻辑是applyBeanPostProcessorsAfterInitialization方法。方法源码:

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

分析第6行,本质是调用BeanPostProcessor接口的子类AbstractAutoProxyCreator的postProcessAfterInitialization方法。

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { // 使用动态代理技术,产生代理对象 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 获取advisor, 寻找Advisors,过滤,并做排序 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 通过jdk动态代理或者cglib动态代理,产生代理对象,默认用SingletonTargetSource Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 放入代理类型缓存 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } // 放入通知缓存 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }

分析上述代码,第15行是判断aop.xml配置文件中哪些bean需要生成代理。进入getAdvicesAndAdvisorsForBean方法,找到findEligibleAdvisors,源码如下:

//为指定class寻找合适的Advisor protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = findCandidateAdvisors(); List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }

第3行代码,寻找候选Advisors,根据上文的配置文件,有两个候选Advisor,分别是aop:aspect节点下的aop:before和aop:after这两个,这两个在XML解析的时候已经被转换生成了RootBeanDefinition。 第5行extendAdvisors方法作用是向候选Advisor链的开头(也就是List.get(0)的位置)添加一个org.springframework.aop.support.DefaultPointcutAdvisor。 第4行代码,根据候选Advisors,寻找可以使用的Advisor,依次进入findAdvisorsThatCanApply->findAdvisorsThatCanApply,方法findAdvisorsThatCanApply源码如下:

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new LinkedList<>(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // already processed continue; } if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }

重点看下canApply方法,进入:

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } }

方法的第一个参数advisor的实际类型是AspectJPointcutAdvisor,它是PointcutAdvisor的子类,因此执行第7行的方法:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); if (!pc.getClassFilter().matches(targetClass)) { return false; } MethodMatcher methodMatcher = pc.getMethodMatcher(); if (methodMatcher == MethodMatcher.TRUE) { // No need to iterate the methods if we're matching any method anyway... return true; } IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set<Class<?>> classes = new LinkedHashSet<>(); if (!Proxy.isProxyClass(targetClass)) { classes.add(ClassUtils.getUserClass(targetClass)); } classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); for (Class<?> clazz : classes) { Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) { return true; } } } return false; }

此方法对Advisor对应的expression进行两次判断:

目标类必须满足expression的匹配规则目标类中的方法必须有一个满足expression的匹配规则 如果bean满足这个两个条件,那么容器会对该bean生成代理对象.具体方式为返回一个数组对象,该数组对象中存储的是<bean>对应的Advisor。

spring为<bean>生成代理

回来看AbstractAutoProxyCreator的wrapIfNecessary方法,第15行拿到<bean>对应的Advisor数组,若不为空,则就会通过调用createProxy方法为<bean>创建代理,方法createProxy如下:

protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } // 创建代理工厂对象 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); //判断的内容是<aop:config>这个节点中proxy-target-class="false"或者proxy-target-class不配置,即不使用CGLIB生成代理 //如果满足条件,进入evaluateProxyInterfaces方法,获取当前Bean实现的所有接口,把这些接口Class对象都添加到ProxyFactory中 if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 把指定和通用拦截对象合并, 并都适配成Advisor Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 获取使用JDK动态代理或者cglib动态代理产生的对象 return proxyFactory.getProxy(getProxyClassLoader()); }

进入proxyFactory.getProxy方法:

public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }

此getProxy方法,是用AopProxyFactory代理工厂创建AopProxy, 然后用AopProxy创建Proxy代理对象。这里的AopProxyFactory默认是DefaultAopProxyFactory,看它的createAopProxy方法:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }

平时我们说AOP原理三句话就能概括: 1、对类生成代理使用CGLIB 2、对接口生成代理使用JDK原生的Proxy 3、可以通过配置文件指定对接口使用CGLIB生成代理 这三句话的出处就是createAopProxy方法。看到默认是第14行的代码使用JDK自带的Proxy生成代理,以下三种情况例外:

1、ProxyConfig的isOptimize方法为true,这表示让Spring自己去优化而不是用户指定 2、ProxyConfig的isProxyTargetClass方法为true,这表示配置了proxy-target-class=“true” 3、ProxyConfig满足hasNoUserSuppliedProxyInterfaces方法执行结果为true,这表示<bean>对象没有实现任何接口或者实现的接口是SpringProxy接口

在进入第2行的if判断之后再根据目标<bean>的类型决定返回哪种AopProxy。

总结: 1、proxy-target-class没有配置或者proxy-target-class=“false”,返回JdkDynamicAopProxy 2、proxy-target-class="true"或者对象没有实现任何接口或者只实现了SpringProxy接口,返回Cglib2AopProxy

不管是JdkDynamicAopProxy还是Cglib2AopProxy,AdvisedSupport都是作为构造函数参数传入的,里面存储了具体的Advisor。

通过getProxy方法获取<bean>对应的代理

根据上述分析,查看下JdkDynamicAopProxy生成代理的方式:

public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }

第5行代码的作用是拿到所有要代理的接口,第6行代码的作用是尝试寻找这些接口方法里面有没有equals方法和hashCode方法,同时都有的话打个标记,寻找结束,equals方法和hashCode方法有特殊处理。

最终通过第7行的Proxy.newProxyInstance方法获取接口/类对应的代理对象,Proxy是JDK原生支持的生成代理的方式。

jdk动态代理的调用原理

链接:https://www.cnblogs.com/xrq730/p/6757608.html 上述分析,最后生成了代理对象,生成代理之后就要调用方法了,由于JdkDynamicAopProxy本身实现了InvocationHandler接口,因此具体代理前后处理的逻辑在JdkDynamicAopProxy类的invoke方法中:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Object target = null; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } else if (method.getDeclaringClass() == DecoratingProxy.class) { // There is only getDecoratedClass() declared -> dispatch to proxy config. return AopProxyUtils.ultimateTargetClass(this.advised); } else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // Service invocations on ProxyConfig with the proxy config... return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; 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); // Get the interception chain for this method. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // Check whether we have any advice. If we don't, we can fallback on direct // reflective invocation of the target, and avoid creating a MethodInvocation. 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 { // We need to create a method invocation... invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed(); } // Massage return value if necessary. Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { // Special case: it returned "this" and the return type of the method // is type-compatible. Note that we can't help if the target sets // a reference to itself in another returned object. retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { throw new AopInvocationException( "Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // Must have come from TargetSource. targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }

第10行~第17行的代码,表示equals方法与hashCode方法即使满足expression规则,也不会为之产生代理内容,调用的是JdkDynamicAopProxy的equals方法与hashCode方法。

第22行~第26行的代码,表示方法所属的Class是一个接口并且方法所属的Class是AdvisedSupport的父类或者父接口,直接通过反射调用该方法。

第30行~第34行的代码,是用于判断是否将代理暴露出去的,由aop:config标签中的expose-proxy="true/false"配置。

第42行的代码,获取AdvisedSupport中的所有拦截器和动态拦截器列表,用于拦截方法,具体到我们的实际代码,列表中有三个Object,分别是:

chain.get(0):ExposeInvocationInterceptor,这是一个默认的拦截器,对应的原Advisor为DefaultPointcutAdvisor chain.get(1):MethodBeforeAdviceInterceptor,用于在实际方法调用之前的拦截,对应的原Advisor为AspectJMethodBeforeAdvice chain.get(2):AspectJAfterAdvice,用于在实际方法调用之后的处理

第46行~第52行的代码,如果拦截器列表为空,很正常,因为某个类/接口下的某个方法可能不满足expression的匹配规则,因此此时通过反射直接调用该方法。

第53行~第58行的代码,如果拦截器列表不为空,按照注释的意思,需要一个ReflectiveMethodInvocation,并通过proceed方法对原方法进行拦截,proceed方法里面使用到了递归的思想,对chain中的Object进行循环调用。

转载请注明原文地址: https://www.6miu.com/read-5036478.html

最新回复(0)