美文网首页
6.注册Bean

6.注册Bean

作者: wyh001 | 来源:发表于2023-09-29 14:27 被阅读0次

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

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

一、配置元数据注册接口

bean元数据注册接口.png

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

二、单例对象注册接口

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

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

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

创建单例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);
    }
}

接口类图如下:

注册依赖.png

四、使用时机

Ioc容器启动时

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

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

    • BeanFactoryPostProcessor
    • BeanDefinitionRegistryPostProcessor

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

启动后运行中

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

相关文章

  • 注册bean

    使用步骤 加载配置文件 对于Spring来说,xml,properties,yaml,包括class文件都是配置文...

  • 通过配置文件注册Bean

    通过id注册一个bean并在class中写入改bean的Java文件,这样就注册了一个bean,scope用来规定...

  • Spring自定义标签解析与实现

    在Spring Bean注册解析(一)和Spring Bean注册解析(二)中我们讲到,Spring在解析xml文...

  • 动态注册bean

    干货点: 看完该篇文章我们可以了解到为何要动态注册bean、动态注册bean的方式、注册和实例化的区别、sprin...

  • BeanDefinition的注册

    BeanDefinition的注册 根据 beanName注册 beanDefinition, bean 的 na...

  • Bean的创建、注册以及获取

    [TOC] Bean的创建、注册以及获取 前言: 1.Spring基于XML配置bean和基于编程式(@Bean)...

  • Spring 常用注解

    一、注解的分类    主要分为两大类:使用Bean注解、注册Bean注解。 使用Bean的注解    @Autow...

  • 180804-Spring之动态注册bean

    Spring之动态注册bean 什么场景下,需要主动向Spring容器注册bean呢? 如我之前做个的一个支持扫表...

  • Spring相关技术自检表

    IOC组件注册-@Configuration&@Bean给容器中注册组件组件注册-@ComponentScan-自...

  • spring梳理(二) 基于注解的方式注册bean

    我们知道,如果想要将bean交由spring容器管理,就需要首先将bean注册在spring容器中,而bean可以...

网友评论

      本文标题:6.注册Bean

      本文链接:https://www.haomeiwen.com/subject/puprbdtx.html