0

Я пытаюсь реализовать функциональность службы связи на основе шаблона стратегии с использованием Spring. У меня есть следующие классы -NoUniqueBeanDefinitionException - Spring DI с шаблоном стратегии

интерфейс - MessageService.java

package com.xxx 

public Interface MessageService{ 

    String sendMessage(String idOrNumber); 

} 

реализации Классы -

1) EmailService.java

package com.xxx 

@Component 
public class EmailService implements MessageService{ 

     public String sendMessage(String idOrNumber){ 

    // Do some operation 

    return "success" 

    } 

} 

2) SmsService.java

package com.xxx 

@Component 
public class SmsService implements MessageService{ 

     public String sendMessage(String idOrNumber){ 

    // Do some operation 

    return "success" 

    } 

} 

CommunicationFactory Класс

package com.xxx 

@Component 
public class CommunicationFactory { 

    @Resource(name ="smsService") 
    private SmsService smsService 


    @Resource(name ="emailService") 
    private EmailService emailService; 


    public MessageService getCommunicationChannel(String channel){ 

    MessageService messageService = null; 

    if("sms".equals(channel){ 

    messageService = smsService;  

    } 

    if("email".equals(channel){ 

    messageService = emailService; 

    } 

    return messageService; 

} 

У меня есть почтовой класс реализации

package com.xxx 

@Component 
@Service 
public class CommunicationServiceImpl implements CommunicationService { 

     @Autowired 
     private MessageService messageService; 

     CommunicationFactory communicationFactory; 


     @Override 
     public String sendCommunication(String idOrNumber){ 

     //Which implementation be called - SMS or EMAIL 
     messageService = communicationFactory.getCommunicationChannel(channel); 

     String statusMessage = messageService.sendMessage(idOrNumber); 

     } 

} 

Я получаю следующее сообщение об ошибке во время работы сервера ,

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.xxx.MessageService com.xxx.CommunicationServiceImpl.messageService; nested exception is 

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.xxx.MessageService] is defined: expected single matching bean but found 2: smsService,emailService 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) [spring-beans- 

3.2.3.RELEASE.jar:3.2.3.RELEASE] 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) [spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) [spring-beans- 

3.2.3.RELEASE.jar:3.2.3.RELEASE] 
    ... 25 more 
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.xxx.MessageService] is defined: expected single matching bean but found 2: 

smsService,emailService 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:863) [spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768) [spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) [spring-beans- 

3.2.3.RELEASE.jar:3.2.3.RELEASE] 
    ... 27 more 

Где я ошибаюсь? Любые указатели были бы полезны

+0

Вы не имеете спецификатора в классе обслуживания. – chrylis

ответ

1

Попробуйте это.

реализации Классы -

1) EmailService.java 

package com.xxx 

@Component("emailService") 
public class EmailService implements MessageService{ 

     public String sendMessage(String idOrNumber){ 

    // Do some operation 

    return "success" 

    } 

} 
2) SmsService.java 

package com.xxx 

@Component("smsService") 
public class SmsService implements MessageService{ 

     public String sendMessage(String idOrNumber){ 

    // Do some operation 

    return "success" 

    } 

} 

И проблема заключается здесь:

@Autowired 
private MessageService messageService; 

Возможное решение @Autowired как услуги.

@Autowired 
private MessageService smsService; 
@Autowired 
private MessageService emailService; 

или, если у вас такая же проблема.

@Autowired 
@Qualifier("smsService") 
private MessageService smsService; 
@Autowired 
@Qualifier("emailService") 
private MessageService emailService; 
+0

Дани, я попробовал ваше предложение. Это тоже не сработало. Я получаю то же исключение –

+0

Хорошо, я думаю, что ваша проблема здесь @Autowired private MessageService messageService ;, Причина, когда Spring DI пытается ввести эту ссылку, - это два компонента с одним и тем же интерфейсом, и Spring не может решить, какой из них установлен. Определите один или повторите этот подход. – Dani

+0

Мне нравится помогать людям получать отрицательные голоса в подарок ... Отличное отношение. – Dani

0

Простейшая реализация я знаю полагаться на введенном перечне услуг и имеющим метод GET для извлечения ответственной службы:

package com.xxx 

@Component 
public class CommunicationFactory { 

    /** 
    * This list would be ordered if the interface is implementing `org.springframework.core.Ordered` or an implementation declares `@org.springframework.core.annotation.Order`(in Spring 4) 
    */ 
    @Autowired 
    private List<MessageService> messageServices; 

    /** 
    * @return the FIRST communication channel for the given channel 
    */ 
    public MessageService getCommunicationChannel(String channel){ 
     for (MessageService ms : messageServices) { 
      if (ms.supports(channel)) { 
       return ms; 
      } 
     } 
     return null; // or a default :) 
    } 

    /** 
    * With this implementation you can even have multiple implementations firing a message if they support the given channel. 
    * @return a list of communication channels that support the given channel 
    */ 
    public List<MessageService> getCommunicationChannels(String channel){ 
     List<MessageService> supporting = new ArrayList<>(); 
     for (MessageService ms : messageServices) { 
      if (ms.supports(channel)) { 
       supporting.add(ms); 
      } 
     } 
     return supporting; 
    } 
} 
Смежные вопросы