我正在我的代码中注册事务管理器,我通常会使用基于注释的配置,但是直到运行时我才知道有多少数据源(以及事务管理器),我必须以编程方式注册这些,如如下:
private final void registerTransactionManagerBean(final DataSource dataSource,ConfigurableApplicationContext context){
String transactionManagerName = this.getName() + "-transactionManager";
context.getBeanFactory().registerSingleton(transactionManagerName, new DataSourceTransactionManager(dataSource));
LOG.info("Registering transaction manager under name : " + transactionManagerName);
}
假设this.getName()返回'mydb',我最初希望能够像这样限定一个transacton管理器:
@Transactional("mydb-transactionManager")
然而,我所意识到的是,该注释的价值是指限定符而不是名称。我通过声明下面的bean来进行快速测试,它可以工作:
@Bean
@Qualifier("mydb-transactionManager")
public PlatformTransactionManager test() {
return new DataSourceTransactionManager(new EmbeddedDatabaseBuilder().build());
}
我的问题是,有没有办法在注册bean时以编程方式添加限定符?
非常感谢。
我已经解决了这个问题,我正在犯这个问题(在BeanFactoryAnnotationUtils:isQualifierMatch中):
catch (NoSuchBeanDefinitionException ex) {
// ignore - can't compare qualifiers for a manually registered singleton object
}
我手动注册我的事务管理器bean所以我认为这就是为什么我被卡住了。我不确定哪些选项让我与众不同,不能以编程方式将事务管理器注册为运行时事件。
答案 0 :(得分:0)
我已经解决了这个问题,我正在犯这个问题:
catch (NoSuchBeanDefinitionException ex) {
// ignore - can't compare qualifiers for a manually registered singleton object
}
我手动注册我的事务管理器bean所以我认为这就是为什么我被卡住了。我不确定哪些选项让我与众不同,不能以编程方式将事务管理器注册为运行时事件。
提出JIRA问题 - https://jira.spring.io/browse/SPR-11915
答案 1 :(得分:0)
public class RuntimeRegistrationWithQualifierTest {
private AnnotationConfigApplicationContext context;
@Test
public void beanWithQualifier() {
final GenericBeanDefinition helloBeanDefinition = new GenericBeanDefinition();
helloBeanDefinition.addQualifier(new AutowireCandidateQualifier(Hello.class));
final GenericBeanDefinition worldBeanDefinition = new GenericBeanDefinition();
worldBeanDefinition.addQualifier(new AutowireCandidateQualifier(World.class));
final DefaultListableBeanFactory factory = context.getDefaultListableBeanFactory();
factory.registerBeanDefinition("helloBean", helloBeanDefinition);
factory.registerSingleton("helloBean", "hello");
factory.registerBeanDefinition("worldBean", worldBeanDefinition);
factory.registerSingleton("worldBean", "world");
context.register(Foo.class);
context.refresh();
final Foo foo = context.getBean(Foo.class);
assertThat(foo.hello).isEqualTo("hello");
assertThat(foo.world).isEqualTo("world");
}
@Before
public void newContext() {
context = new AnnotationConfigApplicationContext();
}
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
@interface Hello {}
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
@interface World {}
static class Foo {
final String hello;
final String world;
Foo(@Hello final String hello, @World final String world) {
this.hello = hello;
this.world = world;
}
}
}