Java 通过编程模仿@Bean方法将多个实例注册为Bean
(spring boot 1.5,java 8) 假设有一个基础,一些墙类型和天花板。他们彼此依赖,就像他们的物理对手一样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
这个配置类有一个基础被注入并产生墙豆,所以天花板可以被注入墙壁。不要介意这些不好的做法,我只是试图在不改变基本机制的情况下使代码尽可能短
@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
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。闻起来像是比赛条件和未定义行为的结果。