2.1、spring源码(finishBeanFactoryInitialization)

先贴一下这个方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 为上下文初始化类型转换器
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		// 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		// 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		// 禁止使用临时类加载器进行类型匹配
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化剩下的单例对象
		beanFactory.preInstantiateSingletons();
	}

先看设置转换服务的这部分

if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

如果beanFactory中包含CONVERSION_SERVICE_BEAN_NAME这个名称的bean,并且类型匹配ConversionService的bean,就往beanFactory的设置转换

点进ConversionService,进入ConversionService接口,点开一个实现类

1对1

	@Nullable
	<T> T convert(@Nullable Object source, Class<T> targetType);

随便点开一个converter

final class ZoneIdToTimeZoneConverter implements Converter<ZoneId, TimeZone> {

	@Override
	public TimeZone convert(ZoneId source) {
		return TimeZone.getTimeZone(source);
	}

}

1对N

	@Nullable
	Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);

随便点开一个converter

final class ArrayToCollectionConverter implements ConditionalGenericConverter 

点进ConditionalGenericConverter

public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter

点开GenericConverter,ConditionalConverter

根据source和target来做条件判断,从而判断哪个转换器生效哪个转换器不生效

N对N

 随便点进一个converter

final class NumberToNumberConverterFactory implements ConverterFactory<Number, Number>, ConditionalConverter 

点进ConverterFactory(转换器工厂,用来获取对应的转换器)

public interface ConverterFactory<S, R> {

	/**
	 * 获取转换器
	 *
	 * Get the converter to convert from S to target type T, where T is also an instance of R.
	 * @param <T> the target type
	 * @param targetType the target type to convert to
	 * @return a converter from S to T
	 */
	<T extends R> Converter<S, T> getConverter(Class<T> targetType);

}

看一下这个接口对应的注解,是objects转换成R类以及其对应的子类

A factory for "ranged" converters that can convert objects from S to subtypes of R.

接下来看这一段代码,从判断可以看出如果beanFactory中有EmbeddedValueResolver的类型解析器,那么就不需要执行这段代码了

//Register a default embedded value resolver if no bean post-processor
//(such as a PropertyPlaceholderConfigurer bean) registered any before:

if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

点进去hasEmbeddedValueResolver方法

@Override
	public boolean hasEmbeddedValueResolver() {
		// 返回embeddedValueResolvers是否为空集的结果
		return !this.embeddedValueResolvers.isEmpty();
	}

搜embeddedValueResolvers,找到添加embeddedValueResolvers的方法,在这个地方打断点,debug的时候看那里调用到这个方法。

@Override
	public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
		Assert.notNull(valueResolver, "StringValueResolver must not be null");
		// 将valueResolver添加到embeddedValueResolvers中
		this.embeddedValueResolvers.add(valueResolver);
	}

我们回到最开始的方法里面,里面有一段注释,“Register a default embedded value resolver if no bean post-processor”,说明是在beanPostProcessor时放进去的。

// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		// 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

下面还提到了PropertyPlaceholderConfigurer,该bean继承了beanPostProcessor,执行PropertyPlaceholderConfigurer时会调用到beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);,

String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

这段代码放在AOP中说

	beanFactory.setTempClassLoader(null);

设置临时类加载器

beanFactory.freezeConfiguration();

因为下面一个方法要开始初始化bean实例了,所以在初始化之前“冰冻”bean的定义信息。

beanFactory.preInstantiateSingletons();

实例化bean对象,整体大致流程大概是getBean-->doGetBean-->createBean-->doCreateBean.

我们把断点打到这个方法

 对比beanDefinitionMap和singletonObject中的对象,singletonObject的对象是初始化过的,beanDefinitionMap中包含初始化和未初始化的对象,不在singletonObject在beanDefinitionMap的对象就是未初始化的对象

点进preInstantiateSingletons,贴一下这个方法

@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		// 将所有BeanDefinition的名字创建一个集合
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 触发所有非延迟加载单例bean的初始化,遍历集合的对象
		for (String beanName : beanNames) {
			// 合并父类BeanDefinition
 			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// 条件判断,抽象,单例,非懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判断是否实现了FactoryBean接口
				if (isFactoryBean(beanName)) {
					// 根据&+beanName来获取具体的对象
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					// 进行类型转换
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						// 判断这个FactoryBean是否希望立即初始化
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						//  如果希望急切的初始化,则通过beanName获取bean实例
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
					getBean(beanName);
				}
			}
		}

首先这段代码是日志代码,抛开不看

if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

 接着看这一行代码,获取所有beanDefinition的名称并放到一个list中

List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

 接着遍历这个list中的所有bean

for (String beanName : beanNames) {
			// 合并父类BeanDefinition
 			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// 条件判断,抽象,单例,非懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判断是否实现了FactoryBean接口
				if (isFactoryBean(beanName)) {
					// 根据&+beanName来获取具体的对象
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					// 进行类型转换
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						// 判断这个FactoryBean是否希望立即初始化
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						//  如果希望急切的初始化,则通过beanName获取bean实例
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
					getBean(beanName);
				}
			}
		}

在看这个循环代码之前,我们先了解一个概念BeanDefinition有两个实现子类,分别是‘RootBeanDefinition’和‘GenericBeanDefinition’.

点进getMergedLocalBeanDefinition方法,可以看到先从MergedLocalBeanDefinition集合中获取beanName,如果没有则通过与父级合并返回RootBeanDefinition

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// Quick check on the concurrent map first, with minimal locking.
		// 首先以最小的锁定快速检测并发映射。
		// 从bean名称映射到合并的RootBeanDefinition的集合中获取beanName对应的RootBeanDefinition
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		// 如果mbd不为null 且 不需要重新合并定义
		if (mbd != null && !mbd.stale) {
			// 返回对应的RootBeanDefinition
			return mbd;
		}
		// 获取beanName对应的合并Bean定义,如果beanName对应的BeanDefinition是子BeanDefinition,
		// 则通过与父级合并返回RootBeanDefinition
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

