参考代码尝试:
https://github.com/LinkedBear/spring-framework-learning-code/tree/master/spring-01-ioc/src/main/java/com/linkedbear/spring/basic_di/d_autowired
示例如下:
@Configuration
public class QuickstartConfiguration {
@Bean
public Person person() {
return new Person();
}
}
默认bean的id就是方法名,如上面Person类的id就叫‘person’。如果想更改id值,直接修改方法名即可
@Component
注解,这种适用于我们项目中自定义的类@Component
public class Person {
}
默认的bean的id就是类名(首字母替小写),如上面的Person类的id就叫‘person’,如果想更改id值,直接在注解中指定就行,如@Component(“aaa”),Person类的id就改成了’aaa’
具体spring注册了哪些bean,可以通过如下来验证
ApplicationContext ctx = new AnnotationConfigApplicationContext(AutowiredConfiguration.class);
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
Stream.of(beanDefinitionNames).forEach(System.out::println);
// *****像上面,如果两种的id改成相同值,也不会报错。但是通过id来获取bean时,也不报错,获取到的是用@Bean声明的那个bean。是不是@Bean的优先级更高些???
Object person = ctx.getBean("person");
System.out.println(person);
// *****但如果是按类型来获取bean,因为都是Person类型,和通过id获取的一样,id相同就取@Bean声明的那个bean,有唯一的就取唯一的,一个都取不到就直接报错,这个直接用@Autowired注入的一样
Person bean = ctx.getBean(Person.class);
System.out.println(bean);
参考@Autowired代码
// Dog类直接声明成了bean,属性注入了Person类
@Component
public class Dog {
@Value("dogdog")
private String name;
@Autowired
//@Qualifier("administrator")
private Person person;
@Autowired
private List<Person> persons;
@Override
public String toString() {
return "Dog{" + "name='" + name + '\'' + ", person=" + person + ", persons=" + persons + '}';
}
}
// Cat类是一个普通java类,有Person属性,通过@bean的方式声明
@Bean
@Autowired // 高版本可不标注
public Cat cat(Person person) {
Cat cat = new Cat();
cat.setName("mimi");
cat.setPerson(person);
return cat;
}
@Autowired默认是按照类型来匹配的,如果id相同,默认取的是@Bean声明的那个bean?(这块为了代码的可维护性,建议不要重名吧);如果id唯一就取唯一的;如果一个都取不到,就报错。
重点就不类名相同,没有匹配的id的情况,有3种解决方式:
// 对于属性注入的方式,把person修改成person1、person2之类的
@Autowired
private Person person1;
// 对于构造器的方式,参数上修改成person1、person2之类的.这样声明Cat的bean时,就会找bean的id为‘person1’的类,注入到cat的person属性上
@Bean
//@Autowired
public Cat cat(Person person1) {
Cat cat = new Cat();
cat.setName("mimi");
cat.setPerson(administrator);
return cat;
}
// 属性上
@Autowired
@Qualifier("person1")
private Person person;
// 构造器上
@Bean
//@Autowired
public Cat cat(@Qualifier("person1") Person person) {
Cat cat = new Cat();
cat.setName("mimi");
cat.setPerson(person);
return cat;
}
// 声明在@Bean上的
@Bean
@Primary
public Person person1() {
Person master = new Person();
master.setName("master");
return master;
}
// 声明在@Component上
@Component("administrator")
@Primary
public class Person {
private String name = "administrator";
...
}
上面都是注入一个 Bean 的方式,通过两种不同的办法来保证注入的唯一性。但如果需要一下子把所有指定类型的 Bean 都注入进去应该怎么办呢?其实答案也挺简单的,注入一个用单个对象接收,注入一组对象就用集合来接收:
@Component
public class Dog {
// ......
@Autowired
private List<Person> persons;
输出时就可以看到注入了所有Person类型的类
Dog{name='dogdog', person=Person{name='administrator'}, persons=[Person{name='administrator'}, Person{name='master'}]}
因篇幅问题不能全部显示,请点此查看更多更全内容