前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【小家Spring】AbstractAutowireCapableBeanFactory#populateBean实现Bean的属性赋值和initializeBean对Bean的初始化

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

作者头像
YourBatman
发布2019-09-03 16:31:08
1K0
发布2019-09-03 16:31:08
举报

前言

在上一篇博文:【小家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方法完成。

	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这两步是怎么实现的:

	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方法,来给赋值了:

//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处理依赖注入:

	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的):

		@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的实现的声明周期相关接口的属性注入

	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将数据暴露出去的一种方式,我们直接实现这个接口就能拿到了~

	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的重要实现解释如下:

//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文章会专门解析~~

//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等等)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年03月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • AbstractAutowireCapableBeanFactory#populateBean实现依赖注入
  • initializeBean进行Bean的初始化工作
  • 总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档