将bean注册到Spring上下文是一种反范式吗



假设我们有一个配置文件作为应用程序的资源。该资源文件包含一个键,该键包括一个对象数组,每个对象声明一个配置以实例化Foo对象。

通常,我们可以用@Component|Service|Configuration|...注释我们的类型,因此它将在Spring的应用程序上下文中可用,或者我们可以简单地声明bean工厂,以显示对象应该如何在应用程序容器中实例化。

这一次,我想创建许多具有相同类型(即Foo)但具有不同配置的对象。它们中的每一个都有一个唯一的bean名称,所以我可以@Autowired所有这些bean,只需声明一个Map<String, Foo>字段,Spring Framework将其作为键值对列表注入,该列表包含与其名称相关联的bean。

这个问题更具哲理。Spring Framework通过使用依赖注入,利用控制反转的原理,因此我们正在卸载类所依赖对象的生命周期管理。

由于Spring不关心我在配置文件中所做的事情,所以以编程方式注册bean是一种反范式吗?

通过使用BeanDefinitionRegistryPostProcessor,您可以通过编程方式定义bean的配置。它只是一个bean配置,而不是一个bean实例。Spring将创建bean实例,并根据bean配置管理其生命周期。

因此,在最后,bean仍然由Spring创建和管理,这并不违反IoC哲学,该哲学提倡let容器创建bean,而不是由开发人员自己创建。

注册Spring bean和Spring管理这些bean的生命周期是单独的操作。需要让Spring可以使用所有的bean,这样Spring就可以管理它们的生命周期。

有几种注册bean的方法(不是详尽的列表)。

  • XML文件
  • Java注释—@ComponentScan/@Configuration/@Component就是这种注册的一些示例。

  • PostProcessors是另一种方法。

  • spring.factories-您甚至可以在META-INF/spring.factories下的一个特殊属性下添加所有bean,并使所有bean可用于Spring启动应用程序。

  • 候选组件索引
  • 向供应商注册的功能性风格是懒惰的,没有反映成本。参见[1]

您甚至可以混合和匹配上面的一个或多个机制,Spring将尊重所有这些机制。

要回答您上面给出的具体问题:

> Is it an anti-paradigm to register that beans programmatically, since Spring does not take care of what I did in the configuration file?

绝对不是。您可以用一种或多种方式注册bean,但这不会改变Spring在连接依赖关系时处理它们的方式。

之所以有这么多注册机制,是为了让应用程序开发人员可以根据他们的用例选择最合适的机制,希望迁移到更新、优化的方法。

当您在Map<String, Foo>中请求特定类型的所有bean时,Spring将为您提供所有依赖项,而不管它们是如何注册的。

坚持使用一些对你有用的注册机制(尽可能小),这样你的队友就可以理解并维护豆子是如何连接的。

[1] -春季5.x 的新功能

正如您所指出的,IoC/DI就是将对象构建和管理的责任委派给框架。

话虽如此,如果扩展框架,即实现BeanDefinitionRegistryPostProcessor,Spring仍将管理bean和以下注入。这不会违背IoC的定义

现在,更详细地说,如果您在运行时从杂项类以编程方式访问上下文以获得bean,那么您将打破IoC模式。通过这样做,您将把了解如何构建自己的责任回馈给类。

我的经验法则是,我的类对Spring的实现细节(松耦合)了解得越少越好此外,如果您在Spring的生命周期之后注册bean(在BeanFactoryPostProcessor运行之后不创建bean),那么您将只使用框架的自然路径。

最新更新