Spring Framework源码解析——BeanFactory


版权声明

  • 本文原创作者:谷哥的小弟
  • 作者博客地址:http://blog.csdn.net/lfdfhl

在这里插入图片描述

1. BeanFactory 概述

BeanFactory 是 Spring IoC 容器的最基础接口,它定义了获取、配置和管理 Bean 的核心方法。它是 Spring 框架中容器体系的顶层接口之一,提供了最基本的依赖注入功能。

1.1 接口定义

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String name) throws BeansException;

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    boolean containsBean(String name);

    boolean isSingleton(String name) throws BeansException;

    boolean isPrototype(String name) throws BeansException;

    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws BeansException;

    Class<?> getType(String name) throws BeansException;

    String[] getAliases(String name);
}
  • getBean:获取容器中已注册的 Bean 实例。
  • containsBean:判断某个名称的 Bean 是否存在。
  • isSingleton / isPrototype:判断 Bean 的作用域。
  • getType / isTypeMatch:获取或匹配 Bean 的类型。
  • getAliases:获取某个 Bean 的所有别名。

1.2 与 ApplicationContext 的关系

  • BeanFactory 是 Spring 容器的基础接口。
  • ApplicationContext 是其子接口,扩展了 BeanFactory 的功能,增加了国际化、事件发布、资源加载等高级功能。
  • BeanFactory 是“按需加载”,而 ApplicationContext 是“预加载单例 Bean”。

2. 核心实现类

DefaultListableBeanFactory 是 Spring 中最常用的 BeanFactory 实现类,它实现了 BeanDefinitionRegistry 接口,支持注册和管理 Bean 定义。

2.1. 核心属性

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {

    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
}
  • beanDefinitionMap:存储 Bean 名称与 BeanDefinition 的映射关系。
  • beanDefinitionNames:存储所有已注册的 Bean 名称列表。

2.2 注册 Bean 定义

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException {
    this.beanDefinitionMap.put(beanName, beanDefinition);
    if (!this.beanDefinitionNames.contains(beanName)) {
        this.beanDefinitionNames.add(beanName);
    }
}
  • 将 Bean 定义放入 beanDefinitionMap 中。
  • 将 Bean 名称加入 beanDefinitionNames 列表。

3. Bean 的加载过程

getBean() 是获取 Bean 的核心方法。其调用链如下:

getBean()doGetBean()getSingleton()createBean()doCreateBean()populateBean()initializeBean()

3.1 doGetBean() 方法

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    final String beanName = transformedBeanName(name);
    Object sharedInstance = getSingleton(beanName);
    
    if (sharedInstance != null && args == null) {
        // 如果是 FactoryBean,处理 & 前缀
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
        // 创建 Bean
        bean = createBean(beanName, mbd, args);
    }

    return (T) bean;
}
  • transformedBeanName:处理 & 前缀(用于获取 FactoryBean 本身)。
  • getSingleton:尝试从单例缓存中获取 Bean。
  • createBean:如果不存在,调用 createBean 创建新实例。

3.2 单例 Bean 的创建

3.2.1 getSingleton() 方法

public Object getSingleton(String beanName) {
    return this.singletonObjects.get(beanName);
}
  • singletonObjects:是一个 Map<String, Object>,缓存所有已创建的单例 Bean。

3.2.2 创建 Bean 的流程

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 1. 解析 Bean 的 Class
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    
    // 2. 实例化 Bean
    Object beanInstance = instantiateBean(beanName, mbd);
    
    // 3. 属性注入
    populateBean(beanName, mbd, instanceWrapper);
    
    // 4. 初始化 Bean
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    
    // 5. 注册为单例
    addSingleton(beanName, exposedObject);
    
    return exposedObject;
}

4. Bean 的生命周期

