3、Spring DI 从容器中获取bean实例

本文详细解析了在Spring框架中,如何从ClassPathXmlApplicationContext容器获取bean实例的过程,包括从别名映射获取真实beanname,检查单例缓存,以及创建bean实例的详细步骤,涉及getBean、doGetBean、createBean等多个核心方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇文章主要介绍如何从Spring容器中获取bean实例,以ClassPathXmlApplicationContext为例。
从ClassPathXmlApplicationContext中获取实例,其实就是从context中的DefaultListableBeanFactory中获取实例,调用AbstractBeanFactory中的get(String beanname)方法:

在doGetBean方法中,大致流程如下:
一:获取真实beanname,因为用户提供的beanname有可能是别名,通过alias-beanname的map获取到最终的真实beanname;
二:从单例缓存中获取bean实例,若获取到的对象不为空,则调用bean = getObjectForBeanInstance(sharedInstance, name, beanName, null)方法,获取真实bean实例,因为从缓存中获取到的对象有可能是factoryBean;
三:若单例缓存中获取不到相应实例,则创建实例对象:
1、根据beanName获取缓存中的beanDefinition对象,并将其转化为RootBeanDefinition类型;
2、先分析单例模式:若bean为单例模式,则执行以下代码:
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
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);
}
可以看到,在这个代码段中,会创建一个工厂实例,后续会调用createBean(beanName, mbd, args)方法进行bean实例的创建;
进入createBean(beanName, mbd, args)内部:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
....
//解析class,创建class对象存储在beanFactory中
resolveBeanClass(mbd, beanName);

// Prepare method overrides.
try {
//对override属性进行验证和标记
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.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, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}

Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}

未完待续
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值