如何解决Micronaut - 创建、获取和销毁 ApplicationContext bean
我需要动态创建和销毁 HttpClient
对象,以对应客户在我的 Micronaut 应用程序中注册/注销自己。作为其中的一部分,我想将它们作为 bean 添加到应用程序上下文中,以便它们在项目中也自动使用自定义 HttpFilter
。
我认为使用名称为 ApplicationContext
的 Qualifier
bean 方法来管理这些 bean 来管理这些 bean 是相当简单的,但是这些 API 的行为方式似乎让我感到困惑:
-
applicationContext.createBean(HttpClient.class,Qualifiers.byName("myLabel"),myUrl)
失败:
io.micronaut.context.exceptions.NoSuchBeanException: No bean of type
[io.micronaut.http.client.HttpClient] exists. Make sure the bean is not disabled by bean
requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the
bean is enabled then ensure the class is declared a bean and annotation processing is
enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as
an annotation processor).
为什么 bean 存在那么重要?我正在尝试创建它!
-
applicationContext.findBean(HttpClient.class)
失败:
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [io.micronaut.http.client.DefaultHttpClient]
Message: Missing bean argument [LoadBalancer loadBalancer] for type: io.micronaut.http.client.DefaultHttpClient. Required arguments: LoadBalancer loadBalancer,HttpClientConfiguration configuration,String contextPath,HttpClientFilterResolver filterResolver
为什么要尝试创建它?我只想找到它!
(注意。applicationContext.getBean(HttpClient.class,Qualifiers.byName("myLabel"))
可以在这里工作,但因为我无法解决第一点,我无法验证这一点)
-
applicationContext.destroyBean(HttpClient.class)
不允许在方法中指定Qualifier
,这意味着我不能使用它从上下文中删除 bean。它还在没有限定符 (applicationContext.createBean(HttpClient.class,myUrl)
) 的 bean 创建后返回 null,这表明它无论如何都找不到创建的 bean...
我认为我在这里使用了错误的 API,但正确的 API 是什么?
总而言之,我很困惑 - 欢迎任何有关正确使用这些 API 的帮助。
解决方法
HttpClient
是用于定义 http 客户端而不是 bean 的接口(请注意,Micronaut 提供的默认 ~ DefaultHttpClient
~ 实现不是豆)。因此,对上述 ApplicationContext
上下文查找或实例化方法的任何调用都将导致错误:
ApplicationContext#createBean
ApplicationContext#findBean
ApplicationContext#getBean
- ... // 其他实例化方法
请注意,这是有意设计的,因为 HttpClient
API 旨在自动注入并通过 AOP 建议进行操作。
您可以注入一个原始的(使用默认方法)HttpClient
:
@Singleton
public class MyBeanIml implements MyBean {
@Client
HttpClient client;
// ...
}
或者对于自定义方法,生成的实现,您可以使用HttpClient
声明性实现:
@Client("endpoint-uri")
public interface MyHttpClient {
@Get
String query();
// ...
}
如果没有指定创建自定义的确切要求(顺便说一下,动态在这种情况下太模糊)HttpClient
s,您可以采用的方法是拥有一个自定义 {{ 1}}d bean 包装 injected @Prototype
可以使用您的自定义参数进行实例化,您可以在其中将您的方法委托给包装的 HttpClient
或实现您的自定义方法:>
HttpClient
然后您可以使用 @Prototype
public class CustomHttpClientImpl implements CustomHttpClientImpl.CustomHttpClient {
@Inject
@Client
private final HttpClient httpClient;
private final String endpoint;
public CustomHttpClientImpl(@Parameter String endpoint,HttpClient httpClient) {
this.httpClient = httpClient;
this.endpoint = endpoint;
}
@Override
public String query() {
return this.httpClient.toBlocking()
.exchange(HttpRequest.GET(URI.create(this.endpoint)),String.class)
.body();
}
// delegate to the `httpClient` bean or implement your custom API querying methods
public interface CustomHttpClient {
String query();
}
}
创建您的 Prototype
d bean 实例:
ApplicationContext
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。