【小家Spring】AbstractAutowireCapableBeanFactory#populateBean实现Bean的属性赋值和initializeBean对Bean的初始化

2019-09-03 16:31:08 浏览数 (1)

前言

在上一篇博文:【小家Spring】AbstractBeanFactory#getBean()、doGetBean完成Bean的初始化、实例化,以及BeanPostProcessor后置处理器源码级详细分析

源码分析的时候,留下两个重要的步骤还没有说,一个是属性赋值的populateBean()(依赖注入),还有一个就是赋值后对Bean的一些初始化操作:initializeBean()

Spring源码基于的Spring版本为:5.0.6.RELEASE(下同) Spring源码基于的Spring版本为:5.0.6.RELEASE(下同) Spring源码基于的Spring版本为:5.0.6.RELEASE(下同)

AbstractAutowireCapableBeanFactory#populateBean实现依赖注入

在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean方法完成。

代码语言:javascript复制
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		// 对实例做的一个判空校验
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			} else {
				// Skip property population phase for null instance.
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		boolean continueWithPropertyPopulation = true;

		//给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
		//具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				
					//postProcessAfterInstantiation 这个方法返回true,后面的处理器才会继续执行,单反返回false,后面的就不会再执行了
					//并且continueWithPropertyPopulation 打上标记表示false,也就是说后面的属性复制就不会再执行了
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
		
		// 处理器若告知说不用继续赋值了,那就以处理器的结果为准即可
		if (!continueWithPropertyPopulation) {
			return;
		}

		//pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
		//本例中,我们的helloServiceImpl的Bean定义里,pvs为null
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		//根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml(或者@Bean中)文件中有显式的配置
		//如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			// 深拷贝当前已有的配置
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			// 根据名称进行注入(见下)
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			// 根据类型进行注入(见下)
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			//结合注入后的配置,覆盖当前配置
			pvs = newPvs;
		}

		// 显然hasInstAwareBpps=true,
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//是否进行依赖检查  默认值就是None  所以此处返回false,表示不需要依赖检查(关于依赖检查的4种模式,建议使用@Required来显示控制)
		//@Required注解作用于Beansetter方法上,用于检查一个Bean的属性的值在配置期间是否被赋予或设置(populated)
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			// 过滤出所有需要进行依赖检查的属性编辑器
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

			// 在这个节点上:调用了InstantiationAwareBeanPostProcessor#postProcessPropertyValues方法,
			// 若返回null,整个populateBean方法就结束了=============
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						// 关于postProcessPropertyValues的实现,有几个处理器是非常关键的:
						// 比如AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等等,且看下面的分解
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						// 若返回null,Spring表示你已经属性值都设置好了,那他也不再管了
						if (pvs == null) {
							return;
						}
					}
				}
			}
			// 显然,现在大多数情况下,都不会在check这个了
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

		// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
		// 注意:这一步完成结束后为止。我们的HelloServiceImpl这个Bean依赖的parent,还只是RuntimeBeanReference类型,还并不是真实的Parent这个Bean
		//在Spring的解析段,其它容器中是没有依赖的Bean的实例的,因此这个被依赖的Bean需要表示成RuntimeBeanReferenc对象,并将它放到BeanDefinition的MutablePropertyValues中。
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
		
	}

先看看autowireByNameautowireByType这两步是怎么实现的:

