当前位置: 首页 > 知识库问答 >
问题:

扩展抽象配置的spring·Java配置

冯通
2023-03-14

在我们的软件,我们使用spring Java配置。我们有一个设置,其中一个配置扩展了一个抽象配置。请看一下这个测试案例:


    import java.util.concurrent.atomic.AtomicInteger;
    import org.junit.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    public class SpringConfigTest {

      @Test
      public void test() {
        final AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
        ctx.getBeansOfType(AtomicInteger.class).entrySet().stream().forEach(
            b -> System.out.println(b.getKey() + " : " + b.getValue() + " (" + b.getValue().hashCode() + ")"));
      }

      @Configuration
      public static class MyConfig extends AbstractConfig {

        @Bean(name = "anotherName")
        public AtomicInteger myBean() {
          return new AtomicInteger(5);
        }
      }

      public static abstract class AbstractConfig {

        @Bean
        public AtomicInteger myBean() {
          return new AtomicInteger(10);
        }
      }
    }

其思想是,myconfig覆盖了abstractconfig并且在创建的ApplicationContext中只有一个AtomicInteger类型的bean位于名称AnotherName之下。

结果是:

anotherName : 5 (2109798150)
myBean : 5 (1074389766)

所以它说,有两个bean(两个实例--每个名称一个)--甚至更令人吃惊的是:创建这两个bean都使用了相同的方法(myconfig#mybean())。

这种行为在我们看来很奇怪:我们希望spring要么尊重通常的Java继承方式,只从myconfig创建bean...或者至少创建两个独立的bean(“10”和“5”),以防它将abstractconfig视为独立的配置。

在研究此问题时,我们还尝试在myconfig类上注册方法名:


public static class MyConfig extends AbstractConfig {

    @Bean(name = ["anotherName", "myBean"])
    public AtomicInteger myBean() {
    ...

而这次我们只有一个bean:anotherName:5(2109798150)

...更让我们吃惊的是。

有没有人知道这是正确的行为,还是我们只是用错了呢?我们是不是应该在spring的JIRA提一张罚单?提前道谢!

共有2个答案

陆才俊
2023-03-14

在spring,豆子可以先按类型连线,但再按名字连线。因此@qualifier(“myBeanname”)可以消除多个具有相同类型的bean的自带性歧义,例如。

so:非抽象bean被赋予了另一个名称,这一事实导致它在应用程序上下文中被视为不同的bean。

您可以在非配置类中声明bean。那被称为“Lite”模式,但在应用程序上下文中它仍然是一个bean。请参阅lite模式下的答案。

我不知道一个bean可以有多个名字,但由于spring bean默认为单例,因此在第二种情况下只能创建一个bean,因为“mybean”已经存在,并且应用程序上下文中只能有一个具有该名称的bean。

嵇浩然
2023-03-14

我不是spring专业人士,但我想说这种行为是有意为之的。为了实现您想要的(希望我猜对了)“注入这个bean而不是另一个”,您将在bean上使用@primary,根据情况有选择地启用配置,您将使用@conditional即@profile。

 类似资料:
  • 你可以通过 nuxt.config.js 文件中的 extend 配置项来扩展 Webpack 的配置: module.exports = { build: { extend (config, { isDev, isClient }) { // ... } } }

  • 我有一个关于春豆的问题。 有父类parent和构造函数(没有任何setter)。 Object1 obj1-对于任何子实例,它都是相同的对象。Object2 obj2、Object3 obj3-对于任何实例都可以是不同的 若我为父对象使用setter(我不能更改它),我可以声明抽象bean,为它设置object1obj1,然后我可以将它用作抽象bean(只设置obj2和obj3引用/值)。 是否有

  • 本文向大家介绍C#扩展抽象基类,包括了C#扩展抽象基类的使用技巧和注意事项,需要的朋友参考一下 示例 与接口(可以描述为实现合同)不同,抽象类充当扩展的合同。 抽象类无法实例化,必须对其进行扩展,然后可以实例化生成的类(或派生类)。 抽象类用于提供通用实现 上面的示例显示了实现Car的任何扩展类如何自动接收HonkHorn方法。这意味着任何开发新汽车的开发人员都无需担心它将如何鸣笛。

  • 我正在开发一个REST API与Spring引导v2.0.0。RELEASE与mongoDB耦合。使用sping-boot-starter-data-mongob连接MongoDB im。 正在申请中。属性我可以更改与mongodb相关的基本配置,但我的问题是,当涉及高级属性时,管理这些配置的最佳方式应该是什么。例如,不能通过应用程序更改每个主机的连接属性。财产。 因此,我使用了AbstractM

  • 问题内容: 我在Django中有一个扩展的UserProfile模型: 还有一个signal.py: 我通过在我的:中确保信号被注册: 因此,应该为每个注册用户创建一个新的UserProfile,对吗?但事实并非如此。尝试登录时,总是出现“ UserProfile匹配查询不存在”错误,这意味着该数据库条目不存在。 我应该说我使用django-registration,它提供了user_regist