0

我想基於使用Spring戰略模式來實現通信服務功能。我有以下類 -NoUniqueBeanDefinitionException - 春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 2014-09-01 22:28:38

回答

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

丹妮,我試了你的建議。它也沒有工作。我收到了同樣的異常 – 2014-09-01 22:07:48

+0

好吧,我覺得你的問題是在這裏@Autowired 私人MessageService messageService ;,原因在春季DI嘗試注入該引用,是兩個豆相同的接口和Spring不能決定哪一個組。定義一個或重新實現這種方法。 – Dani 2014-09-01 22:25:37

+0

我喜歡幫助人得到反對票爲存在......偉大的態度。 – Dani 2014-09-01 22:37:40

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; 
    } 
}