结论:
-
@Bean自动注入优先筛选选择类型相同的bean
-
然后选有@Primary注解的bean,如果有多个有@Primary修饰的bean就会报错,只有一个这样的bean就选择
-
如果都没用@Primary修饰的bean就会选择@Bean要注入的参数的参数名与bean名字相同的bean
-
如果找不到名字相同的,就会去找名字不同的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,如果有多个就报错,只有一个就选择它