代码语言:javascript复制
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		//根据bw的PropertyDescriptors,遍历出所有可写的(即set方法存在),存在于BeanDefinition里的PropertyValues,且不是简单属性的属性名
		//简单属性的判定参照下面方法,主要涵盖基本类型及其包装类,Number,Date等=============
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			
			// 显然,只有容器里存在的,才能根据这个名称注册进去。
			//注意,这里存在,有点意思:含有Bean,或者Bean定义等等都算
			/** @Override
			public boolean containsBean(String name) {
				String beanName = transformedBeanName(name);
				// 首先工厂里必须有单例Bean,或者bean定义
				// 然后还必须不是BeanFactory(不是&打头),或者是FactoryBean  就算是包含这个Bean的
				if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
					return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
				}
				
				// Not found -> check parent.  看看父容器里有木有
				BeanFactory parentBeanFactory = getParentBeanFactory();
				return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
			} */
			
			// 再说明一下containsLocalBean这个方法,和containsBean的区别在于它只在自己的容器里找,不去父容器里找,其余的一样
			if (containsBean(propertyName)) {
				// 注意:此处找到依赖了,调用了getBean(),所以即使你现在仅仅只是Bean定义,那么会被创建实例对象
				Object bean = getBean(propertyName);
				pvs.add(propertyName, bean);
				// 注册依赖关系
				// 此处需要知道的是:Spring中使用dependentBeanMap和dependenciesForBeanMap来管理这些Bean的依赖关系:
				//Map<String, Set<String>> dependentBeanMap:存放着当前Bean被引用的Bean的集合
				//Map<String, Set<String>> dependenciesForBeanMap:存放的则是当前Bean所依赖的Bean的集合
				//依赖注入的具体实现是在BeanWrapperImpl类中的setPropertyValue方法里=======================
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '"   beanName  
							"' via property '"   propertyName   "' to bean named '"   propertyName   "'");
				}
			} else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '"   propertyName   "' of bean '"   beanName  
							"' by name: no matching bean found");
				}
			}
		}
	}


	protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		// 类型转换器,如果没有指定,就用BeanWrapper这个转换器
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// Don't try autowiring by type for type Object: never makes sense,
				// even if it technically is a unsatisfied, non-simple property.
				//如果是Object类型不进行装配==============
				if (Object.class != pd.getPropertyType()) {
					// 获取相关的写方法参数
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					// 看看实例是否实现了PriorityOrdered接口,若没有实现  就稍后点加载吧-----
					boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);

					// 这里会根据传入desc里的入参类型,作为依赖装配的类型
					// 再根据这个类型在BeanFacoty中查找所有类或其父类相同的BeanName
					// 最后根据BeanName获取或初始化相应的类,然后将所有满足条件的BeanName填充到autowiredBeanNames中。
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}

					// 需要注入的依赖都拿到后,就开始注册这些依赖吧
					for (String autowiredBeanName : autowiredBeanNames) {
						// 一样的 这里注册这些依赖
						registerDependentBean(autowiredBeanName, beanName);
					}
					autowiredBeanNames.clear();
				}
			} catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}

AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor#postProcessPropertyValues实现注解给属性赋值:

从上面看到了,Bean已经解析拿到了注解的一些元信息,因此此处就调用一些处理器的postProcessPropertyValues方法,来给赋值了:

代码语言:javascript复制
//AutowiredAnnotationBeanPostProcessor:这里就是解析该Bean的Autowired信息,然后给inject进去
	@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		} catch (BeanCreationException ex) {
			throw ex;
		} catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}
	
//CommonAnnotationBeanPostProcessor:逻辑和上面一毛一样,它处理的JSR-250的注解,比如@Resource
	@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		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;
	}
	
//RequiredAnnotationBeanPostProcessor:它就是去校验,标注了@Required注解的,必须是是存在这个Bean的
	@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		if (!this.validatedBeanNames.contains(beanName)) {
			if (!shouldSkip(this.beanFactory, beanName)) {
				List<String> invalidProperties = new ArrayList<>();
				for (PropertyDescriptor pd : pds) {
					if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
						invalidProperties.add(pd.getName());
					}
				}
				if (!invalidProperties.isEmpty()) {
					throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
				}
			}
			this.validatedBeanNames.add(beanName);
		}
		return pvs;
	}

InjectionMetadata#inject处理依赖注入:

代码语言:javascript复制
	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()) {
			boolean debug = logger.isDebugEnabled();
			for (InjectedElement element : elementsToIterate) {
				if (debug) {
					logger.debug("Processing injected element of bean '"   beanName   "': "   element);
				}
				// 主要的方法,还是在InjectedElement#inject里
				element.inject(target, beanName, pvs);
			}
		}
	}

InjectedElement实现如下:

这里我们就以最常用的AutowiredFieldElement为例讲解(它是一个普通内部类,为private的):

