Spring源码之getBean(获取 bean)方法(一)解读

测试类

一个简单的测试类

public class Test_2 {
   

    public static void main(String[] args) {
   
        /* 初始化启动 spring ioc 容器 */
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-spring.xml");
        /* 从 spring ioc 容器中获取一个 bean */
        ProductInfoService productInfoService = (ProductInfoService) applicationContext.getBean("productInfoServiceImpl");
        System.out.println("拿到的Bean为:" + productInfoService);
    }
}

对于 ApplicationContextClassPathXmlApplicationContext 类图如下

在这里插入图片描述

getBean() 源码解读

使用开发工具进入 DEBUG 模式,进入 getBean 方法,来到 AbstractApplicationContext 抽象类中

// 打上断点调试
ProductInfoService productInfoService = (ProductInfoService) applicationContext.getBean("productInfoServiceImpl");

查看 AbstractApplicationContext 中的 getBean 方法

@Override
public Object getBean(String name) throws BeansException {
   
	assertBeanFactoryActive();
	return getBeanFactory().getBean(name);
}

然后我们看这里的这个 getBean方法,实际上是调用了抽象类 AbstractBeanFactorydoGetBean 方法

查看 AbstractBeanFactorydoGetBean 方法

@SuppressWarnings("unchecked")
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
   

		/**
		 * 通过 name 获取 beanName。这里不使用 name 直接作为 beanName 有两个原因
		 * 1、name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 本身,而非 FactoryBean
		 *   实现类所创建的 bean。在 BeanFactory 中,FactoryBean 的实现类和其他的 bean 存储
		 *   方式是一致的,即 <beanName, bean>,beanName 中是没有 & 这个字符的。所以我们需要
		 *   将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 实例。
		 * 2、还是别名的问题,转换需要 &beanName
		 */
		final String beanName = transformedBeanName(name);
		Object bean;

		// 先从缓存中获取,因为在容器初始化的时候或者其他地方调用过getBean,已经完成了初始化
		Object sharedInstance = getSingleton(beanName);
		// 如果已经初始化过,直接从缓存中获取
		if (sharedInstance != null && args == null) {
   
			// 如果beanName的实例存在于缓存中
			if (logger.isDebugEnabled()) {
   
				if (isSingletonCurrentlyInCreation(bea
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值