带有@Qualifier的@Bean声明不起作用
可以说我有一个配置类(JmsQueueConfig,请参见下文)。在此类中,我想为整个应用程序配置多个队列。对于一个队列,没有问题。但是,当我添加第二个队列并尝试从服务(MemberService)使用这些队列之一时,Spring-
boot会告诉我
com.example.notification.application.jms.JmsEventPublisher中的构造函数的参数1需要一个bean,但是找到2:-queueAccountToNotification:由类路径资源[com
/ example / notification / application / jms
/中的方法’queueAccountToNotification’定义[JmsQueueConfig.class]-queueNotificationToAccount:由类路径资源[com
/ example / notification / application / jms /
JmsQueueConfig.class]中的方法’queueNotificationToAccount’定义
行动:
考虑将其中一个Bean标记为@Primary,更新使用者以接受多个Bean,或使用@Qualifier标识应使用的Bean
这是我的配置类:
@Configuration@EnableJms
@ImportAutoConfiguration(classes = {
JmsAutoConfiguration.class,
ActiveMQAutoConfiguration.class
})
public class JmsQueueConfig {
@Value("${APP_QUEUE_ACCOUNT_TO_NOTIFICATION}")
private String queueAccountToNotificationName;
@Value("${APP_QUEUE_NOTIFICATION_TO_ACCOUNT}")
private String queueNotificationNameToAccount;
@Bean
@Qualifier("q1")
public Queue queueAccountToNotification() {
return new ActiveMQQueue(queueAccountToNotificationName);
}
@Bean
@Qualifier("q2")
public Queue queueNotificationToAccount() {
return new ActiveMQQueue(queueNotificationNameToAccount);
}
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
@Bean
@Qualifier("p1")
public EventPublisher eventPublisher(JmsTemplate jmsTemplate) {
return new JmsEventPublisher(jmsTemplate, new ActiveMQQueue(queueAccountToNotificationName));
}
@Bean
public MessageConverter messageConverter() {
return new JmsMessageConverter();
}
}
我的服务:
@Service@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor
@Slf4j
public class MemberService {
@Autowired
@Qualifier("q1")
Queue q;
@Qualifier("p1")
EventPublisher eventPublisher;
public void createMemberSubscription(final Member member) {
final MembershipSubscriptionEvent event = new MembershipSubscriptionEvent(UUID.randomUUID().toString(), member.getEmail());
//eventPublisher.publish(event);
log.info("createMemberSubscription");
}
public void removeMemberSubscription(final Member member) {
final MembershipRemovalEvent event = new MembershipRemovalEvent(UUID.randomUUID().toString());
//eventPublisher.publish(event);
log.info("removeMemberSubscription");
}
}
我是Spring生态系统的新手,我可能不太了解@Autowired和绑定。任何好的文档或示例将不胜感激。在Spring和SoF上,我还没有找到任何此类文档。
JmsEventPublisher类
@Component@FieldDefaults(level = AccessLevel.PRIVATE)
@Slf4j
@AllArgsConstructor
public class JmsEventPublisher implements EventPublisher {
final JmsTemplate jmsTemplate;
final Destination destination;
@Override
public void publish(DomainEvent event) {
jmsTemplate.convertAndSend(destination, event);
log.trace("Sent event. [destination={}, event={}]", destination, event);
}
}
回答:
我认为您@Qualifier
对文档有误解,“ , ”
在你的情况下@Qualifier
是没有意义的。
@Bean @Qualifier("q1")
public Queue queueAccountToNotification() {
return new ActiveMQQueue(queueAccountToNotificationName);
}
相反,你应该这样做
@Bean(name = "q1") public Queue queueAccountToNotification() {
return new ActiveMQQueue(queueAccountToNotificationName);
}
@Bean(name = "q2")
public Queue queueNotificationToAccount() {
return new ActiveMQQueue(queueNotificationNameToAccount);
}
同样除去@Qualifier
上eventPublisher(...)
那并不能解决所有问题。:)
如异常所示,spring无法自动Destination
绑定JmsEventPublisher中的字段。因为它有两个类型为Destination(q1和q2)的bean。
为了解决这个问题,您可以做的是。
放入@Primary
其中一个bean声明,然后使用@Qualifier
。
@Primary@Bean(name = "q1")
public Queue queueAccountToNotification() {
return new ActiveMQQueue(queueAccountToNotificationName);
}
public class JmsEventPublisher implements EventPublisher {
final JmsTemplate jmsTemplate;
@Qualifier("q1")
final Destination destination;
..........
}
底线是要@Qualifier
在多个相同类型的bean的情况下工作,您需要@Primary
另一个选择是使用@Primary而不是@Primary,可以将变量命名为与Bean名称完全相同的名称,然后spring将自动为您注入正确的Bean。即
public class JmsEventPublisher implements EventPublisher { final JmsTemplate jmsTemplate;
final Destination q1; // q1 or q2
.....
}
类似地在MemberService中
public class MemberService { @Autowired
Queue q1; // q1 or q2
.....
}
以上是 带有@Qualifier的@Bean声明不起作用 的全部内容, 来源链接: utcz.com/qa/434604.html