代码语言:javascript复制
		@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			// 拿到这个字段名
			Field field = (Field) this.member;
			Object value;
			// 大多数情况下,这里都是false
			if (this.cached) {
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			} else {
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
				Assert.state(beanFactory != null, "No BeanFactory available");
				// 转换器,没有手动注册,默认都是SimpleTypeConverter===============
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				try {
					// 把当前bean所依赖的这个Bean解析出来(从Spring容器里面拿,或者别的地方获取吧~~~)
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				} catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				synchronized (this) {
					if (!this.cached) {
						// 如果已经拿到了这个Bean实例,
						if (value != null || this.required) {
							this.cachedFieldValue = desc;
								
							// 把该Bean的依赖关系再注册一次
							registerDependentBeans(beanName, autowiredBeanNames);
							
							// 因为是按照类型注入,所以肯定只能指导一个这个的依赖Bean,否则上面解析就已经报错了
							if (autowiredBeanNames.size() == 1) {
								String autowiredBeanName = autowiredBeanNames.iterator().next();
								// 这里是来处理放置缓存的字段值
								if (beanFactory.containsBean(autowiredBeanName) &&
										beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
									this.cachedFieldValue = new ShortcutDependencyDescriptor(
											desc, autowiredBeanName, field.getType());
								}
							}
						} else {
							this.cachedFieldValue = null;
						}
						this.cached = true;
					}
				}
			}
			// 给该对象的该字段赋值。注意这里makeAccessible设置为true了,所以即使你的字段是private的也木有关系哦~~~
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}
	}
initializeBean进行Bean的初始化工作

上面步骤已经完成了Bean的属性的赋值工作,接下里就进行Bean的一些初始化工作,其中包括:

1:Bean后置处理器初始化

2:Bean的一些初始化方法的执行init-method等等

3:Bean的实现的声明周期相关接口的属性注入

代码语言:javascript复制
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		
		// 第一步:先执行所有的AwareMethods,具体如下代码,比较简单
		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#postProcessBeforeInitialization  初始化之前的处理器方法
			// 规则:只要谁反悔了null,后面的就都不要执行了
			// 这里面实现postProcessBeforeInitialization 的处理器就很多了,有很多对Aware进行了扩展的,具体如下面的具体介绍吧=================
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//这里就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod 
			// 备注:这里initMethod方法的名称不能是afterPropertiesSet,并且这个类不是 InitializingBean类型才会调用,需要特别注意。
			//(然后该方法只有方法名,所以肯定是反射调用,效率稍微低那么一丢丢)
			
			// 由此可以见,实现这个接口的初始化方法,是在标注形如@PostConstruct之后执行的
			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()) {
			// 整个Bean都初始化完成了,就执行后置处理器的这个方法
			// 如果谁反悔了null,后面的处理器都不会再执行了
			
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

invokeAwareMethods:相关Aware接口为:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

这些都是spring将数据暴露出去的一种方式,我们直接实现这个接口就能拿到了~

代码语言:javascript复制
	private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

applyBeanPostProcessorsBeforeInitialization的重要实现解释如下:

代码语言:javascript复制
//ApplicationContextAwareProcessor:核心处理为
	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

//BeanValidationPostProcessor:对bean进行数据校验
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!this.afterInitialization) {
			doValidate(bean);
		}
		return bean;
	}

//BootstrapContextAwareProcessor
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (this.bootstrapContext != null && bean instanceof BootstrapContextAware) {
			((BootstrapContextAware) bean).setBootstrapContext(this.bootstrapContext);
		}
		return bean;
	}

//ServletContextAwareProcessor:
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (getServletContext() != null && bean instanceof ServletContextAware) {
			((ServletContextAware) bean).setServletContext(getServletContext());
		}
		if (getServletConfig() != null && bean instanceof ServletConfigAware) {
			((ServletConfigAware) bean).setServletConfig(getServletConfig());
		}
		return bean;
	}

//LoadTimeWeaverAwareProcessor
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof LoadTimeWeaverAware) {
			LoadTimeWeaver ltw = this.loadTimeWeaver;
			if (ltw == null) {
				Assert.state(this.beanFactory != null,
						"BeanFactory required if no LoadTimeWeaver explicitly specified");
				ltw = this.beanFactory.getBean(
						ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME, LoadTimeWeaver.class);
			}
			((LoadTimeWeaverAware) bean).setLoadTimeWeaver(ltw);
		}
		return bean;
	}

