簡體   English   中英

為什么我在春季沒有自動布線中沒有類型獨特的bean

[英]Why i am not getting No unique bean of type in Autowiring in spring

人.java

@Controller
public class Person 
{
    @Autowired
    private Ability ability;

     public void printMessage(){

         ability.printMessasge();
     }

     public void setOutputGenerator( Ability ability) {
            this.ability = ability;
        }  
}

Ability.java

@Controller
public class Ability 
{
     void printMessasge(){

         System.out.println("I print message");
     }

}

spring.xml

<bean id="invisible" class="com.mkyong.common.Ability" >
</bean>  

<context:component-scan base-package="com.mkyong" /> 

App.java

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "spring.xml");

        Person person = (Person) context.getBean("person");
        person.printMessage( );
    }

在上面的示例中,我定義了兩個Ability類的bean,一個使用@Controller ,另一個在xml文件中。 根據Autowire的類型,我應該得到

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: 
...
No unique bean of type [com.mkyong.common.Ability] is defined:

但是我得到適當的輸出。 為什么?

如果我創建一個由Ability類實現的接口,那么我將得到UnsatisfiedDependencyException異常。 像這樣:

Parent.java

public interface Parent{

     public void printMessasge();

}

Ability.java

@Controller
public class Ability implements Parent
{
      void printMessasge(){

         System.out.println("I print message");
     } 

人.java

@Controller
public class Person 
{
    @Autowired
    Parent parent;
     public void printMessage(){
         parent.printMessasge();
     }

     public void setOutputGenerator( Parent parent) {
            this.parent= parent;
        }  
}

默認情況下,Spring確實按類型進行匹配,但是如果有多個匹配的Bean,它將回退到按名稱進行匹配。 參考資料( 6.9.4使用限定符微調基於注釋的自動裝配 )表示:

對於后備匹配,bean名稱被認為是默認的限定符值。

使用@Qualifier批注使按類型以及名稱的自動裝配更加明確。

這種配置不會導致UnsatisfiedDependencyException ,因為Spring非常聰明,還可以查看所需依賴項的名稱,就像@Adam在他的回答中所寫的那樣。 因此,即使默認的自動裝配模式是按類型,並且對於該依賴項有兩個相同類型的bean,Spring也能夠解決沖突。

官方文檔6.9.4中的“使用限定符對基於注釋的自動裝配進行微調”部分對此行為進行了描述。 有關自動裝配模式的更多詳細信息,請參見6.4.5自動裝配協作器

如果將Person.ability字段的名稱更改為其他名稱,例如Person.ability2,那么Spring將拋出org.springframework.beans.factory.NoUniqueBeanDefinitionException 它不能決定應為Person.ability2字段連接哪個bean,因為:

  1. 上下文中有com.mkyong.common.Ability類型的兩個bean
  2. 字段名稱與任何一個bean名稱都不匹配

編輯:在第二種情況下,您提到(使用接口),Spring會出於與我上面解釋的相同的bean命名原因而引發異常。


官方文檔參考:

您定義了兩個模糊的be​​an,當spring嘗試通過類型查找bean時,它會找到兩個bean,一個通過scan其他在spring.xml中顯式定義的bean。 使用@Qualifier標記在Person類中加載的正確bean。 所以大概你想要這樣,

 @Controller
public class Person 
{

      @Autowired
      @Qualifier("invisible")
      private Ability ability;

     public void printMessage(){

         ability.printMessasge();
     }

     public void setOutputGenerator( Ability ability) {
            this.ability = ability;
        }  
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM