gpt4 book ai didi

spring - 使用 BeanDefinitionRegistryPostProcessor 创建 N 个 bean

转载 作者:行者123 更新时间:2023-12-03 14:10:25 41 4
gpt4 key购买 nike

我正在尝试使用 BeanDefinitionRegistryPostProcessor 动态创建 N 个 bean .基于 this问题,我选择使用 BeanDefinitionRegistryPostProcessor对于我的用例。

我在我的 application.yml 中定义了以下内容:

app:
downstream-services:
rest:
jsonPlaceHolder:
url: https://jsonplaceholder.typicode.com/todos
api-type: io.mateo.dynamicbeans.JsonPlaceHolderApi

连接到 ConfigiruationProperties在这里上课: https://github.com/ciscoo/dynamicbeans/blob/master/src/main/java/io/mateo/dynamicbeans/FeignConfigurationProperties.java

然后我想注入(inject) ConfigiruationProperties类以及我在这里定义的工厂 bean: https://github.com/ciscoo/dynamicbeans/blob/master/src/main/java/io/mateo/dynamicbeans/FeignClientAutoConfiguration.java

所以现在我有以下内容:

https://github.com/ciscoo/dynamicbeans/blob/master/src/main/java/io/mateo/dynamicbeans/FeignClientFactoryPostProcessor.java
@Component
public class FeignClientFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
private final FeignConfigurationProperties properties;
private final FeignClientFactory feignClientFactory;

public FeignClientFactoryPostProcessor(FeignConfigurationProperties properties, FeignClientFactory feignClientFactory) {
this.properties = properties;
this.feignClientFactory = feignClientFactory;
}

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
properties.getDownstreamServices().getRest().forEach((beanName, props) -> makeClient(beanName, props, registry));
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// no-op
}

private void makeClient(String beanName, FeignClientProperties props, BeanDefinitionRegistry registry) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(props.getApiType());
beanDefinition.setInstanceSupplier(() -> feignClientFactory.create(props));
registry.registerBeanDefinition(beanName, beanDefinition);
}
}

它应该创建的单个 bean 是在此处注入(inject)服务类: https://github.com/ciscoo/dynamicbeans/blob/master/src/main/java/io/mateo/dynamicbeans/JsonPlaceHolderService.java

我遇到的问题是:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.mateo.dynamicbeans.FeignClientFactoryPostProcessor]: No default constructor found; nested exception is java.lang.NoSuchMethodException: io.mateo.dynamicbeans.FeignClientFactoryPostProcessor.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1262) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
... 17 common frames omitted
Caused by: java.lang.NoSuchMethodException: io.mateo.dynamicbeans.FeignClientFactoryPostProcessor.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3350) ~[na:na]
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2554) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
... 18 common frames omitted

但是当我删除 final来自两个属性和定义的构造函数的关键字,我得到一个 NullPointerException .

那么如何动态创建N个bean 以便它们及时可用对于我的任何 @Service类使用?

我知道 https://spring.io/projects/spring-cloud-openfeign .我在这里重新创建了我的问题,以说明我在动态创建 SOAP 客户端的不同项目中遇到的相同问题。

更新 :进行以下更改: https://github.com/ciscoo/dynamicbeans/commit/4f16de9d03271025cd65d95932a3e854c0619c29 ,现在我可以完成我的用例了。

最佳答案

正如您链接到的问题的答案所暗示的那样,您不能将依赖项注入(inject) bean 工厂后处理器。您需要以编程方式绑定(bind)它,而不是注入(inject)您的配置属性类。在 Spring Boot 2.x 中,即 achieved using the Binder API :

The new Binder API can also be used outside of @ConfigurationProperties directly in your own code. For example, the following will bind to a List of PersonName objects:

List<PersonName> people = Binder.get(environment)
.bind("my.property", Bindable.listOf(PersonName.class))
.orElseThrow(IllegalStateException::new);

The configuration source could be represented in YAML like this:

my:
property:
- first-name: Jane
last-name: Doe
- first-name: John
last-name: Doe

关于spring - 使用 BeanDefinitionRegistryPostProcessor 创建 N 个 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53462889/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com