【Spring -- 02 BeanFactory 】

BeanFactory 是 Spring 框架的核心接口之一,负责管理 Spring 应用上下文中的所有 bean 对象。它是一个简单的 IOC(Inversion of Control)容器,是 ApplicationContext 的基础。以下是对 BeanFactory 接口的一些详细介绍:

主要功能

  1. 依赖注入BeanFactory 通过依赖注入机制管理和提供对象依赖关系。它根据配置元数据(通常是 XML 文件或注解)来实例化、配置和组装对象​ (Home)​。

  2. 延迟初始化BeanFactory 采用延迟初始化策略,即只有在第一次访问 bean 时才会创建该 bean 实例。这与 ApplicationContext 的预初始化策略不同,后者会在容器启动时创建所有单例 bean​ (Home)​。

  3. Bean 配置和管理BeanFactory 提供了多种方法来获取和管理 bean 实例,例如 getBean(String name)getBean(Class<T> requiredType) 等​ (Home)​​ (Home)​。

主要方法

  • Object getBean(String name): 通过 bean 的名称来获取 bean 实例。
  • Object getBean(String name, Object... args): 获取具有特定构造函数参数的 bean 实例。
  • <T> T getBean(Class<T> requiredType): 通过 bean 的类型来获取 bean 实例。
  • <T> T getBean(Class<T> requiredType, Object... args): 获取具有特定构造函数参数和类型的 bean 实例。
  • boolean containsBean(String name): 检查容器中是否包含指定名称的 bean。
  • boolean isSingleton(String name): 判断指定名称的 bean 是否为单例模式。
  • boolean isPrototype(String name): 判断指定名称的 bean 是否为原型模式。
  • boolean isTypeMatch(String name, Class<?> typeToMatch): 检查指定名称的 bean 是否匹配给定的类型。

与 ApplicationContext 的关系

BeanFactory 是 Spring IOC 容器的最基本接口,而 ApplicationContext 是其高级子接口。ApplicationContextBeanFactory 的基础上添加了许多企业级特性,如国际化支持、事件传播、和不同的上下文实现(如 WebApplicationContext)等。ApplicationContext 通常在实际开发中更常用,因为它提供了更多的功能和更简便的使用方式​ (Home)​​ (Home)​。

使用场景

BeanFactory 适合资源受限的环境,例如移动设备或嵌入式系统,因为它比 ApplicationContext 更轻量级。尽管如此,开发人员在大多数情况下更倾向于使用 ApplicationContext,因为它提供了更全面的功能支持。

参考资料

类图

BeanFactory 接口 和 实现类 DefaultListableBeanFactory

 实现类 DefaultListableBeanFactory

BeanFactory 通过 registerBeanDefinition 方法注册一个 BeanDefinition 对象。BeanDefinition 描述了 bean 的详细信息,包括 scope(范围)、创建方式(构造函数或工厂方法)、初始化方法和销毁方法等。这些定义为 Spring 容器管理 bean 的创建和生命周期提供了蓝图。

Bean Definition

BeanDefinition 包含以下几个重要方面:

  • Scope:bean 的作用范围,如 singleton 或 prototype。
  • 创建方式:通过构造函数或工厂方法创建。
  • 初始化和销毁方法:在 bean 的生命周期中调用的初始化和销毁回调方法。
  • 属性和依赖:bean 所需的属性和依赖项注入信息。

注册 Bean Definition

我们常用的配置类、XML 配置、组件扫描等方式都是在生成 BeanDefinition 对象后,将其注册到 BeanFactory 中。例如:

  • 配置类:使用 @Configuration@Bean 注解。
  • XML 配置:通过 <bean> 元素定义。
  • 组件扫描:使用 @ComponentScan 注解扫描包路径下的组件。

BeanFactory 增强处理

BeanFactory 需要手动调用 BeanFactory 后处理器(BeanFactoryPostProcessor)来增强其功能。后处理器可以解析特定注解(如 @Bean@ComponentScan),并补充 BeanDefinition。典型的 BeanFactory 后处理器包括 ConfigurationClassPostProcessorComponentScanAnnotationParser 等。

添加 Bean 后处理器

BeanFactory 还需要手动添加 Bean 后处理器(BeanPostProcessor),以在 bean 创建过程中提供增强功能。例如,@Autowired@Resource 注解的解析就是通过 Bean 后处理器完成的。常见的 Bean 后处理器包括 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor

初始化单例 Bean

BeanFactory 需要手动调用 preInstantiateSingletons 方法来初始化单例 bean。这个方法会确保所有定义为单例的 bean 在容器启动时都被实例化和初始化。

解析 ${} 和 #{}

为了解析属性占位符(${})和 Spring 表达式语言(#{}),BeanFactory 需要额外的设置。例如,可以通过添加 PropertySourcesPlaceholderConfigurer 来解析 ${},通过 StandardBeanExpressionResolver 来解析 #{}

示例代码:

package org.liuy;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedList;

@Slf4j
public class BeanfactoryTest {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("config", beanDefinition);

        // beanFactory 后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor->{
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        // bean 后处理器
        beanFactory.getBeansOfType(BeanPostProcessor.class).values()
                .forEach(beanPostProcessor -> beanFactory.addBeanPostProcessor(beanPostProcessor));

        // 预实例化
        beanFactory.preInstantiateSingletons();

        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }


//        log.info("beanFactory.getBean");
//        System.out.println(beanFactory.getBean("config"));

        System.out.println(beanFactory.getBean(Bean1.class).bean2);
//        System.out.println(beanFactory.getBean(Bean2.class));

    }
}

@Configuration
@Slf4j
class Config{
    public Config() {
        log.info("Config  Construct");
    }

    @Bean
    Bean1 bean1(){
        return new Bean1();
    }

    @Bean
    Bean2 bean2(){
        return new Bean2();
    }

}
@Slf4j
class Bean1{

    public Bean1() {
        log.info("Bean1  Construct");
    }

    @Autowired
    public Bean2 bean2;
}
@Slf4j
class Bean2{
    public Bean2() {
        log.info("Bean2  Construct");
    }
}

 

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值