Spring @Bean注解的自动注入的规律

结论:
  1. @Bean自动注入优先筛选选择类型相同的bean

  2. 然后选有@Primary注解的bean,如果有多个有@Primary修饰的bean就会报错,只有一个这样的bean就选择

  3. 如果都没用@Primary修饰的bean就会选择@Bean要注入的参数的参数名与bean名字相同的bean

  4. 如果找不到名字相同的,就会去找名字不同的bean,如果有多个就报错,只有一个就选择它

实验:

首先认识User类,People类,User类,测试类ServerApplicationTests:

User类:就一个成员 String name

People类:就一个成员 User user

测试类ServerApplicationTests:用于测试@Bean的注入到底选择了那个User 类型的bean对象

具体如下:

User类: 就一个成员 String name ,其他都是get ,set ,toString 方法

public class User {
    public String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }

    public User(String name) {
        this.name = name;
    }

    public User() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

People类

就一个成员 User类型,其他都是get ,set ,toString 方法

public class People {
    public User user;

    public People(User user) {
        this.user = user;
    }

    public People() {
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "People{" +
                "user=" + user +
                '}';
    }
}

测试类:

需要把SpringBoot整合junit ,用它测试,这是下面实验的入口

提示: junit测试时不需要main方法的,junit测试可以使用Spring的IOC容器

                          //这里填的是引导类的class
@SpringBootTest(classes=com.lww.server.ServerApplication.class)
class ServerApplicationTests {
    @Autowired
    People people;
    @Test
    void contextLoads() {
        System.out.println(people);
    }
}
实验一 :

证明**@Bean自动注入会按类型选择,而且是不需要参数名保持一致**

@Configuration
public class TestBean {
    @Bean
    // bean 的名字时getUser1
   public User getUser1() {
        return new User("user1");
    }

    @Bean
    public People getPeople(User user){
        return new People(user);
    }
}

结果:

控制台打印结果:
User{name=‘user1’}

说明getPeople(User user)方法注入时选择了名为getUser1 的bean,虽然参数名user与bean名getUser1不一致,但是类型相同就可以用它注入

实验二:
@Configuration
public class TestBean {
    @Bean
    // bean 的名字时getUser1
   public User getUser1() {
        return new User("user1");
    }

    @Bean
    // bean 的名字时getUser2
    public User getUser2(){
        return new User("user2");
    }
    @Bean
          //关注  这个方法用哪个User类型的bean来注入
    public People getPeople(User user){
        return new People(user);
    }
}

结果:报错 ,因为有两个User类型,不知道选择哪个

把 getPeople 方法的参数名改成getUser2,像这样:

@Configuration
public class TestBean {
    @Bean
     // bean 的名字时getUser1
   public User getUser1() {
        return new User("user1");
    }

    @Bean
     // bean 的名字时getUser2
    public User getUser2(){
        return new User("user2");
    }
    @Bean
     //关注:这个方法用哪个User类型的bean来注入
    public People getPeople(User getUser2){
        return new People(getUser2);
    }
}

结果:

控制台打印:

People{user=User{name=‘user2’}}

说明 选择了名为getUser2的bean来注入

原因: @Bean注入 先从类型相同中的bean对象里选择,然后会优先选择名字相同的bean对象

实验三:

加上一个@Primary注解修饰public User getUser1()方法

@Configuration
public class TestBean {
    @Bean
    @Primary
    // bean 的名字时getUser1
   public User getUser1() {
        return new User("user1");
    }

    @Bean
     // bean 的名字时getUser2
    public User getUser2(){
        return new User("user2");
    }
    @Bean
    //关注  这个方法用哪个User类型的bean来注入
    public People getPeople(User getUser2){
        return new People(getUser2);
    }
}

结果:

People{user=User{name=‘user1’}}

说明选择了名为getUser1的bean对象,

即使方法getPeople(User getUser2)的参数名时getUser2,也没有选择名为getUser2的bean

而是选择了有@Primary修饰的名为getUser1的bean

说明了@Primary修饰的bean在自动注入时的优先级时比参数名与bean名字相同的优先级更高

那如果 getUser1(), getUser2()方法都加上@Primary注解呢?

@Configuration
public class TestBean {
    @Bean
    @Primary
   public User getUser1() {
        return new User("user1");
    }

    @Bean
      @Primary
    public User getUser2(){
        return new User("user2");
    }
    @Bean
    //关注  这个方法用哪个User类型的bean来注入
    public People getPeople(User getUser2){
        return new People(getUser2);
    }
}

结果:报错了,说明对于有@Primary的bean就不会 因为你名字与@Bean注入的参数名相同就优先选你而是会直接报错

证明了: @Bean自动注入优先筛选选择类型相同的bean,然后选有@Primary注解的bean,如果有多个有@Primary修饰的bean就会报错,如果都没用@Primary修饰的bean就会选择参数名与bean名字相同的,如果找不到相同的,就会去找名字不同的bean,如果有多个就报错,只有一个就选择它

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值