本文主要分析Spring的循環(huán)依賴問題截汪。開始正文之前龟虎,我們需要定義這2個(gè)類。LoopReferenceA中引用LoopReferenceB蚀瘸,LoopReferenceB中引用LoopReferenceA。
/**
* @author cmazxiaoma
* @version V1.0
* @Description: TODO
* @date 2018/8/14 15:42
*/
@Component
public class LoopReferenceA {
@Autowired
private LoopReferenceB loopReferenceB;
// public LoopReferenceA(@Autowired LoopReferenceB loopReferenceB) {
// this.loopReferenceB = loopReferenceB;
// }
}
/**
* @author cmazxiaoma
* @version V1.0
* @Description: TODO
* @date 2018/8/14 15:43
*/
@Component
public class LoopReferenceB {
@Autowired
private LoopReferenceA loopReferenceA;
}
分析
AbstractApplicationContext中的refresh()方法是Spring中很核心的方法庶橱。Spring中所有的方法初始化都是在這個(gè)方法中完成的贮勃,用于容器初始化。refresh()里面的細(xì)節(jié)我就不多說了苏章,本文篇幅有限寂嘉。只是大致過一下概念,有利于我們后面追蹤分析問題枫绅。
- prepareRefresh():容器預(yù)先準(zhǔn)備泉孩,記錄容器啟動(dòng)時(shí)間和進(jìn)行標(biāo)記狀態(tài)
- obtainFreshBeanFactory():創(chuàng)建BeanFactory。如果已經(jīng)存在該工廠并淋,那么銷毀其里面的beans和自行關(guān)閉寓搬。如果沒有,則創(chuàng)建工廠县耽,并且進(jìn)行裝載BeanDefinition
- prepareBeanFactory(): 配置BeanFactory的上下文句喷,比如classLoader和BeanPostProcessor,注冊(cè)一些需要解決的依賴和需要忽略的依賴兔毙、注冊(cè)涉及容器系統(tǒng)環(huán)境的bean等等脏嚷。
- postProcessBeanFactory():模板方法,在BeanDefinition被裝載后(所有BeanDefinition被加載瞒御,但是沒有bean被實(shí)例化)父叙,提供一個(gè)修改beanFactory容器的入口。
- invokeBeanFactoryPostProcessor():在Bean未開始實(shí)例之前肴裙,提供BeanDefinition修改或者注冊(cè)的入口趾唱。我們熟悉的PropertyPlaceHolderConfigurer就是在這里調(diào)用的。
- registerBeanPostProcessor():用于攔截Bean創(chuàng)建的BeanPostProcessor蜻懦。
- initMessageSource():初始化容器所需要的MessageSource甜癞,用于國際化處理
- initApplicationEventMulticaster():初始化容器的事件廣播器。
- onRefresh():模板方法
- registerListeners():注冊(cè)監(jiān)聽器
- finishBeanFactoryInitialization():完成容器的初始化,里面會(huì)調(diào)用preInstantiateSingletons()完成單例對(duì)象的創(chuàng)建宛乃。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1.Prepare this context for refreshing.
prepareRefresh();
// 2.Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3.Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 4.Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 5.Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 6.Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 7.Initialize message source for this context.
initMessageSource();
// 8.Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 9.Initialize other special beans in specific context subclasses.
onRefresh();
//10. Check for listener beans and register them.
registerListeners();
// 11.Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//12. Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
我們只用關(guān)注beanFactory.preInstantiateSingletons()方法悠咱。這個(gè)方法用于創(chuàng)建單例且是急加載的對(duì)象。
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.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return 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();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
這個(gè)方法是位于DefaultListableBeanFactory中,這個(gè)類實(shí)現(xiàn)BeanDefinitionRegistry接口征炼,通過重寫的registerBeanDefinition注冊(cè)容器中的BeanDefinition析既。遍歷所有的BeanDefinitionNames,從mergedBeanDefinitions中獲取RootBeanDefinition谆奥。如果bean不是抽象且是單例且是急加載的話眼坏,那么進(jìn)行下一步判斷。如果bean是FactoryBean類型酸些,還需要判斷里面的object是否急加載宰译。如果是的話檐蚜,直接調(diào)用getBean(beanName)完成創(chuàng)建。如果bean不是FactoryBean類型的話沿侈,直接調(diào)用getBean(beanName)闯第。
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.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<String>(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)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((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) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
AbstractBeanFactory中的getBean(name),看來是實(shí)現(xiàn)了BeanFactory接口的getBean(name)方法,里面調(diào)用的是AbstractAutowireCapableBeanFactory中的doGetBean()方法缀拭。
//---------------------------------------------------------------------
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
別被這么長的代碼嚇到了咳短,其實(shí)核心的代碼也就那么多。分析源碼的時(shí)候智厌,不要被邊邊角角的代碼帶偏诲泌,我們只用抓住核心代碼,卷起衣袖開干即可铣鹏。何況網(wǎng)上有很多大神寫的關(guān)于框架源碼分析的博客敷扫,站在巨人上面的我們事半功倍。
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final 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.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("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 parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
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);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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);
}
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();
final 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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
抓住Object sharedInstance = getSingleton(beanName);
這行代碼诚卸,我們追蹤這行代碼葵第,會(huì)發(fā)現(xiàn)最終調(diào)用的是DefaultSingletonBeanRegistry中的getSingleton()方法。這里指的注意是allowEarlyReference的值是true合溺,說明允許提前暴露bean的引用卒密。getSingleton()的作用是檢查緩存中或者是實(shí)例工廠中是否有對(duì)應(yīng)的bean,這主要是解決了Spring循環(huán)依賴的問題棠赛。因?yàn)樵趧?chuàng)建單例LoopReferenceA對(duì)象的時(shí)候哮奇,會(huì)存在依賴LoopReferenceB對(duì)象。而創(chuàng)建LoopReferenceB的時(shí)候避免出現(xiàn)循環(huán)依賴的問題睛约,Spring會(huì)在LoopReferenceA對(duì)象還沒有創(chuàng)建完成之前將創(chuàng)建LoopReferenceA對(duì)象的ObjectFactory暴露出來鼎俘,并且加入到singletonFactories緩存中。當(dāng)LoopReferenceB對(duì)象創(chuàng)建的時(shí)候辩涝,直接從singletonFactories緩存中拿到LoopReferenceA的ObjectFactory贸伐,再從ObjectFactory獲取LoopReferenceA的實(shí)例即可。其實(shí)這個(gè)時(shí)候已經(jīng)真相大白了怔揩,但是我們還需要繼續(xù)追蹤捉邢,好對(duì)Spring這個(gè)流程有個(gè)更加清晰的概念。
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
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);
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 != NULL_OBJECT ? singletonObject : null);
}
如果名字為name的bean實(shí)例只是普通的實(shí)例商膊,那么直接返回beanInstance伏伐。如果是FactoryBean類型的,獲取其的object對(duì)象翘狱,將其返回即可秘案。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
如果獲取sharedInstance(提前暴露的對(duì)象)為null的話,會(huì)執(zhí)行到這里潦匈。Spring只會(huì)處理單例情況下出現(xiàn)的循環(huán)依賴的問題阱高。而對(duì)于采取ProtoType策略創(chuàng)建的bean,則不會(huì)去解決茬缩。如果LoopRefereceA和LoopReferenceB都指定@Scope("prototype")赤惊,那這里肯定會(huì)拋出如圖所示的錯(cuò)誤。
當(dāng)LoopReferenceA實(shí)例化完成凰锡,此時(shí)由于不是單例模式未舟,不能去暴露LoopReferenceA的ObjectFactory。然后填充屬性(其實(shí)是調(diào)用populateBean())去解決LoopRefereceB依賴的問題掂为,從容器中獲取不到LoopReferenceB對(duì)象裕膀,那么去創(chuàng)建LoopReferenceB對(duì)象。同樣從容器嘗試從獲取LoopReferenceA對(duì)象勇哗。還是會(huì)找不到LoopReferenceA對(duì)象昼扛,所以會(huì)去創(chuàng)建LoopReferenceA對(duì)象。在創(chuàng)建原型類型的對(duì)象前欲诺,Spring會(huì)將需要正在創(chuàng)建原型的對(duì)象的名稱放入到prototypesCurrentlyInCreation抄谐。同樣上述操作,prototypesCurrentlyInCreation已經(jīng)存在LoopReferenceA扰法、LoopReferenceB蛹含。所以當(dāng)再一次創(chuàng)建LoopReferenceA對(duì)象時(shí),會(huì)通過isPrototypeCurrentlyInCreation(beanName)會(huì)檢查這個(gè)bean是否已經(jīng)創(chuàng)建塞颁。檢查不通過浦箱,肯定存在循環(huán)依賴問題,所以會(huì)拋出BeanCurrentlyInCreationException異常祠锣。
/**
* Callback before prototype creation.
* <p>The default implementation register the prototype as currently in creation.
* @param beanName the name of the prototype about to be created
* @see #isPrototypeCurrentlyInCreation
*/
@SuppressWarnings("unchecked")
protected void beforePrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<String>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
}
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
/**
* Return whether the specified prototype bean is currently in creation
* (within the current thread).
* @param beanName the name of the bean
*/
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}
繼續(xù)向下追蹤酷窥,單例對(duì)象最終會(huì)調(diào)用getSingleton()完成創(chuàng)建。
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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);
}
先從singletonObjects緩存中通過beanName找對(duì)象锤岸。如果找不到的話竖幔,會(huì)去調(diào)用singletonFactory的getObject()完成單例對(duì)象的創(chuàng)建。在此之前是偷,會(huì)把需要?jiǎng)?chuàng)建的對(duì)象名稱加入到singletonsCurrentlyInCreation緩存中拳氢。如果添加失敗的話,證明singletonsCurrentlyInCreation中有重復(fù)的元素蛋铆,很明顯存在循環(huán)引用馋评,拋出BeanCurrentlyInCreationException異常。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
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!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
最后單例創(chuàng)建成功刺啦,調(diào)用addSingleton(beanName, singletonObject)把beanName放入到singletonObjects緩存中留特。
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
如果對(duì)象創(chuàng)建完畢后,會(huì)調(diào)用afterSingletonCreation需要移除singletonsCurrentlyInCreation緩存中該bean加載的狀態(tài)的記錄。
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
繼續(xù)追蹤代碼蜕青,已經(jīng)到了準(zhǔn)備創(chuàng)建bean的階段苟蹈,感慨不容易啊。同時(shí)也發(fā)現(xiàn)了在Spring中真正干活的方法基本上是do開頭的右核。我們會(huì)發(fā)現(xiàn)在調(diào)用doCreateBean()之前會(huì)調(diào)用resolveBeforeInstantiation()對(duì)bean進(jìn)行處理慧脱。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
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);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
在resolveBeforeInstantiation()中,如果rootBeanDefinition還未被解析贺喝,可以調(diào)用InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation()進(jìn)行實(shí)例化前的前置處理(在這里我們可以做JDK代理或者CGLIB代理菱鸥,經(jīng)歷過這個(gè)過程,bean就不會(huì)是原來的那個(gè)bean了)躏鱼。如果前置處理的結(jié)果不等于null的話氮采,那么不會(huì)經(jīng)歷普通bean的創(chuàng)建過程了,就可以直接調(diào)用所有BeanPostProcessor中的postProcessAfterInitialization()進(jìn)行初始化后的后置處理染苛。最后處理完畢的bean如果不等于null的話鹊漠,beforeInstantiationResovled標(biāo)志位應(yīng)該置為true,代表已經(jīng)被處理過了殖侵。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
千辛萬苦贸呢,終于來到了最終篇,doCreateBean()用于常規(guī)bean的創(chuàng)建拢军。
instanceWrapper = createBeanInstance(beanName, mbd, args);
這行說明bean可以通過工廠方法楞陷、構(gòu)造方法自動(dòng)、簡單初始化策略來完成bean實(shí)例的創(chuàng)建茉唉。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final 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);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
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.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
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<String>(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 " +
"'getBeanNamesOfType' 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;
}
createBeanInstance()是用于創(chuàng)建bean的實(shí)例固蛾。如果bean存在工廠方法,調(diào)用instantiateUsingFactoryMethod(beanName, mbd, args)
完成實(shí)例化度陆。如果bean存在多個(gè)構(gòu)造器的話且都有不同的參數(shù)艾凯,根據(jù)參數(shù)匹配出合適的構(gòu)造器調(diào)用autowireConstructor(beanName, mbd, ctors, args)
完成實(shí)例化。如果既不存在工廠方法也不存在帶有參數(shù)的構(gòu)造器就采用無參構(gòu)造器懂傀,調(diào)用instantiateBean(beanName, mbd)完成bean的實(shí)例化趾诗。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
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());
}
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);
}
}
// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.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);
}
這里主要是調(diào)用所有的MergedBeanDefinitionPostProcessor中的postProcessMergedBeanDefinition()來預(yù)解析注解,處于bean與bean中依賴的對(duì)象之間的關(guān)系蹬蚁,將其之間的關(guān)系包裝成InjectionMetadata恃泪,最后調(diào)用通過this.injectionMetadataCache.put(cacheKey, metadata)
將其放入緩存中。大名鼎鼎的AutowiredAnnotationBeanPostProcessor犀斋、CommonAnnotationBeanPostProcessor贝乎、RequiredAnnotationBeanPostProcessor都實(shí)現(xiàn)了這個(gè)接口。
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
try {
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
"] for autowiring metadata: could not find class that it depends on", err);
}
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<InjectionMetadata.InjectedElement>();
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
}
});
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
這里是用于去解決循環(huán)依賴的問題叽粹。如果rootBeanDefinition是單例的且允許循環(huán)引用且該bean處于正在創(chuàng)建的過程中览效,我們可以在bean初始化前暴露出創(chuàng)建bean的ObjectFactory却舀,并且加入到緩存中。
// 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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
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);
}
}
}
上面的ObjectFactory的getObject()中調(diào)用到了getEarlyBeanReference()锤灿,我們可以在SmartInstantiationAwareBeanPostProcessor中的getEarlyBeanReference()中進(jìn)行aop操作翔忽,注入advice英古。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
if (exposedObject == null) {
return null;
}
}
}
}
return exposedObject;
}
earlySingletonReference只有檢測(cè)到有循環(huán)依賴的情況下才不會(huì)為null拱她。如果bean等于exposedObject阔馋,證明在bean初始化的時(shí)候沒有進(jìn)行增強(qiáng)處理每强。 dependentBeans是依賴當(dāng)前bean的bean集合始腾。如果actualDependentBeans不為空說明依賴當(dāng)前的bean的bean集合中已經(jīng)存在創(chuàng)建成功的實(shí)例,說明存在循環(huán)依賴的問題空执。
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<String>(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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
registerDisposableBeanIfNecessary()主要的作用是注冊(cè)DisposableBean,如果配置了destory-method浪箭,這里需要注冊(cè)以便于在Destory的時(shí)候進(jìn)行調(diào)用。
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
注意到這個(gè)populateBean()方法辨绊,它是對(duì)bean進(jìn)行填充奶栖,將各個(gè)屬性進(jìn)行注入。由于可能存在依賴其他的bean门坷,會(huì)進(jìn)行遞歸初始依賴的bean宣鄙。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
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;
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;
}
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) {
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);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
}
回到populateBean()上來,我們可以發(fā)現(xiàn)這個(gè)方法做了以下幾件事情:
- 通過InstantiationAwareBeanPostProcessor中的postProcessAfterInstantiation()方法控制著是否要繼續(xù)執(zhí)行屬性的注入默蚌。如果返回為false冻晤,直接返回。
- 根據(jù)屬性注入的類型(名稱绸吸、類型注入)鼻弧,調(diào)用
autowireByName(beanName, mbd, bw, newPvs)
或者是autowireByType(beanName, mbd, bw, newPvs)
獲取依賴bean的實(shí)例,并存入到PropertyValues中锦茁。
3.調(diào)用InstantiationAwareBeanPostProcessor中的postProcessPropertyValues()在屬性獲取完畢填充前對(duì)屬性進(jìn)行后置處理攘轩。
4.調(diào)用applyPropertyValues(beanName, mbd, bw, pvs)
將所有PropertyValues中的屬性填充至BeanWrapper中。
以AutowiredAnnotationBeanPostProcessor為例子码俩,我們來看看它的postProcessPropertyValues如何對(duì)bean中的屬性進(jìn)行處理的度帮。首先從injectionMetadataCache通過bean的clazz從injectionMetadataCache緩存中獲取合適的InjectionMetadata,調(diào)用metadata.inject()實(shí)現(xiàn)屬性注入稿存。
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
通過遍歷當(dāng)前InjectionMetadata中需要注入的InjectedElement笨篷,一一調(diào)用inject()完成注入。
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
通過field挠铲、required創(chuàng)建DependencyDescriptor對(duì)象冕屯。調(diào)用 beanFactory.resolveDependency()去處理field字段的依賴。
@Override
protected void inject(Object bean, String beanName, 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<String>(1);
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)) {
if (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);
}
}
}
老規(guī)律拂苹,真正做事情的方法大多數(shù)都是do開頭安聘。調(diào)用doResolveDependency()處理依賴痰洒。
@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (javaUtilOptionalClass == descriptor.getDependencyType()) {
return new OptionalDependencyFactory().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;
}
}
首先獲取descriptor中的依賴對(duì)象類型,通過autowireCandidateResolver解析得出建議的value浴韭。如果value等于null丘喻,去判斷type是否是Array、Collection念颈、Map類型泉粉。如果不是這幾種類型,multipleBeans會(huì)返回null榴芳。接著調(diào)用findAutowireCandidates()匹配所需要的bean實(shí)例嗡靡,匹配出autowiredBeanName,調(diào)用descriptor.resolveCandidate(autowiredBeanName, type, this)
獲取屬性的依賴。
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, 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);
}
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
resolveCandidate()最終會(huì)調(diào)用beanFactory.getBean()獲得bean的實(shí)例窟感。一切真相大白讨彼。
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName, requiredType);
}
尾言
大家好,我是cmazxiaoma(寓意是沉夢(mèng)昂志的小馬)柿祈,希望和你們一起成長進(jìn)步哈误,感謝各位閱讀本文章。
小弟不才躏嚎。
如果您對(duì)這篇文章有什么意見或者錯(cuò)誤需要改進(jìn)的地方,歡迎與我討論蜜自。
如果您覺得還不錯(cuò)的話,希望你們可以點(diǎn)個(gè)贊。
希望我的文章對(duì)你能有所幫助卢佣。
有什么意見重荠、見解或疑惑,歡迎留言討論珠漂。
最后送上:心之所向晚缩,素履以往。生如逆旅媳危,一葦以航荞彼。