//InitDestroyAnnotationBeanPostProcessor:处理声明周期注解方法的处理器。有了它,就允许用注解代替去实现Spring的接口InitializingBean和DisposableBean了。
//比如@PostConstruct和@PreDestroy等
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeInitMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
		}
		return bean;
	}

applyBeanPostProcessorsAfterInitialization的重要实现解释如下:

Aop相关的几个实现,这里先不做解释,等到后面AOP文章会专门解析~~

代码语言:javascript复制
//ApplicationListenerDetector:把所有的ApplicationListener的Bean,都加入到addApplicationListener里面,放到广播器里面
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		if (bean instanceof ApplicationListener) {
			// potentially not detected as a listener by getBeanNamesForType retrieval
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
				// singleton bean (top-level or inner): register on the fly
				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
			}
			else if (Boolean.FALSE.equals(flag)) {
				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
					// inner bean with other scope - can't reliably process events
					logger.warn("Inner bean '"   beanName   "' implements ApplicationListener interface "  
							"but is not reachable for event multicasting by its containing ApplicationContext "  
							"because it does not have singleton scope. Only top-level listener beans are allowed "  
							"to be of non-singleton scope.");
				}
				this.singletonNames.remove(beanName);
			}
		}
		return bean;
	}

//BeanValidationPostProcessor:校验
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (this.afterInitialization) {
			doValidate(bean);
		}
		return bean;
	}

//ScheduledAnnotationBeanPostProcessor:解析方法中标注有@Scheduled注解的 然后加入当作一个任务进行执行
	@Override
	public Object postProcessAfterInitialization(final Object bean, String beanName) {
		Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
		if (!this.nonAnnotatedClasses.contains(targetClass)) {
			Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
					(MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> {
						Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(
								method, Scheduled.class, Schedules.class);
						return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
					});
			if (annotatedMethods.isEmpty()) {
				this.nonAnnotatedClasses.add(targetClass);
				if (logger.isTraceEnabled()) {
					logger.trace("No @Scheduled annotations found on bean class: "   bean.getClass());
				}
			}
			else {
				// Non-empty set of methods
				annotatedMethods.forEach((method, scheduledMethods) ->
						scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean)));
				if (logger.isDebugEnabled()) {
					logger.debug(annotatedMethods.size()   " @Scheduled methods processed on bean '"   beanName  
							"': "   annotatedMethods);
				}
			}
		}
		return bean;
	}

//SimpleServletPostProcessor:这个很有意思。 相当于当Servlet是以Bean的形式注入容器的时候,Bean初始化完成后,会自动调用它的init方法~~~~~~~~
//如果config为null,那么它传入可能为代理的DelegatingServletConfig
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof Servlet) {
			ServletConfig config = this.servletConfig;
			if (config == null || !this.useSharedServletConfig) {
				config = new DelegatingServletConfig(beanName, this.servletContext);
			}
			try {
				((Servlet) bean).init(config);
			}
			catch (ServletException ex) {
				throw new BeanInitializationException("Servlet.init threw exception", ex);
			}
		}
		return bean;
	}

整个初始化流程如下

  1. 调用各类感知Aware接口
  2. 执行applyBeanPostProcessorsBeforeInitialization初始化前的 处置操作
  3. 调用InitializingBean接口初始化 (如果配置了method-init,则调用其方法初始化 )
  4. 调用applyBeanPostProcessorsAfterInitialization 初始化之后的处置操作
总结

populateBean和initializeBean完成了我们Spring IOC容器的核心内容:依赖注入。前面做的都是非常非常多的准备工作,同时这里也调用了可以参与Bean生命周期的各种钩子方法。

Spring非常非常优秀的一个设计:是我前面强调过多次的职责单一原则,每一个功能,甚至每一个步骤都由特殊的处理器(或者工具类)来完成。优秀的设计,成就了Spring它的扩展能力极强,我们甚至可以在不知道Spring原理的情况下,流畅的使用它的各项功能。(比如Spring AOP、声明式事务、Schedule等等)

0 人点赞