Какой хук Spring Framework я использую на динамически зарегистрированных сторонних bean-компонентах?
У меня есть BeanDefinitionRegistryPostProcessor
, который я использую для динамического сканирования пути к классам и создания нескольких третьих партийные бобы (экземпляры gRP C AbstractStub
). Мне нужно зарегистрировать ClientInterceptors
на заглушке, чтобы дополненный AbstractStub
был готов к обработке заявки. Я использую динамически создаваемый *Stub
@Beans
, чтобы исключить все шаблоны @Bean
и обеспечить согласованные конфигурации каналов.
Ограничения
- Реализации
AbstractStub
соответствуют gRP C порожденные классы. Мои классы расширяются AbstractStub
. - Предпочтительный фабричный метод stati c - метод
builder(Channel)
; это то, что используется при ручной компиляции @Bean
объявлений. - Для каждой заглушки требуется
Channel
в качестве зависимости. Есть несколько Channel
@Beans
.
Попытки
Я пробовал три подхода:
Подход 1: BeanDefinitionBuilder
+ Supplier
Функция
BeanDefinitionBuilder.genericBeanDefinition(Class, Supplier)
не позволили ввести зависимость Channel
.
void registerBeanDefintion(final Class<S> clazz, final BeanDefinitionRegistry registry) {
Supplier<S> stubSupplier = () -> {
clazz.getConstructor({Channel.class});
return BeanUtils.instantiateClass(constructor, null); // fails here; no Channel
}
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(clazz, stubSupplier);
builder.addDependsOn(MANAGED_CHANNEL_BEAN_NAME);
builder.addConstructorArgReference(MANAGED_CHANNEL_BEAN_NAME);
registry.registerBeanDefinition(clazz.getName(), builder.getBeanDefinition());
Подход 2: BeanDefinitionBuilder
с CallOption
крючками
Невозможно зарегистрировать ClientInterceptor
в BeanDefinition.
void registerBeanDefintion(final Class<S> clazz, final BeanDefinitionRegistry registry) {
builder.addDependsOn(MANAGED_CHANNEL_BEAN_NAME);
builder.addConstructorArgReference(MANAGED_CHANNEL_BEAN_NAME);
CallOptions callOptions = CallOptions.DEFAULT;
// no hook in CallOptions to register ClientInterceptor
registry.registerBeanDefinition(clazz.getName(), builder.getBeanDefinition());
Подход 3: postProcessBeanFactory()
postProcessBeanFactory
не работает на экземплярах bean-компонентов, поэтому зависимости предварительно не разрешаются.
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
Iterator<String> iterator = configurableListableBeanFactory.getBeanNamesIterator();
while (iterator.hasNext()) {
String beanName = iterator.next();
if (beanName.endsWith("Stub")) {
AbstractStub stub = (AbstractStub) configurableListableBeanFactory.getBean(beanName); //fails
stub.withInterceptors(newClientInterceptor()); // never gets executed
}
}
}