Spring源码系列——FactoryBean源码解析

前言

在实际开发当中,如果偏向于系统基础架构开发的话,对于FactoryBean的使用应该不会特别陌生。FactoryBean和BeanFactory这二者经常会被拿出来比较,原因在于这二者的名字看起来很容易让人混淆,然而这二者的原理和作用完全不一样。本篇文章将围绕FactoryBean展开源码解析。

FactoryBean接口

public interface FactoryBean<T> {
   
	// 返回创建的bean对象
	T getObject() throws Exception;
    // bean对象的Class类型
    Class<?> getObjectType();
    // bean对象是否是单例,默认为单例。
    default boolean isSingleton() {
   
		return true;
	}
}

实现FactoryBean

@Component("myDemoService")
public class MyDemoFactoryBean implements FactoryBean<MyDemoService> {
   
    @Override
    public MyDemoService getObject() throws Exception {
   
        return new MyDemoService();
    }

    @Override
    public Class<?> getObjectType() {
   
        return MyDemoService.class;
    }
}

我们来写一个类测试一下,看看能够从容器中获取到MyDemoFactoryBean和MyDemoService这两个bean:

@Configuration
@ComponentScan("com.leon.factorybean")
public class Config {
   
}
public class MyApplication {
   
    public static void main(String[] args) {
   
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
        String[] myDemoTactoryBeanNames = applicationContext.getBeanNamesForType(MyDemoFactoryBean.class);
        String[] myDemoServicBeanNames = applicationContext.getBeanNamesForType(MyDemoService.class);
        System.out.println(JsonUtil.convert(myDemoTactoryBeanNames));
        System.out.println(JsonUtil.convert(myDemoServicBeanNames));
    }
}

执行结果如下:

["&myDemoFactoryBean"]
["myDemoFactoryBean"]

可以看到,确实可以从IOC容器中获取分别获取到MyDemoFactoryBean和MyDemoService这两个bean。这说明:

  • FacotryBean也是bean,受IOC容器管理;
  • FacotryBean可以生产指定的bean,即FacotryBean#getObject()返回的对象;
  • BeanName:默认情况下,FactoryBean的beanName为【&】+ 【类名<首字母小写>】;而它生产的bean的beanName就为【类名<首字母小写>】。
    接下来,我们来看看FactoryBean在Spring中是如何解析的。

FactoryBean源码追踪

1.入口

在Spring当如,追踪源码的方式最直接的方式就是通过applicatonContext.getBean方式。

MyDemoFactoryBean myDemoFactoryBean = applicationContext.getBean(MyDemoFactoryBean.class);

2.委托给AbstractApplicationContext#getBean

实际调用的是AbstractApplicationContext#getBean(java.lang.Class),该方法其实也是空壳方法,实际将其委托给BeanFactory的getBean方法。

@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
   
    assertBeanFactoryActive();
    return getBeanFactory().getBean(requiredType);
}

3.再委托给DefaultListableBeanFactory#getBean(java.lang.Class)

getBeanFactory()实际上返回的是DefaultListableBeanFactory实例。到这里可以得知,DefaultListableBeanFactory是Spring当中的Be

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值