我想将一个豆子(我们称之为
clientStub
)注入到我的service
豆子中。
为此有两个要求:
clientStub
bean,我需要访问 @Client
注释,它携带一些重要信息,用于在属性中查找相关配置。@Bean
方法参数注入)预期用途:
@Autowired
public MyService(
@Client("invoice-manager") InvoiceManagerClientStub clientStub,
SomeOtherBean bean1, ...) {
或
@Bean
MyService myService(
@Client("invoice-manager") InvoiceManagerClientStub clientStub,
SomeOtherBean bean1, ...) {
所以我想做与
@Value
注释相同的事情,例如从参数上的注释派生值(加上一些内部查找)。
不幸的是,通常的
BeanFactory
似乎不知道目标的注释。
考虑替代方案
使用
BeanPostProcessor
将值注入带注释的字段中。嗯,这就是我目前正在做的事情,但是拥有一个带有单个 setter 进行注入的不可变类感觉不太好。
将其注入到字段中,然后将其公开为 bean 或手动调用构造函数更糟糕。
创建注入类的代理实例。这是不可能的,因为注入的类是生成的+最终的,而不是我的库的一部分。
从 bean 名称派生配置:不确定如何实现这一点以及如何向用户解释配置参数应在其属性文件中命名。我也想避免 bean 名称冲突。
非目标
覆盖任何核心 bean。我想将扩展作为库分发(基于 spring-boot),因此应避免过度替换 spring 内部 bean。
TLDR
如何告诉 spring 使用我的注释的值(解析器)解析参数?
已经沉默了四年:)但实际上有一种方法(并且已经存在很长时间了)。您可以使用原型作用域 bean 并将 InjectionPoint 实例注入到您的 bean 类或 bean 方法中。
示例文章:https://moelholm.com/blog/2016/10/09/spring-43-introducing-the-injectionpoint-class
示例:
@Configuration
public class ClientConfig {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public ClientStub client(InjectionPoint injectionPoint) {
Client client = Optional.ofNullable(injectionPoint.getAnnotation(Client.class)).orElseThrow();
return new ClientStub(client);
}
}