2023-09-16
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/105139638

populateBean分段1

在填充属性前,还会给InstantiationAwareBeanPostProcessor的处理器处理,给他们机会让他们去修改bean实例,这里也是扩展点。如果处理postProcessAfterInstantiation方法会发false,那就会停止属性填充,跳出循环并返回,说明可以控制是否要进行填充,但是spring内部的处理器不会有处理,要处理还是要自定义去扩展处理器。

    boolean continueWithPropertyPopulation = true;//是否让InstantiationAwareBeanPostProcessor继续执行
    		// 在填充前还可以用InstantiationAwareBeanPostProcessors来修改bean
    		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {//非合成的
    			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    						continueWithPropertyPopulation = false;//停止处理
    						break;
    					}
    				}
    			}
    		}
    		if (!continueWithPropertyPopulation) {//如果停止处理就返回
    			return;
    		}

populateBean分段2

获取自动装配模式,默认是NO,如果有设置了,就会根据设置来进行装配。

    //获取属性值
    		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    		//获取自动装配模式,默认是no
    		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    			// Add property values based on autowire by name if applicable.
    			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    				autowireByName(beanName, mbd, bw, newPvs);
    			}
    			// Add property values based on autowire by type if applicable.
    			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    				autowireByType(beanName, mbd, bw, newPvs);
    			}
    			pvs = newPvs;
    		}

populateBean分段3

这里会进行InstantiationAwareBeanPostProcessor处理器的postProcessProperties处理,

    //是否有InstantiationAwareBeanPostProcessors
    		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    
    		PropertyDescriptor[] filteredPds = null;
    		if (hasInstAwareBpps) {
    			if (pvs == null) {//创建PropertyValues
    				pvs = mbd.getPropertyValues();
    			}
    			for (BeanPostProcessor bp : getBeanPostProcessors()) {//继续后置处理器处理
    				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    					if (pvsToUse == null) {
    						if (filteredPds == null) {
    							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    						}
    						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    						if (pvsToUse == null) {
    							return;
    						}
    					}
    					pvs = pvsToUse;
    				}
    			}
    		}
    		

ConfigurationClassPostProcessor内部类ImportAwareBeanPostProcessor的postProcessProperties

这个就是前面如果配置类有Configuration注解,会进行动态代理,会实现EnhancedConfiguration接口,里面有个setBeanFactory接口方法,会传入beanFactory

    @Override
    		public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) {
    			// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
    			// postProcessProperties method attempts to autowire other configuration beans.
    			if (bean instanceof EnhancedConfiguration) {
    				((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
    			}
    			return pvs;
    		}

CommonAnnotationBeanPostProcessor的postProcessProperties

这里就处理我们前面applyMergedBeanDefinitionPostProcessors处理注入注解元数据。

    	@Override
    	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    		InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
    		try {
    			metadata.inject(bean, beanName, pvs);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
    		}
    		return pvs;
    	}

InjectionMetadata的inject

遍历前面注册的InjectedElement,然后进行注入。

    	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    		Collection<InjectedElement> checkedElements = this.checkedElements;
    		Collection<InjectedElement> elementsToIterate =
    				(checkedElements != null ? checkedElements : this.injectedElements);
    		if (!elementsToIterate.isEmpty()) {
    			for (InjectedElement element : elementsToIterate) {
    				if (logger.isTraceEnabled()) {
    					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
    				}
    				element.inject(target, beanName, pvs);
    			}
    		}
    	}

InjectedElement的inject

进行属性或者方法注入,但是方法注入前会判断是否已经有设置值了,有设置就不会注入,直接返回了。

    		protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
    				throws Throwable {
    
    			if (this.isField) {//属性注入
    				Field field = (Field) this.member;
    				ReflectionUtils.makeAccessible(field);
    				field.set(target, getResourceToInject(target, requestingBeanName));
    			}
    			else {
    				if (checkPropertySkipping(pvs)) {
    					return;
    				}
    				try {//方法注入
    					Method method = (Method) this.member;
    					ReflectionUtils.makeAccessible(method);
    					method.invoke(target, getResourceToInject(target, requestingBeanName));
    				}
    				catch (InvocationTargetException ex) {
    					throw ex.getTargetException();
    				}
    			}
    		}
checkPropertySkipping

判断是否要略过属性注入,如果是定义的时候给定值了就忽略。

    protected boolean checkPropertySkipping(@Nullable PropertyValues pvs) {
    			Boolean skip = this.skip;
    			if (skip != null) {
    				return skip;
    			}
    			if (pvs == null) {
    				this.skip = false;
    				return false;
    			}
    			synchronized (pvs) {
    				skip = this.skip;
    				if (skip != null) {
    					return skip;
    				}
    				if (this.pd != null) {
    					if (pvs.contains(this.pd.getName())) {
    						// 给定了值了就忽略,直接返回
    						this.skip = true;
    						return true;
    					}
    					else if (pvs instanceof MutablePropertyValues) {//如果是可变的话,就注册到处理过的属性集合里
    						((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
    					}
    				}
    				this.skip = false;
    				return false;
    			}
    		}

ResourceElement的getResourceToInject

getResourceToInject是关键的方法,其实是InjectedElement的抽象方法,子类有不同的实现类,比如ResourceElementEjbRefElementWebServiceRefElement,当然我们就关注ResourceElement啦,其他自己有兴趣可以看。

这个方法首先判断注释元数据有没有Lazy注解,也就是懒加载,有的话会创建一个代理类,内部是用AOP代理工厂做的,细节后面说,然后有个getTarget代理方法,可以在需要时候调用获取。如果不是就直接getResource

    @Override
    		protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
    			return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
    					getResource(this, requestingBeanName));
    		}

CommonAnnotationBeanPostProcessor的getResource

先判断jndi的注入,然后才调用autowireResource,我们一般就是autowireResource

    protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
    			throws NoSuchBeanDefinitionException {
    
    		if (StringUtils.hasLength(element.mappedName)) {
    			return this.jndiFactory.getBean(element.mappedName, element.lookupType);
    		}
    		if (this.alwaysUseJndiLookup) {
    			return this.jndiFactory.getBean(element.name, element.lookupType);
    		}
    		if (this.resourceFactory == null) {
    			throw new NoSuchBeanDefinitionException(element.lookupType,
    					"No resource factory configured - specify the 'resourceFactory' property");
    		}
    		return autowireResource(this.resourceFactory, element, requestingBeanName);
    	}

autowireResource比较关键,我们后面再讲吧。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

阅读全文