书接上文我对 IoC 感兴趣的 2 个点别离是
- IoC 是怎么获取 bean 信息,并治理 bean 的
-
IoC 引以为豪的依赖注入
- IoC 是怎么解决循环依赖的(没错齐全是因为网上说面试爱问)
当初曾经解决了第一个问题了,上面来剖析下第二个问题 – 依赖注入
依赖注入简略来说就是本人创建对象交给 Spring 容器治理。那必定就有以下几个步骤了
- 创建对象
- 将对象所依赖的对象注入进来
- 怎么解决循环依赖的问题的
本篇也将围绕着三点开展了。
ps: 源码剖析乃集体总结,如果有任何不对的中央,欢送分割我探讨
创建对象
在上一篇中曾经理解到了 Spring 是如何获取 bean 的各项信息,并把信息存储在 DefaultListableBeanFactory
中了。
此时 Spring 还未初始化实现还记得 AbstractApplicationContext#refresh
办法么。
他会在 finishBeanFactoryInitialization
中创建对象
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有残余的(非提早初始化)单例。finishBeanFactoryInitialization(beanFactory);
@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.
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);// 一般 bean 进入这个办法
}
}
}
// Trigger post-initialization callback for all applicable beans... 为所有实用的 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();
}
}
}
}
随后会进入 AbstractBeanFactory#doGetBean
, 他是十分外围的一个办法, 大抵流程如下,先从本容器中查问,没有,就去父容器查问,以此类推。查到了,就去曾经创立的 bean 中singletonObjects
(key 为 beanName,value 为创立好的 bean) 中寻找,有就间接返回,找不到就再创立,能够了解为,调用这个办法肯定能获取到须要的 bean。
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.|查问缓存中是否
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean'" + beanName +
"'that is not fully initialized yet - a consequence of a circular reference");
}
else {logger.trace("Returning cached instance of singleton bean'" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.| 查看是否能在以后 BeanFactory 中获得须要的 Bean。没有找到就去父容器去取
BeanFactory parentBeanFactory = getParentBeanFactory();
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);
}
// 如果以后 beanFactory 中有 bean
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) {markBeanAsCreated(beanName);
}
try {
// 依据 BeanName 获取 BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.| 获取以后 bean 依赖的 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);
try {getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'"+ beanName +"' depends on missing bean '"+ dep +"'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {//TODO 创立 bean,配置 bean 外围办法
sharedInstance = getSingleton(beanName, () -> {
try {return createBean(beanName, mbd, args);// 创立 bean
}
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);
}
// 创立 property bean 的中央
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean'" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {throw new IllegalStateException("No Scope registered for scope name'" + scopeName + "'");
}
try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);
try {return createBean(beanName, mbd, args);
}
finally {afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope'" + scopeName + "'is not active for the current thread; consider" +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 此时 bean 曾经蕴含了依赖关系的 bean
// Check if required type matches the type of the actual bean instance.|查看所需类型是否与理论 bean 实例的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean'" + name + "'to required type'" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
而后会调用AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean. 持有创立进去的 Bean 对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {// 单例,先把缓存中的同名 Bean 革除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//TODO 理论创立 bean
if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);
}
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) {
try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 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.isTraceEnabled()) {
logger.trace("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);
}
}
if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name'" + beanName + "'has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been" +
"wrapped. This means that said other beans do not use the final version of the" +
"bean. This is often the result of over-eager type matching - consider using" +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
如果该 bean 没有任何依赖会很顺利的通过反射创立,调用如下办法。
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {Assert.notNull(ctor, "Constructor must not be null");
try {ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {return KotlinDelegate.instantiateClass(ctor, args);
}
else {Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {if (args[i] == null) {Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {argsWithDefaultValues[i] = args[i];
}
}
return ctor.newInstance(argsWithDefaultValues);
}
}
... 略
}
最初把创立好的 bean,增加进 map 中
protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
依赖注入
依赖注入呢,会在创立实现后多一步
如果有 bean,有须要依赖注入的属性
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {if (pvs.isEmpty()) {return;}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();}
else {original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {converter = bw;}
//BeanDefinitionValueResolver 对 BeanDefinition 的解析是在这个 valueResolver 中实现
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {if (pv.isConverted()) {deepCopy.add(pv);
}
else {String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {throw new IllegalArgumentException("Autowire marker for property without write method:" + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);// 获取到的 bean 对象
Object convertedValue = resolvedValue;
// 判断是否有 set 办法
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// 依赖注入产生的中央
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
最终会调用 set 办法,进行注入
//set 办法注入
@Override
public void setValue(@Nullable Object value) throws Exception {
Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {ReflectionUtils.makeAccessible(writeMethod);
return null;
});
try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> writeMethod.invoke(getWrappedInstance(), value), acc);
}
catch (PrivilegedActionException ex) {throw ex.getException();
}
}
else {ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value);
}
}
@Autowired
呢略微有点不同
它是在此处进行解决。
注解是通过 field 间接设置值AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Field field = (Field) this.member;
Object value;
if (this.cached) {
try {value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
循环依赖
测试代码如下
@Component
public class Father {
@Autowired
private Son son;
public void say(){son.say();
System.out.println("say hello");
}
}
@Component
public class Son {
@Autowired
private Father father;
public void say(){System.out.println("abcdefg");
}
}
如何解决循环依赖呢?spring 会在创立反射创立完 bean 之后, 依赖注入之前,把 bean 的援用先缓存到 singletonFactories
中
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
着有什么用呢
当解析类中的 bean 的时候会调用 getBean
获取,就会进入到 DefaultSingletonBeanRegistry#getSingleton(String, boolean)
尝试获取 bean,这外面 `
singletonsCurrentlyInCreation会记录正在创立的 bean,例如下面我写的例子,father 须要 son,son 又须要 father,不论哪一个先创立,举个例子,father 先创立,在须要注入的时候,发现 son 没有创立,这个时候,开始创立 son,son 在注入的时候,又须要 father,此时 father 还未创立完,这时候
singletonFactories 就起到作用了,
singletonFactories存的是创立实现的,然而还注入实例的对象,然而 father 的援用不会变,只是还没有给 son 赋值。这时候就把 father 的援用先给 son,son 创立实现,在赋值给 father。大抵就是这么一个过程。创立实现,再把
singletonFactories 外面的删除,对立贮存到
singletonObjects`。
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock|疾速检没有锁的现有实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock|在残缺的单例锁中统一地创立晚期援用
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
创立实现当前删除,对立存储到 singletonObjects
中。
protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}