Spring 中 Bean 的生命周期由 BeanFactory 管理,其流程如下:

  1. 实例化:通过构造方法或工厂方法创建 Bean 实例。
  2. 属性注入:注入依赖的其他 Bean 或配置值。
  3. 初始化前回调:如 BeanNameAwareBeanFactoryAware 等接口的回调。
  4. 初始化方法调用:如 @PostConstructInitializingBean 接口或配置的 init-method
  5. 使用 Bean:Bean 可以被使用。
  6. 销毁前回调:如 @PreDestroyDisposableBean 接口或配置的 destroy-method
  7. 销毁 Bean:清理资源。

初始化 Bean 示例如下:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 调用 Aware 接口方法
    invokeAwareMethods(beanName, bean);

    // 调用初始化方法
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    invokeInitMethods(beanName, wrappedBean, mbd);

    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

5. 工厂 Bean(FactoryBean)

FactoryBean 是一种特殊的 Bean,它本身是一个工厂,用于创建其他 Bean。

5.1 接口定义

public interface FactoryBean<T> {
    T getObject() throws Exception;
    Class<?> getObjectType();
    boolean isSingleton();
}

5.2 获取 FactoryBean 实例

Object bean = getBean("&myFactoryBean");
assertTrue(bean instanceof FactoryBean);
  • 使用 & 前缀获取 FactoryBean 本身。
  • 不带前缀则获取其 getObject() 返回的 Bean。

6. Bean 的作用域(Scope)

Spring 支持多种作用域,包括:

  • singleton(默认):每个容器中只有一个实例。
  • prototype:每次调用 getBean() 都返回一个新实例。
  • request / session(Web 作用域):每个请求或会话一个实例。

作用域实现机制如下:

public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    return mbd.isSingleton();
}
  • RootBeanDefinition 中保存了 Bean 的作用域配置。

7. BeanFactory 的扩展机制

7.1 BeanFactoryPostProcessor

允许在 Bean 实例化之前修改 BeanDefinition

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

示例:

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        BeanDefinition beanDef = beanFactory.getBeanDefinition("myBean");
        beanDef.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    }
}

7.2 BeanPostProcessor

允许在 Bean 实例化前后进行干预。

public interface BeanPostProcessor {
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

8. BeanFactory 与 ApplicationContext 的对比

特性BeanFactoryApplicationContext
初始化时机按需加载(懒加载)启动时预加载单例 Bean
功能特性仅提供基本的依赖注入提供国际化、事件发布、资源加载等高级功能
资源加载仅支持类路径加载支持多种资源加载方式(如 Ant 路径)
扩展点支持需手动注册 BeanPostProcessor 等组件自动注册并调用扩展点

9. 核心代码示例与解释

9.1 手动注册 Bean 定义并获取 Bean

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
RootBeanDefinition definition = new RootBeanDefinition(MyBean.class);
factory.registerBeanDefinition("myBean", definition);

MyBean bean = factory.getBean("myBean", MyBean.class);
System.out.println(bean);
  • 创建 DefaultListableBeanFactory
  • 定义 BeanDefinition
  • 注册 Bean 定义。
  • 获取 Bean 实例。

9.2 使用 BeanFactoryPostProcessor 修改 Bean 定义

factory.addBeanPostProcessor(new CustomBeanFactoryPostProcessor());
  • 将自定义的 BeanFactoryPostProcessor 添加到容器中。

10. 总结

BeanFactory 是 Spring IoC 容器的核心接口之一,它提供了最基本的依赖注入功能。其设计体现了模块化、可扩展性和灵活性,是构建 Spring 容器体系的基础。通过理解其源码结构、生命周期管理、Bean 加载机制以及扩展机制,开发者可以更深入地掌握 Spring 的运行原理,并在实际项目中更好地进行配置和优化。实践建议如下:

  1. 优先使用 ApplicationContext:在企业级应用中推荐使用,因其提供了更全面的功能。
  2. 理解 BeanFactory 的懒加载机制:适用于资源受限的场景。
  3. 合理使用 BeanPostProcessorBeanFactoryPostProcessor:用于扩展容器行为。
  4. 避免过度依赖 BeanFactory 的底层 API:保持代码的可测试性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谷哥的小弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值