spring獲取bean的源碼解析
介紹
前面一章說了AbstractApplicationContext中的refresh方法中的invokeBeanFactoryPostProcessors。主要是調(diào)用BeanFactoryPostProcessor。其中也有獲取bean的過程,就是beanFactory.getBean的方法。這一章就說下getBean這個(gè)方法。由于spring中獲取bean的方法比較復(fù)雜,涉及到的流程也非常多,這一章就先說下整個(gè)大體的流程。其中的細(xì)節(jié)會(huì)在后面也會(huì)慢慢說。
源碼
直接看源碼吧
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {
return doGetBean(name, requiredType, args, false);
}
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 把name轉(zhuǎn)化成beanName,也就是把FactoryBean的名稱轉(zhuǎn)化成beanName如果有別名則用別名
final String beanName = transformedBeanName(name);
Object bean;
// 從緩存中獲取實(shí)例
// 可能是需要的Bean實(shí)例,也可能是FactoryBean
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或者FactoryBean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 判斷prototype類型的bean是否存在循環(huán)引用
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 校驗(yàn)父類BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 父類去獲取bean
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 {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 標(biāo)記成已創(chuàng)建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 把原來BeanDefinition轉(zhuǎn)換成RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 獲取依賴的bean,也就是通過@DependsOn注入進(jìn)來的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 校驗(yàn)dependsOn的bean是否存在循環(huán)應(yīng)用
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 加入到引用的緩存中,由于校驗(yàn)dependsOn循環(huán)引用
registerDependentBean(dep, beanName);
// 獲取@dependsOn的bean
getBean(dep);
}
}
// 創(chuàng)建單例的bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
// 獲取需要的bean或者FactoryBean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 創(chuàng)建prototype的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);
}
// 創(chuàng)建其他的bean,比如session,request等
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, () -> {
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;
}
}
// 如果要求的類型不是這個(gè)bean的實(shí)例類型,則進(jìn)行轉(zhuǎn)換
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.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;
}
獲取bean的整體流程就像上面源碼所示,這里再梳理下spring獲取bean的整個(gè)流程
1.先轉(zhuǎn)換bean的名稱,轉(zhuǎn)換成beanName。這里意思就是,我們?cè)讷@取bean的時(shí)候,可能是FactoryBean的名稱(&開頭),這里轉(zhuǎn)成不帶&開頭的名稱,如果有別名,再獲取別名。
2.從緩存中獲取bean,這里的緩存分為一二三級(jí)緩存,也就是我們常常被問到了spring三級(jí)緩存,具體邏輯下面再說。
3.根據(jù)獲取的到對(duì)象再去獲取我們想要的bean,因?yàn)檫@里獲取到的對(duì)象可能是我們需要的bean,也可能是FactoryBean。
4.如果緩存中沒有,那么我們就要自己去創(chuàng)建bean了。
5.查看有沒有父類的BeanFactory,如果有,那么就父類去創(chuàng)建bean。
6.獲取要?jiǎng)?chuàng)建的bean對(duì)象的@DependsOn注解上的名稱,先去創(chuàng)建DependsOn的bean,并且校驗(yàn)是否存在循環(huán)引用
7.創(chuàng)建bean,根據(jù)類型創(chuàng)建不同的bean,比如singleton,prototype,request,session等。
8.如果需要轉(zhuǎn)換類型,則進(jìn)行類型轉(zhuǎn)換。
整體的獲取bean的流程就是這樣了,其中有些具體流程接著分析。
從緩存中獲取bean對(duì)象
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 從一級(jí)緩存中獲取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 從二級(jí)緩存中獲取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 從三級(jí)緩存中獲取
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
spring通過三級(jí)緩存來解決循環(huán)依賴的問題。簡單來介紹下三級(jí)緩存。
1. singletonObjects為一級(jí)緩存,我們實(shí)例化的bean都在這個(gè)map里,俠義的說singletonObjects才是我們真正的spring容器,存放bean的地方。
2. earlySingletonObjects為二級(jí)緩存,是存放未完成的bean的緩存,如果有代理的話,存放的是代理對(duì)象。
3. singletonFactories為三級(jí)緩存,存放的是一個(gè)ObjectFactory,數(shù)據(jù)通過getObject方法獲得。
從BeanInstance中獲取對(duì)象
接下來看getObjectForBeanInstance方法。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// name是不是factoryBean的name(&開頭的)
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果是FactoryBeanName,但是獲取到的bean不是FactoryBean,則拋異常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// 如果bean不是FactoryBean,或者名稱是FactoryBeanName,直接返回BeanInstace
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
// 從緩存中獲取
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 這里可以確定beanInstance是FactoryBean了
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());
// 通過FactoryFBean中獲取需要的beanInstance
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
這里是通過BeanInstance獲取我們想要的bean,這里也簡單說下流程
1. 首先判斷name是不是FactoryBean的name,也就是&開頭的name,如果是去判斷beanInstance是不是FactoryBean,如果beanInstance不是FactoryBean則拋異常。
2. 由于上面已經(jīng)判斷過,如果name是FactoryBeanName,但是BeanInstance不是FactoryBean的話,就會(huì)拋出異常。所以如果BeanInstance如果不是FactoryBean的話,那么name一定不是FactoryBeanName。那么就直接返回BeanInstance就是我們需要的了。
如果name是FactoryBeanName,那么我們需要獲取的就是FactoryBean,也直接返回就可以了。
3. 如果都沒有返回,那么已經(jīng)可以確定我們此時(shí)的已經(jīng)可以確定BeanInstance是FactoryBean了,因?yàn)槿绻皇荈actoryBean的話,在!(beanInstance instanceof FactoryBean)就已經(jīng)返回了。
4. 通過FactoryBean的getObject方法獲取我們需要的bean實(shí)例。
創(chuàng)建bean
根據(jù)@dependsOn查找依賴的bean并且加到依賴?yán)锩嫒]有什么好說的,代碼邏輯也很簡單,接下來看創(chuàng)建單例bean。其他類型的bean的創(chuàng)建也都差別不大??丛创a
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 直接從一級(jí)緩存中取
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 + "'");
}
// 在沒創(chuàng)建bean之前的處理
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 獲取創(chuàng)建的bean
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;
}
// 創(chuàng)建結(jié)束之后的工作
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 加到一級(jí)緩存中,其實(shí)也就是真正的容器中了
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
對(duì)于創(chuàng)建單例bean的主要流程就是如此,傳入一個(gè)beanName,和一個(gè)ObjectFactory。ObjectFactory中具體實(shí)現(xiàn)了創(chuàng)建bean的邏輯。在看具體創(chuàng)建bean的邏輯之前,我們還需要去看下getSingleton中的創(chuàng)建bean之前的工作和創(chuàng)建bean之后的工作。這里面就是查找bean的循環(huán)依賴的方法(和dependsOn不同)。主要是查找根據(jù)filed,set,構(gòu)造器方法的循環(huán)依賴。
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
可以看到代碼非常的簡單,就是創(chuàng)建bean之前,如果沒有排除依賴檢查,那么就加入到正在創(chuàng)建的Set中,如果加入不進(jìn)去,說明之前已經(jīng)加過,這就產(chǎn)生了循環(huán)依賴,從而拋出異常。
如果在創(chuàng)建bean之后,沒有排除檢查依賴,并且移除失敗,說明已經(jīng)不在Set中,也會(huì)拋出異常。
好了,既然明白了spring是如何校驗(yàn)循環(huán)依賴的,也看到了三級(jí)緩存,后面再說為什么不能解決構(gòu)造器依賴就很好說了。接著看創(chuàng)建bean的方法。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 獲取要?jiǎng)?chuàng)建bean的class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 如果沒有beanclass,設(shè)置beanclass
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 配置方法重載
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 那些beanPostProcessor如果能產(chǎn)生代理,則直接返回bean
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 創(chuàng)建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...
throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
這里其實(shí)還是沒有到創(chuàng)建bean的過程,還是在創(chuàng)建bean的一些準(zhǔn)備工作。其實(shí)我們可以發(fā)現(xiàn),spring中,真正做事的都是do開頭的方法。
這邊的流程就是設(shè)置beanClass,后面需要根據(jù)反射來創(chuàng)建bean。然后會(huì)根據(jù)spring里面的beanPostProcessor,看看有沒有能產(chǎn)生代理bean的,如果有就返回,沒有就去創(chuàng)建bean。
看真正的doCreateBean方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 裝飾Bean的對(duì)象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 通過緩存獲取
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 創(chuàng)建bean
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) {
try {
// 調(diào)用MergedBeanDefinitionPostProcessor的方法
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 加入到三級(jí)緩存中去
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 {
// 填充依賴的bean,field注入,和方法注入的bean
populateBean(beanName, mbd, instanceWrapper);
// 調(diào)用初始化的方法
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) {
// 獲取二級(jí)緩存的值
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 如果一致,則直接使用二級(jí)緩存的對(duì)象
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
// 如果調(diào)用初始化后的bean和之前的bean不一致,并且有依賴
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 查找循環(huán)依賴
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 如果有循環(huán)依賴并且在創(chuàng)建中,則拋出異常
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.");
}
}
}
}
// 注冊(cè)disposableBean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
真正創(chuàng)建bean這里還是有點(diǎn)復(fù)雜的。這里再進(jìn)行一個(gè)簡單梳理。
1. 根據(jù)class還有bean以及參數(shù)創(chuàng)建bean。
2. 調(diào)用beanPostprocessor的方法,調(diào)用屬于MergedBeanDefinitionPostProcessor的方法。對(duì)bean進(jìn)行一些處理,比如找到那些依賴的bean的field和method。
3. 將bean加入到三級(jí)緩存中去。
4. 填充bean需要注入的其他bean。
5. 調(diào)用初始化方法,先去調(diào)用@PostConstruct注解方法,然后調(diào)用InitializingBean的afterPropertiesSet,以及自定義的init-method方法。在bean調(diào)用初始化方法之后,再去調(diào)用后置接口看看是否需要生成Aop代理。
6. 接著進(jìn)行校驗(yàn)。這里稍微比較復(fù)雜一點(diǎn)。如果從二級(jí)緩存能取到,那就說明之前被別人從三級(jí)緩存拿出來過了??赡苁且?yàn)檠h(huán)依賴,也可能是因?yàn)閯e的地方調(diào)用了getBean方法了。從三級(jí)緩存拿出來的時(shí)候有個(gè)getEarlyBeanReference的方法,就是查看是否要生成代理的bean。如果生成過了,那么在調(diào)用第五步的時(shí)候,就不會(huì)在生成代理了。這樣exposedObject ==bean,直接只用代理返回。
如果不相等:這里的情況就是如果是spring自己的@Async,在從二級(jí)緩存生成代理之后,再去調(diào)用第五步時(shí)候一樣會(huì)生成代理。所以exposedObject !=bean,所以在再往下發(fā)現(xiàn)有循環(huán)調(diào)用,并且bean還在創(chuàng)建時(shí),就會(huì)拋出異常了。所以一般慎用spring的@Async。但是一般也可以使用@Lazy進(jìn)行處理。至于原理后面再說。
到這里spring的創(chuàng)建bean就結(jié)束了。然后返回時(shí)候就到了入口方法getBean的getObjectForBeanInstance的方法,到底需要的bean還是FactoryBean。
最后就是如果requiredType和實(shí)例不一樣就要進(jìn)行類型轉(zhuǎn)換了。
總結(jié)
本篇大概說下spring獲取bean和加到容器里面的流程。其實(shí)廣義上來說Bean的容器是BeanFactory或者applicationContext。狹義上說就是一個(gè)map。也就是一級(jí)緩存SingletonObjects。我們獲取的真正需要的bean也就是從中獲取的。本篇只是簡要的說了下bean獲取和加入容器的整個(gè)流程,具體的根據(jù)無參構(gòu)造器創(chuàng)建bean,有參數(shù)構(gòu)造器創(chuàng)建bean。還有對(duì)于創(chuàng)建bean中依賴的bean的查找還有創(chuàng)建,三級(jí)緩存如何解決循環(huán)依賴還有為何不能解決構(gòu)造器依賴,以及bean調(diào)用初始化的等等操作都沒有說。因?yàn)橐黄f起來確實(shí)太長了。后面都會(huì)一一去分析。
到此這篇關(guān)于spring獲取bean的源碼解析的文章就介紹到這了,更多相關(guān)spring獲取bean源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Spark?Sql在UDF中如何引用外部數(shù)據(jù)
這篇文章主要為大家介紹了詳解Spark?Sql在UDF中如何引用外部數(shù)據(jù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
mybatis 解決將數(shù)值0識(shí)別成空字符串的問題
這篇文章主要介紹了mybatis 解決將數(shù)值0識(shí)別成空字符串的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置的代碼分享
這篇文章主要介紹了java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置的代碼分享,本文中使用的是QQ在線接口,也可以使用新浪、淘寶等提供的在線接口,需要的朋友可以參考下2014-08-08
關(guān)于springboot加載yml配置文件的no字段自動(dòng)轉(zhuǎn)義問題
這篇文章主要介紹了關(guān)于springboot加載yml配置文件的no字段自動(dòng)轉(zhuǎn)義問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Spring Boot中使用Spring-data-jpa實(shí)現(xiàn)數(shù)據(jù)庫增刪查改
本篇文章主要介紹了Spring Boot中使用Spring-data-jpa實(shí)現(xiàn)增刪查改,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-03-03
Idea創(chuàng)建Jsp項(xiàng)目完整版教程
一直在使用eclipse,對(duì)idea嗤之以鼻,前些日子換成了idea以后覺得太香了,這篇文章主要給大家介紹了關(guān)于Idea創(chuàng)建Jsp項(xiàng)目的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-04-04

