spring源码学习(一)——ioc初始化
spring源码学习(二)——ConfigurationClassPostProcessor(BeanFactory后置处理器的执行)
spring源码学习(四)——aop
1.2.3 初始化bean
执行完beanFactoryPostProcessors之后,会找到所有BeanPostProcessor(Bean的后置处理器),注册到beanFactory中。然后注册各种组件后,来到finishBeanFactoryInitialization(beanFactory)方法,初始化剩下所有非懒加载的单例bean。
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));
}
// 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.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
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.
beanFactory.freezeConfiguration();
//实例化所有立即加载的单例bean(非懒加载)
beanFactory.preInstantiateSingletons();
}
这里设置beanFactory属性,结束beanFactory的初始化工作。ConversionService类型转换器Service也会在这设置,里面维护了转换器的集合。springmvc中接受请求对参数类型的转换就会用到这些转换器。设置完beanFactory,最后调用DefaultListableBeanFactory#preInstantiateSingletons加载所有bean
public void preInstantiateSingletons() throws BeansException {
//所有bean的名字
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//触发所有非延迟加载单例bean的初始化,主要步骤为getBean
for (String beanName : beanNames) {
//合并父BeanDefinition对象
//map.get(beanName)
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是FactoryBean对象则加&获取真实的FactoryBean对象
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final 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
getBean(beanName);
}
}
}
}
可以看到,最终bean的初始化,还是由getBean来完成的。所以非懒加载的单例bean是在ioc初始化过程中,调用的getBean方法,懒加载则是在真正调用的时候使用getBean方法完成初始化。而这里getBean(beanName)方法真正调用的是AbstractBeanFactory#doGetBean方法
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//解析beanName 如果以&开头去掉&开头,如果是别名获取到真正的名字
final String beanName = transformedBeanName(name);
Object bean;
//尝试从一二三级缓中获取bean
Object sharedInstance = getSingleton(beanName);
//如果已经存在则返回
if (sharedInstance != null && args == null) {
//返回实例,针对FactoryBean的处理,返回工厂方法返回的真正实例getObject
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//如果是prototype类型且开启依赖循环,则抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//检查父工厂是否存在该对象
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果beanDefinitionMap中也就是在所有已加载的类中没有beanName则尝试从parentBeanFactory父工厂中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
//bean创建标记下
markBeanAsCreated(beanName);
}
try {
//合并父子bean属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//处理dependsOn配置依赖关系 例如必须在某些bean后创建
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
//创建单例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
//创建bean
return createBean(beanName, mbd, args);
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
return (T) bean;
}
忽略了后面scope的创建,和类型转换。获取真实beanName,尝试从缓存中获取,这里一共有三级缓存是用来处理循环依赖的,后面再详细介绍循环依赖的问题。如果缓存中没有则去创建单例bean。这里调用DefaultSingletonBeanRegistry#getSingleton去获取bean
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 从单例池中拿
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//是否正在销毁,异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
//验证完要真正开始创建对象,先标识该bean正在被创建,因为springbean创建过程复杂,步骤很多,需要标识
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
//传进来的调用,lamda表达式使用。就是createBean创建的bean
//实际会调用AbstractAutowireCapableBeanFactory#getEarlyBeanReference
singletonObject = singletonFactory.getObject();
newSingleton = true;
if (newSingleton) {
//把设置完的bean放入一级缓存,清空其他缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
首先从单例池,也就是一级缓存中获取,如果没有则开始真正的创建bean过程。调用方法参数ObjectFactory#getObject方法就是调用了AbstractAutowireCapableBeanFactory#createBean方法。获取到bean之后,再放入一级缓存中。现在我们跟进createBean方法看看具体的创建过程
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//拿到bd
RootBeanDefinition mbdToUse = mbd;
//根据class属性解析class获得类信息
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//验证MethodOverrides lookup-method和replace-method
mbdToUse.prepareMethodOverrides();
//当是用户自定义的,会调用后置处理器postProcessBeforeInstantiation方法给一个提前改变自己的机会
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
//进入,真真正正创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
这里看到doCreateBean方法,前面带do的方法很明显是真正干事的了。跟进AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean实例,仅仅调用构造方法,但尚未设置属性
//如果有需要覆盖或动态替换的方法会使用cglib动态代理(replace-method,lookup-method),否则直接反射
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
//判断是否提前暴露(解决循环依赖的)是单例,允许循环依赖,正在创建则符合条件
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//加入三级缓存 singletonFactories
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
//初始化bean实例
Object exposedObject = bean;
//bean属性填充
populateBean(beanName, mbd, instanceWrapper);
//调用初始化方法,应用beanPostProcessor后置处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
return exposedObject;
}
首先创建一个未设置属性的实例,还记得之前我的问题,@Bean方法的形参为什么自动会去容器中找到对应的bean注入嘛?这里就能找到答案了。我们来看看AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.解析class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
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) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//如果工厂方法不为空则使用工厂方法初始化策略(@bean)
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);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
//使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
因为@bean方法在之前的解析中,设置了FactoryMethodName,所以会调用instantiateUsingFactoryMethod(beanName, mbd, args)进行创建bean的实例,而instantiateUsingFactoryMethod方法最终调用的是ConstructorResolver#instantiateUsingFactoryMethod
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
....
//@bean设置
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 因为没有通过程序性传入构造参数,所以需要手动判断并解析这些参数
// 如果存在构造参数,则解析这些参数
if (mbd.hasConstructorArgumentValues()) {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {
minNrOfArgs = 0;
}
}
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历与构造方法名字相同的所有方法
for (Method candidate : candidates) {
// 获取方法的参数类型列表
int parameterCount = candidate.getParameterCount();
// 如果是显式声明的构造参数,则反射获得的构造方法参数类型长度与显示参数的个数需要保持一致
// 即这些参数都是必要性参数
if (parameterCount >= minNrOfArgs) {
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
else {
// 解析构造参数,这些参数可以是必填或者非必填
try {
String[] paramNames = null;
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
// 根据信息创建构造参数列表(@bean)
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
}
}
}
}
....
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
忽略了大部分代码,先判断AutowireMode是否为AUTOWIRE_CONSTRUCTOR,之前解析@bean方法时,AutowireMode是设置为AUTOWIRE_CONSTRUCTOR,所以autowiring为true。再继续看看createArgumentArray,在这个方法中会去判断autowiring值,如果为false会抛出异常,如果为true则继续下面的调用:ConstructorResolver#resolveAutowiredArgument->DefaultListableBeanFactory#resolveDependency->DefaultListableBeanFactory#doResolveDependency。
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
//@Value的处理
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
//通过转换器进行类型转换
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
/**
* 根据属性类型找到beanFactory中所有类型的匹配bean
* 返回值的构成为:key=匹配的beanName,value=beanName对应的实例化后的bean(通过getBean返回)
*/
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
//如果没有匹配的bean,并且autowire的Required为true。抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
//如果有多个匹配项根据@Primary和@Priority确定具体匹配的beanName
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.已经确定只有一个匹配项
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
//getBean()
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
determineAutowireCandidate方法,会根据形参的类型去容器中找所有匹配的beanDefinition获取beanName,然后调用DefaultListableBeanFactory#addCandidateEntry->DependencyDescriptor#resolveCandidate,而resolveCandidate方法很简单就是去容器中获取对应的bean。
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
解决完,之前的问题。再回头来看看doCreateBean方法。创建完未赋值的bean实例后,会去判断是否提前暴露(是单例,允许循环依赖,正在创建).如果允许,则将其封装成ObjectFactory加入三级缓存中,然后再调用AbstractAutowireCapableBeanFactory#populateBean方法填充属性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
//给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根据名称自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根据类型自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//后处理器是否已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
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;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
//将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
可以看到这里有两种注入方式,一种根据名称,一种根据类型。根据类型和创建@bean实例时形参注入一样,会去调用DefaultListableBeanFactory#doResolveDependency方法,首先找到所有匹配该类型的beanDefinition对象获取所有beanName,然后调用getBean方法从容器中获取。而根据名称注入就很简单,可以看看AbstractAutowireCapableBeanFactory#autowireByName方法
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//寻找bw中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
//根据名字递归初始化获取相关的bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
//注册依赖
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("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");
}
}
}
}
最终也是调用getBean(beanName)方法,接下来,有可能就会发生循环依赖的情况。
循环依赖
循环依赖其实很好理解。就是spring创建bean A时,发现A里面需要注入属性bean B,但是容器中没有bean B,于是就去创建bean B,但是又发现bean B中又依赖了A,也就是B中需要注入bean A。两个Bean互相依赖就是所谓的循环依赖了。spring通过三个map缓存来解决循环依赖的问题。
假设,上面创建的就是bean A,在填充属性时,需要注入一个bean B。于是getBean(B),又去创建bean B,同创建A的流程一样,在填充属性的时候,发现B又依赖A。于是又调用getBean(A)去容器中获取。getBean调用doGetBean方法。一开始会去尝试从缓存中获取,跟进DefaultSingletonBeanRegistry#getSingleton方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中拿
Object singletonObject = this.singletonObjects.get(beanName);
//如果没有拿到并且是正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//去二级缓存中拿
singletonObject = this.earlySingletonObjects.get(beanName);
//如果二级缓存也没有,并且是否应创建早期引用为true
if (singletonObject == null && allowEarlyReference) {
//从三级缓存中获取ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//如果三级换成中不为空,则调用ObjectFactory的getObject方法实际就是调用之前传入的getEarlyBeanReference获取bean
singletonObject = singletonFactory.getObject();
//将bean放入二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
//从三级换成中删除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
因为bean A在创建完实例,未填充属性时,允许提前暴露,封装成ObjectFactory放入了三级缓存中,所以此时会从三级缓存中取出该ObjectFactory调用getObject方法,这个方法其实就是调用AbstractAutowireCapableBeanFactory#getEarlyBeanReference方法
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
//三级缓存到二级缓存的一些扩展
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//如果是AOP要切的对象,会在这里生成代理对象返回
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
aop的代理对象就是在这里生成的,在getEarlyBeanReference中,如果有bean后置处理器属于SmartInstantiationAwareBeanPostProcessor则会调用方法尝试获取代理对象。接着将getEarlyBeanReference返回的bean对象(有可能是代理对象)放入二级缓存中,并返回。此时bean B获取到bean A,并填充完属性。接着执行完后续流程,从二级缓存删除,再放入一级缓存。此时bean B创建完成,bean A的getBean(B)方法也得到了bean B并填充完属性,循环依赖的问题就解决了。这个循环依赖的解决方法只对非延迟单例对象,非构造方法注入有效。
解决完循环依赖,填充完属性后。 会调用AbstractAutowireCapableBeanFactory#initializeBean方法执行后续操作
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//触发各种定义了aware接口的方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//before方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//先调用InitializingBean的方法,再调用init-method方法
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()) {
//after方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
可以看到后续的执行流程为: 执行实现各种aware接口的方法->bean后置处理器postProcessBeforeInitialization方法->实现InitializingBean接口的afterPropertiesSet方法->InitMethod方法->bean后置处理器的postProcessAfterInitialization方法,bean后置处理器有可能改变bean对象,最后将生成的对象返回,放入一级缓存,清空其他缓存。
IOC初始化总结
ioc初始化大致的流程是:
- 创建beanFactory,解析配置文件信息为beanDefinition
- 执行beanFactory的后置处理器。其中有个ConfigurationClassPostProcessor的后置处理器,会解析@configuration和@Component等注解为beanDefinition,并为@configuration生成代理对象。
- 注册所有Bean的后置处理器
- 初始化各种组件,如MessageSource、事件派发器、监听器
- 尝试从缓存中获取bean对象
- 如果缓存中不存在,则会先调用构造方法创建bean实例,其中有replace-method,lookup-method方法则会生成代理对象,@bean方法的创建,会默认根据类型注入形参。
- 判断是否提前暴露,如果是,则将bean实例包装到ObjectFactory对象放入三级缓存(解决循环依赖)
- 填充属性,如果出现循环依赖,比如先创建Bean A,依赖bean B,再去创建bean B,而bean B又依赖A,在bean B调用getBean(A)时,会在三级缓存中找到包装该bean的ObjectFactory对象,调用getObject方法,获取bean对象放入二级缓存中。aop的动态代理就是在这一步完成的,getObject方法中会执行SmartInstantiationAwareBeanPostProcessor这个bean后置处理器,生成代理对象。
- 填充完属性,触发各种aware接口方法。
- 执行bean后置处理器的before方法
- 如果实现InitializingBean接口则调用afterPropertiesSet方法
- 执行init-method方法
- 执行bean后置处理器的after方法
- 将初始化完成的bean放入一级缓存
- 所有bean初始化完成后,发布事件