Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过编程模仿@Bean方法将多个实例注册为Bean_Java_Spring_Applicationcontext_Spring Bean - Fatal编程技术网

Java 通过编程模仿@Bean方法将多个实例注册为Bean

Java 通过编程模仿@Bean方法将多个实例注册为Bean,java,spring,applicationcontext,spring-bean,Java,Spring,Applicationcontext,Spring Bean,(spring boot 1.5,java 8) 假设有一个基础,一些墙类型和天花板。他们彼此依赖,就像他们的物理对手一样 这个配置类有一个基础被注入并产生墙豆,所以天花板可以被注入墙壁。不要介意这些不好的做法,我只是试图在不改变基本机制的情况下使代码尽可能短 @Configuration class Config { @Autowired Foundation foundation; @Bean // assume there is a lot of repetitive l

(spring boot 1.5,java 8)

假设有一个基础,一些墙类型和天花板。他们彼此依赖,就像他们的物理对手一样

这个配置类有一个基础被注入并产生墙豆,所以天花板可以被注入墙壁。不要介意这些不好的做法,我只是试图在不改变基本机制的情况下使代码尽可能短

@Configuration
class Config {
  @Autowired
  Foundation foundation;

  @Bean
  // assume there is a lot of repetitive logic here
  WoodenWall wood() { return new WoodenWall(foundation); }

  @Bean
  BrickWall brick() { return new BrickWall(foundation); }
}
和天花板:

@Component
class KitchenCeiling {
  @Autowired
  WoodWall wall;
}

我将制作更多的墙类型,并希望它们都注册为bean。我不必为它们中的每一个定义
@Bean
方法,而是希望在一个循环中实例化它们,并在一次遍历中手动注册它们。如果您愿意,可以考虑一个
alltypesofwallsbeansfactory

@Configuration
class Config implements ??? {
  @Autowired
  Foundation foundation;

  @Override
  void addBeans(??? beanRegistry) {
    for (Class beanClass : wallClasses) {
      // instantiate BrickWall, WoodWall, etc
      registry.add(beanClass.getSimpleName(), beanClass, wallInstance);
    }
  }
}
问题是,我找不到正确的接口来实现,或者找不到正确的SpringBeanRegistryPostProcessorFactoryImplementationThingAjig去。我已经尝试了所有其他帖子的答案,所以我可以找到,但没有一个做正确的事情


这里的一个问题是,我需要上下文来初始化bean,因为我需要一个基础,但是我也想在上下文中添加更多的bean,这样,初始化的天花板可以注入我刚制作好的墙壁。

@Bean
方法正是这样做的:它们可以获取已经初始化的依赖项,并返回新的Bean,以便同时在其他地方使用。我只需要与这个确切机制相当的程序

我知道在这种情况下,依赖项解析比较困难(因为spring没有任何反射信息来计算下面的总顺序),但必须有可能告诉spring

  • 初始化它的依赖项
  • 处理新创建的bean
  • 转到1
  • BeanDefinition
    不符合要求,因为它不包含任何实例,要使用factoryMethod设置,我需要为每面墙创建一个factory类。回到原点

    大多数
    BeanDefinitionRegistryPostProcessor
    等接口调用得太晚,不要将我提供给它们的bean注入依赖bean(有1个引用了实例,但没有对它们执行任何操作),或者要求默认构造函数(即没有依赖项)。它们还倾向于为您提供只接受
    BeanDefinition
    的对象


    在另一个有类似需求的项目中,最终使用的是工厂方法,对于它需要生成的每个实例,仍然是
    @Bean
    方法。我开始认为这是不可能的,而且在这个项目中所做的一切都是最好的。

    您可以尝试将
    @PostConstruct
    ConfigurableApplicationContext

    @Configuration
    class Config {
    
      @Autowired
      Foundation foundation;
    
      @Autowired
      ConfigurableApplicationContext ctx;
    
      @PostConstruct
      void addBeans() {
        for (Class beanClass : wallClasses) {
          ctx.getBeanFactory().registerSingleton(beanClass.getSimpleName(), beanClass, wallInstance);
        }
      }
    
    }
    

    我将得出结论,要做到这一点是不可能的。最好的方法是为每个需要注册的Bean实例创建一个工厂方法和一个调用工厂的
    @Bean
    方法。似乎不可能从图片中删除
    @Bean
    方法。

    它可能不完全是您想要的,但是您可以在配置中添加上下文扫描,扫描您的墙包吗?它们将一次被正确地自动注册(这里是您的基础),这些对象不能被Spring实例化,它需要从库中获取一些自定义逻辑,这就是为什么我需要与工厂一起工作的代码>实现应用程序上下文软件< <代码> > <代码>((配置应用程序上下文)应用上下文)。.registerResolvableDependency(BrickWall.class,BrickWall)
    注册表单(“砖墙”,砖墙)
    工作正常,谢谢!我想知道我第一次做错了什么,我以前试过这种方法,但当时没有成功…事实上,这种方法不可靠。有时它会,有时它会抱怨豆子不存在。为该bean提供一个bean方法,它就会运行。重新启动它,现在它抱怨另一个bean。闻起来像是比赛条件和未定义行为的结果。