其中getMergedBeanDefinition,就是将所有beanDefinition对象转换成rootBeanDefinition对象并进行缓存,在后续马上要实例化的时候,直接获取定义信息。如果对象中含有父类,则先创建父类,创建父类才有子类

接着看这一段代码

if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判断是否实现了FactoryBean接口
				if (isFactoryBean(beanName)) {
					// 根据&+beanName来获取具体的对象
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					// 进行类型转换
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						// 判断这个FactoryBean是否希望立即初始化
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						//  如果希望急切的初始化,则通过beanName获取bean实例
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}

先判断对象是否是抽象的,是否是单例的,是否是懒加载的

接着isFactoryBean判断是否实现了FactoryBean接口(这里补充一个FactoryBean核BeanFactory两者的区别,请参考另一篇文章FactoryBean核BeanFactory两者的区别

接下来看一下FactoryBean创建方法在源码中是怎么走的

项目运行后,断点打到这个方法

可以看到,只有写在xml文件中的bean的beanDefinition才被加载,继续往下走,

getBean-->doGetBean-->getSingleton-->createBean-->doCreateBean-->createBeanInstance-->...

 创建好MyFactoryBean

这里可以看到可以xml文件里面的两个bean被初始化了。并没有看到User对象

往下走,进到ac.getBean()方法中,照着刚才的流程getBean-->doGetBean-->getSingleton

 从一级缓存中取出MyFactoryBean对象

 因为sharedInstance被赋值了从一级缓存中取出的MyFactoryBean对象,所以直接调到了上图所指的位置,点进去

 因为当前创建的bean和给定的beanName的依赖为空,所以走到如上图所在的位置,点进这个方法

 点进条件中的方法

“FACTORY_BEAN_PREFIX”指的是&,所以不条件满足,继续往下走

 因为MyFactoryBean实现了FactoryBean,前面又加了个!,所以跳过往下走

 点进去

 从factoryBean的对象缓存中取这个对象,没取到,继续往下走

因为没有对象赋值给object,所以进入下面这个判断

 先将MyFactoryBean实例强转成FactoryBean类型,

然后判断(传进来的RootBeanDefinition是否为空&&包含这个beanName对应的beanDefinition),这里条件满足进到方法中,获取合并后的beanDefinition,

(mbd != null && mbd.isSynthetic())条件,beanDefinition!= null,beanDefinition不是合成的,所以这里为false

走到下面方法,点进去

 factory=MyFactoryBean对象,beanName=MyFactoryBean,所以第一个判断为true,进到上图所示的位置,点进去

 继续点进去

 可以看到,已经获取方法了,此时我们已经走完object = doGetObjectFromFactoryBean(factory, beanName);,继续往下走

Object alreadyThere = this.factoryBeanObjectCache.get(beanName);

又从FactoryBean的对象缓存中取出MyFactoryBean的对象,这个实例还没放到该位置,所以为空

if (alreadyThere != null) {
						// 让object引用alreadyThere
						object = alreadyThere;
					}
					else {
						// 如果要进行后处理
						if (shouldPostProcess) {
							// 如果beanName当前正在创建(在整个工厂内)
							if (isSingletonCurrentlyInCreation(beanName)) {
								// Temporarily return non-post-processed object, not storing it yet..
								// 暂时返回未处理的对象,尚未存储
								// 直接返回object
								return object;
							}
							// 创建单例之前的回调
							beforeSingletonCreation(beanName);
							try {
								// 对从FactoryBean获得的给定对象进行后处理.
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							// 捕捉所有在进行后处理的抛出的异常
							catch (Throwable ex) {
								// 抛出Bean创建异常:FactoryBean的单例对象的后处理失败
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								// 创建单例后的回调
								afterSingletonCreation(beanName);
							}
						}
						// beanName已经在该BeanFactory的单例对象的高速缓存Map集合DefaultListableBeanFactory.singletonObjects中
						if (containsSingleton(beanName)) {
							// 将beanName以及object添加到factoryBeanObjectCache中
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}

因为alreadyThere为空,所以进到else部分

shouldPostProcess=true,所以进到方法体中
isSingletonCurrentlyInCreation(beanName):myFactoryBean已经创建完成了,所以没进去
beforeSingletonCreation(beanName);点进去,这个方法是在做检查

 继续往下走,进如另一个方法object = postProcessObjectFromFactoryBean(object, beanName);,可以看到是执行一些postprocess方法

 

 继续往下走,走到下面的afterSingletonCreation(beanName);方法,点进去,再做一些检查

 继续往下走,把这个对象放到factoryBean的对象缓存中

if (containsSingleton(beanName)) {
							// 将beanName以及object添加到factoryBeanObjectCache中
							this.factoryBeanObjectCache.put(beanName, object);
						}

接着往下走,进入另一个判断,因为方法传进来的参数requiredType为空,所以直接走到返回bean

 返回bean,此时object = getObjectFromFactoryBean(factory, beanName, !synthetic);方法就执行完了

返回的时候会再检查类型是否匹配

 继续返回,获得User对象

总结:

当使用FactoryBean的时候一共创建了2个对象,一个是Factorybean的子接口,另一个是getObject返回的对象,FactoryBean的子接口 的实现对象由spring创建并管理,放在一级缓存和FactoryObjectCache中。getObject返回的对象在getObjectForBeanInstatans()方法中实现的,存储在FactoryObjectCache中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值