当前位置: 首页>后端>正文

6.注册Bean

向IoC中注册bean,有两种方式,分别是向其注册bean配置元数据和注册一个创建完成的单例对象,前者容器将负责bean实例的创建、依赖注入和生命周期的管理。这两种方式管理的对象均可用于依赖注入和依赖查找。

此外,还存在一种注册“依赖”的方式,一般用于框架内部使用,这种方式注册的对象只能用于依赖注入,不能用于依赖查找。

一、配置元数据注册接口

6.注册Bean,第1张
bean元数据注册接口.png

DefaultListableBeanFactory实现注册接口,使用Map保存配置元数据

二、单例对象注册接口

  1. 管理单例对象
    • 管理通过配置元数据定义的单例bean
    • 支持直接注册由外部创建的单例对象
  2. 具体实现
6.注册Bean,第2张
单例bean注册.png

默认实现类是DefaultSingletonBeanRegistry,其内部是通过Map对单例对象进行管理的。该类也等效实现了Scope接口的功能

getSingleton(String, ObjectFactory<?>)方法实现逻辑如下图:

6.注册Bean,第3张
创建单例bean的流程.png

该方法可看作是Scope#get(String,ObjectFactory<?>)的等效实现

Scope支持创建各种不同作用域的bean,容器创建bean默认实现了单例和原型两种作用域

注意:从Scope中移除对象不等同于销毁对象

Spring Cloud中RefreshScope扩展了Scope接口,用于支持bean的动态刷新

三、注册依赖

一般是由框架内部使用,如:

// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

这些依赖可用于依赖注入,但是不能被依赖查找

示例:

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(S6Configuration.class);
    context.refresh();

    // 框架内部注册的依赖,依赖注入成功
    final S6Service s6Service = context.getBean(S6Service.class);
    // 打印出被注入的依赖
    s6Service.show();

    // 框架内部注册的依赖,依赖查找失败
    // 报错
    final BeanFactory beanFactory = context.getBean(BeanFactory.class);
    log.info("[{}]", beanFactory);
}
@Slf4j
@Service
public class S6Service {

    @Autowired
    private BeanFactory beanFactory;

    @Autowired
    private ApplicationContext applicationContext;

    public void show() {
        log.info("beanFactory={}", beanFactory);
        log.info("applicationContext={}", applicationContext);
    }
}

接口类图如下:

6.注册Bean,第4张
注册依赖.png

四、使用时机

Ioc容器启动时

  1. 解析xml配置文件、注解等配置元数据,调用上述接口进行注册,解析过程详见前述章节

  2. 使用容器生命周期接口注册

    • BeanFactoryPostProcessor
    • BeanDefinitionRegistryPostProcessor

    该接口执行时机比较早,在实例化bean之前会被容器优先调用

启动后运行中

在容器运行中注册bean,会导致其不能和其他bean很好地协作,因为此时,其他bean可能已经被实例化了


https://www.xamrdz.com/backend/3np1936055.html

相关文章: