// 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);
}
/** * Add the given singleton factory for building the specified singleton * if necessary. * <p>To be called for eager registration of singletons, e.g. to be able to * resolve circular references. * @param beanName the name of the bean * @param singletonFactory the factory for the singleton object */ 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: 剛剛創建的bean,不存在任何集合中 earlySingletonObjects表示過渡性對象map,已經new出來,但屬性沒填充
singletonObjects:表示已經創建好的對象map
繼續
try { //
//設置填充屬性
populateBean(beanName, mbd, instanceWrapper);
//執行後置處理器,aop就是這裏執行的
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
其中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;
//其中class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
// implements InstantiationAwareBeanPostProcess//處理@resource,@PostConstruct @Predestroy
//還有AutowiredAnnotationBeanPostProcessor
//AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements //MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {//處理@autowire
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
//spring同樣像給構造方法參數一樣可以給bean屬性設置默認值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
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;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
以下面的2個類相互引用爲例
@Component("cirdao")
public class CircusLmqDao {
@Autowired
CircusLmqService circusLmqService;
public void updatequerydao()
{
System.out.println("updatequerydao .............");
}
@Component("cirservice")
public class CircusLmqService {
@Autowired
CircusLmqDao circusLmqDao;
public void updatequery()
{
System.out.println("updatequery .............");
}
}
因爲要設置屬性,所以下面斷點如下
進入
此時只是bean,還沒給屬性賦值,比如circuslmqservice=null,
繼續往下,其中AutowiredAnnotationBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
其中AutowiredAnnotationBeanPostProcessor會在上面起作用
進去
往下
接着進入
進入element.inject
field可以看出
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
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");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
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;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
進入
進去resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
對於其中的 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
進去後
@Nullable
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();
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());
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;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, 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) {
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);
}
}
看下中間過程,其中依賴的屬性的lmqservice還沒創建,所以val==null
繼續看下過程
if (instanceCandidate instanceof Class) //很關鍵
{ instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); }
進去此方法(此時lmqserice還沒實例化,裏面是如何解決·)
執行到此,此時的beanname爲lmqservice也就是cirdao的屬性,查看下此時的beanfactory的objects集合
如圖示,在正在創建cirdao時,首先被放在singletonFactories中,而此時singletonobjects既沒cirdao實例也沒lmqservice實例,
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
進去return beanFactory.getBean(beanName);
繼續進入
此時的getsingle肯定是null,第一次調用,細看下
Object sharedInstance = getSingleton(beanName);如下圖,傳了個參數allowEarlyReference=true//允許早期暴露
對於此時是正在創建cirdao,
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//對於criservice不成立,直接返回,但此時
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
會進入cirservice的實例化
同樣進入和cirdao的實例化流程,此時beanname=cirservice
繼續
繼續
後面同樣進入cirservice的populateBean()過程,
同樣適用wrapper的object的屬性circusLmqdap目前還是null
繼續,直到後置處理器設置屬性,autowire處理時,
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
進去;
和cirdao的類似
進去
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
進去
進去
doResolveDependency()
如下圖
進去(和之前創建cirsdao類似)
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
接着進去dogetbean(cirsdao)//此時由於之前已經創建cirsdap實例雖然未設置完屬性
所以下面的getsingletonobejct()不爲空,可以看一下
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
........................
繼續
執行完上面的就把第一次半成品的cirsdao從singfactory拿出來放到earlysinglletonobjects中,
其中cirsdao實例(只是創建,還沒屬性)是之前創建完放到singfactory中的,如下
//if (earlySingletonExposure) {
// if (logger.isDebugEnabled()) {
// logger.debug("Eagerly caching bean '" + beanName +
// "' to allow for resolving potential circular references");
// }
// addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
//}
removr後
factory只剩一個了.
但此時正在創建的仍是2個,
當拿到cirdao後,返回,給cirslmqservice設置屬性,
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
繼續回退,看下調用棧,
繼續走
field.set(bean, value);如下
這裏由於先初始化cirdao,但cirdao又依賴cirlmqservice,所以先把cirslmqserivce初始化並設置好,再反過來設置cirdao,後面的cirdao也會有個field.set(), //可以反覆看下調用棧
看下回退調用棧,再看下第一次的inject
下面仍會有filed.set()
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
.............................
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
等過程回到創建半個cirdao(尚未設置屬性)後,由於之前依賴的cirserve已經初始化並設置完屬性依賴,會返回完整的crslmqservice bean對象
然後也開始fiedl.set,如下圖,
查看此時的singleobjects
因爲cirservice初始化並設置好屬性,所以添加到了singleobjects,在這裏需要觀察下在哪個位置添加的
而cirdao還沒來得及加到,需要看下
繼續執行,也就是按步執行,回到最初調用起點,(本次函數調用棧較多,由於本次實驗循環依賴,執行過程一樣,方法棧重複了2次)
根據調用棧,一步步來,發現在上方面的方法中cirdao已添加到singletonobjects,由於crisservice之前添加過程一樣,不再贅述。
至此循環依賴完成,
綜上earlysinglepbjects只是add,put, 獲取是在singletonfactorys拿到的,總結就是先把半成品x(以實例化但沒設置屬性的bean)f放在全局的singletonfactorys,然後類似遞歸處理依賴的對象y,由於x和y相互依賴,之前的半成品x已存在,可以順利完成y的初始化(包括field.set),返回上一級繼續完成x的field.set,完成屬性設置,添加到singletonobjects()