Spring源码(三) ——创建实例对象推断构造方法
之前的Spring源码(一)——Bean生命周期源码解读文章,讲了下Bean的生命周期以及ApplicationContext构造方法的大致逻辑,其中最核心的是refresh方法,但是里面有些方法没有细说。比如invokeBeanFactoryPostProcessors(beanFactory),
registerBeanPostProcessors(beanFactory),
finishBeanFactoryInitialization(beanFactory)
这三个方法 是refresh 中想当重要的方法。而我们的上一篇Spring源码(二)——配置类解析以及扫描Bean对象说了下invokeBeanFactoryPostProcessors方法。
今天我们就详细看看与创建对象相关的方法:finishBeanFactoryInitialization()。
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//注意这个方法值实例化所有的非懒加载的单例
我们从finishBeanFactoryInitialization这个方法下钻进去看看,这个方法做了什么事情。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 判断是否有线程安全的类型转化器,如果没有创建一个
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));
}
//如果没有bean后置处理器,则注册一个默认的嵌入式值解析器
//(例如一个property留出的配置符bean)之前注册过:
//主要用于注释属性值的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
//提前初始化LoadTimeWeaverAware bean以允许提前注册它们的转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时ClassLoader进行类型匹配
beanFactory.setTempClassLoader(null);
// 允许缓存所有bean定义元数据。
beanFactory.freezeConfiguration();
// 实例化所有剩余的(非lazy-init)单例
beanFactory.preInstantiateSingletons();
}
我们继续下钻看看 beanFactory.preInstantiateSingletons();
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("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.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
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());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
首先这个方法就先去获取所有的beanName.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
然后遍历beanName.
-
先从容器中获取beanName 对应的beanDefinition.**注意这里获取的是在扫描部分合并后的BeanDefinition,也就是RootBeanDefinition类型。如果没有就获取原beanDefinition,将这个原BeanDefinition封装成RootBeanDefinition类型.
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
-
判断是否不是抽象的,是否是单例,是否非懒加载。
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
-
判断是否是工厂bean。
if (isFactoryBean(beanName)) {
-
如果是工厂bean,调用getBean方法。但是beanName前面加上一个前缀 & 这个复符号。如果不是就直接使用 beanName 去调用getBean方法。
if (isFactoryBean(beanName)) {//是工厂bean // FACTORY_BEAN_PREFIX == & Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; 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()); } if (isEagerInit) {//是,初始化。 getBean(beanName); } } } else {//不是工厂bean,是普通bean getBean(beanName); }
最后的初始化
在上面遍历完beanNames后,Spring 还会在遍历一次,这次是获取实例,判断实例是否实现了SmartInitializingSingleton接口,如果实现了调用afterSingletonsInstantiated方法。
//触发所有适用bean的后初始化回调…
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
上面是创建Bean的大概流程,我们相信看看getBean方法,如何去创建bean对象。
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//省略的代码。。。。。。。。。。。
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//省略的代码。。。。。。。。。。。
return (T) bean;
}
如果是单例,调用getSingleton ,如果是空,调用==createBean(beanName, mbd, args)==方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//省略的代码。。。。。。
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
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 {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//省略的代码。。。。。。
}
在createBean这个方法里面有这样一句代码。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
这个代码就是在实例化之前会调用的方法。只要你的类实现了InstantiationAwareBeanPostProcessor接口并且实现了postProcessBeforeInstantiation方法。 他这个接口里面还有postProcessAfterInstantiation 实例化后方法。
继续我们看看doCreateBean这个方法。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//省略的代码。。。。。。
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//依赖注入
populateBean(beanName, mbd, instanceWrapper);
//初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
//省略的代码。。。。。。
//循环依赖的处理
//省略的代码。。。。。。
return exposedObject;
}
重点来了 ,推断构造方法。
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
下钻这个方法看看。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析类信息
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//如果这个类不是public 修饰的报错。
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
//判断是否已经拥有实例了 有的话
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
//判断循环创建中是否有这个实例,返回这个实例,没有返回NullBean;
return obtainFromSupplier(instanceSupplier, beanName);
}
//判断工厂方法是否不为空
if (mbd.getFactoryMethodName() != null) {
//使用工厂方法去创建实例。
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {//如果参数为空
synchronized (mbd.constructorArgumentLock) {//加锁
if (mbd.resolvedConstructorOrFactoryMethod != null) {//判断是否缓存了构造方法。
resolved = true;//设置成已经解析了构造方法
autowireNecessary = mbd.constructorArgumentsResolved;//将构造方法的参数标记为已经解析。
}
}
}
if (resolved) {
if (autowireNecessary) {
//如果构造方法和参数有解析了 根据参数获取要自动调用构造方法。
return autowireConstructor(beanName, mbd, null, null);
}
else {//解析了构造方法,但是没有参数 调用默认的无参构造方法。
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
//筛选出所有允许使用的构造方法。
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
然后将所有的构造方法传入autowireConstructor f方法中。
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
argsToUse这个属性可以设置成为 能被使用的参数 ,
explicitArgs 这个理解为 传入的参数。
这一块判断传入的参数是否为空,如果不为空设置 能被使用的参数为传入的参数。
如果为空 ,判断factory中看看缓存中是否有缓存构造方法以及参数信息。如果有获取参数信息这是未 能被使用的参数。
当在这一步能获取到构造方法以及参数的时候
如果能从缓存中获取到构造方法以及参数。后面就不需要走了。直接使用从缓存中获取的构造方法与参数去实例化对象。
当在这一步不能获取到构造方法以及参数的时候
AutowireUtils.sortConstructors(candidates);
会调用这个方法,将所有的构造方法,参照参数个数降序排序。
然后遍历构造方法的集合。
然后下面这一段会对构造方法进行一个打分。如果分数越低优先级越高。
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
总结:
autowireConstructor()
- 先检查是否指定了具体的构造方法和构造方法参数值,或者在BeanDefinition中缓存了具体的构造方法或构造方法参数值,如果存在那么则直接使用该构造方法进行实例化
- 如果没有确定的构造方法或构造方法参数值,那么
a. 如果没有确定的构造方法,那么则找出类中所有的构造方法
b. 如果只有一个无参的构造方法,那么直接使用无参的构造方法进行实例化
c. 如果有多个可用的构造方法或者当前Bean需要自动通过构造方法注入
d. 根据所指定的构造方法参数值,确定所需要的最少的构造方法参数值的个数
e. 对所有的构造方法进行排序,参数个数多的在前面
f. 遍历每个构造方法
g. 如果不是调用getBean方法时所指定的构造方法参数值,那么则根据构造方法参数类型找值
h. 如果时调用getBean方法时所指定的构造方法参数值,就直接利用这些值
i. 如果根据当前构造方法找到了对应的构造方法参数值,那么这个构造方法就是可用的,但是不一定这个构造方法就是最佳的,所以这里会涉及到是否有多个构造方法匹配了同样的值,这个时候就会用值和构造方法类型进行匹配程度的打分,找到一个最匹配的
@Bean的情况
首先,Spring会把@Bean修饰的方法解析成BeanDefinition:如果方法不是static的,那么解析出来的BeanDefinition中:factoryBeanName为AppConfig所对应的beanName,比如"appConfig"factoryMethodName为对应的方法名,比如"aService"factoryClass为AppConfig.class如果方法是static的,那么解析出来的BeanDefinition中:factoryBeanName为nullfactoryMethodName为对应的方法名,比如"aService"factoryClass也为AppConfig.class在由@Bean生成的BeanDefinition中,有一个重要的属性isFactoryMethodUnique,表示factoryMethod是不是唯一的,在普通情况下@Bean生成的BeanDefinition的isFactoryMethodUnique为true,但是如果出现了方法重载,那么就是特殊的情况,比如:
@Bean
public static AService aService(){
return new AService();
}
@Bean
public AService aService(BService bService){
return new AService();
}
虽然有两个@Bean,但是肯定只会生成一个aService的Bean,那么Spring在处理@Bean时,也只会生成一个aService的BeanDefinition,比如Spring先解析到第一个@Bean,会生成一个BeanDefinition,此时isFactoryMethodUnique为true,但是解析到第二个@Bean时,会判断出来beanDefinitionMap中已经存在一个aService的BeanDefinition了,那么会把之前的这个BeanDefinition的isFactoryMethodUnique修改为false,并且不会生成新的BeanDefinition了。
并且后续在根据BeanDefinition创建Bean时,会根据isFactoryMethodUnique来操作,如果为true,那就表示当前BeanDefinition只对应了一个方法,那也就是只能用这个方法来创建Bean了,但是如果isFactoryMethodUnique为false,那就表示当前BeanDefition对应了多个方法,需要和推断构造方法的逻辑一样,去选择用哪个方法来创建Bean。