Spring Bean注解:为什么同一类型的多个bean只需要一个限定符

wtlkbnrh  于 2023-06-21  发布在  Spring
关注(0)|答案(3)|浏览(165)

Dog.java

@Component
public class Dog {

    @Autowired
    @Qualifier("dogName")
    public String dogNameop;

    public Dog()  {
        
    }
    
     public Dog(String dogNameop) {
        this.dogNameop = dogNameop;
    }

    public String getDogNameop() {
        return dogNameop;
    }

    public void setDogNameop(String dogNameop) {
        this.dogNameop = dogNameop;
    }
}

Cat.java

@Component
public class Cat {
    private String catName;
    
    public Cat()  {
        
    }

    @Autowired
    public Cat(String catName) {
        this.catName = catName;
    }

    public String getCatName() {
        return catName;
    }

    public void setCatName(String catName) {
        this.catName = catName;
    }
}

Bear.java

@Component
public class Bear {
    private String  bearName;

    public Bear()  {
        
    }
    
    @Autowired
    public Bear(String bearName) {
        this.bearName = bearName;
    }

    public String getBearName() {
        return bearName;
    }

    public void setBearName(String bearName) {
        this.bearName = bearName;
    }
}

配置java

@Configuration
public class Config {
    @Bean
    String dogName()  {
        return "oof";
    }
    
    @Bean
    String catName()  {
        return "catto";
    }

    @Bean
    String bearName()  {
        return "bear";
    }
}

DemoApplication.java

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class DemoApplication {
     

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    
 

    @Bean
    CommandLineRunner commandLineRunner(Dog dog, Cat cat, Bear bear)  {
        return args ->  {
            System.out.println(dog.dogNameop);
            System.out.println(cat.getCatName());
            System.out.println(bear.getBearName());
        };
    } 
}

输出:

oof
catto
bear

如果我从Dog.java中删除@Qualifier("dogName"),我会得到错误:

Field dogNameop in com.example.demo.Dog required a single bean, but 3 were found:

然而,只有一个限定符,它就能正确地分配CatBear类中的字段。怎么做?我希望每个班级:DogCatBear需要内部的@Qualifier

编辑

Cat中的字段名称从catName更改为catNameHm会再次出现错误(将Bear类中的bearName单独更改为bearNameOh也会触发错误)。
因此,看起来一旦应用了一个@Qualifier,它就会使Spring始终通过字段的名称应用String类型的自动装配-在所有类中,而不仅仅是具有@Qualifier annotation的类?

hgtggwj0

hgtggwj01#

Spring解决了依赖注入,因为:

  1. @Bean方法名称是默认的bean名称。Baeldung
    当我们在方法上使用@Bean注解时,Spring使用方法名称作为bean名称。
    1.如果没有指定限定符,并且同一个类的多个bean可用,Spring @Autowire福尔斯退到参数名称作为限定符。Baeldung(参见引用后的示例):
    Spring使用bean的名称作为默认的限定符值
    official docs
    对于回退匹配,bean名称被视为默认限定符值。因此,您可以使用main的id来定义bean,而不是使用嵌套的限定符元素,从而得到相同的匹配结果。
    因此,为了解析@Autowired public Bear(String bearName),Spring会查找名为bearName的bean,由于定义了函数命名,所以会出现这个bean。catName也是如此。
8hhllhi2

8hhllhi22#

围绕的动机是关于Spring如何解决依赖注入。
Spring可以通过类型、名称或显式限定符进行解析。由于这三个bean都是String,SprinfFramework解决依赖注入的唯一方法是通过name或@Qualifier
这就是你必须放置@Qualifier的方式,否则你可以评估重构你的类并将dogNameop更改为dogName,如下所示:

@Component
public class Dog {

    @Autowired
    public String dogName;

    public Dog()  {
        
    }
    
     public Dog(String dogName) {
        this.dogName = dogName;
    }

    public String getDogName() {
        return dogName;
    }

    public void setDogName(String dogName) {
        this.dogName = dogName;
    }
}
wwtsj6pe

wwtsj6pe3#

1.你是一个@Autowire
因此,在您的应用程序上下文中,有三个该类型的bean。

  1. Spring必须做出选择,因为您注入的是一个bean,但是没有限定符,Spring就无法再做任何事情来缩小搜索范围。
    故事的结尾:错误

**注意:**如果你想要所有String类型的bean,你可以在List<String>@Autowire,然后自己决定哪一个适合你的需要。

相关问题