具体的可以查看官方文档
Spring中bean有三种装配机制,分别是:
- 在xml中显式配置
- 在java中显式配置
- 隐式的bean发现机制和自动装配
本文主要讲第三种:自动化装配bean
Spring的自动装配需要从两个角度来实现,或者说是两个操作:
- 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean
- 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI
1. 环境搭建
public class Cat {
public void shout() {
System.out.println("miao~");
}
}
public class Dog {
public void shout() {
System.out.println("wang~");
}
}
public class Student {
private Cat cat;
private Dog dog;
private String name;
public void setCat(Cat cat) {
this.cat = cat;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
public String getName() {
return name;
}
}
2. xml配置实现自动装配
2.1 byName
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.comprehensive.pojo.Cat"/>
<bean id="dog" class="com.comprehensive.pojo.Dog"/>
<bean id="stu1" class="com.comprehensive.pojo.Student" autowire="byName">
<property name="name" value="comprehensive"/>
</bean>
</beans>
//测试类
public class Test_byName {
@Test
public void test1() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student stu1 = context.getBean("stu1", Student.class);
stu1.getCat().shout();
stu1.getDog().shout();
}
}
将 cat 的bean id修改下(如下所示),继续测试
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注意此处,id修改 -->
<bean id="cat123" class="com.comprehensive.pojo.Cat"/>
<bean id="dog" class="com.comprehensive.pojo.Dog"/>
<bean id="stu1" class="com.comprehensive.pojo.Student" autowire="byName">
<property name="name" value="comprehensive"/>
</bean>
</beans>
2.2 byType
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat123" class="com.comprehensive.pojo.Cat"/>
<bean id="dog_wang" class="com.comprehensive.pojo.Dog"/>
<bean id="stu2" class="com.comprehensive.pojo.Student" autowire="byType">
<property name="name" value="comprehensive"/>
</bean>
</beans>
//测试类
public class Test_byType {
@Test
public void test2() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
Student stu2 = context.getBean("stu2", Student.class);
stu2.getCat().shout();
stu2.getDog().shout();
}
}
如果xml这里再注册一个cat 的bean对象(如下所示),继续测试
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat123" class="com.comprehensive.pojo.Cat"/>
<bean id="cat12" class="com.comprehensive.pojo.Cat"/>
<bean id="dog_wang" class="com.comprehensive.pojo.Dog"/>
<bean id="stu2" class="com.comprehensive.pojo.Student" autowire="byType">
<property name="name" value="comprehensive"/>
</bean>
</beans>
3. 注解实现自动装配
3.1 准备工作
- 在spring配置文件中引入context文件头 ```xml xmlns:context=”http://www.springframework.org/schema/context“
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
- 开启属性注解支持!
```xml
<context:annotation-config/>
@Autowired
- @Autowired是按类型自动装配的,不支持id匹配。
需要导入 spring-aop的包! ```xml <?xml version=”1.0” encoding=”UTF-8”?>
```java
public class Student {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
public void setCat(Cat cat) {
this.cat = cat;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
public String getName() {
return name;
}
}
//测试类
public class Test_Autowired {
@Test
public void test3() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans_Autowired.xml");
Student stu3 = context.getBean("stu3", Student.class);
stu3.getCat().shout();
stu3.getDog().shout();
}
}
@Autowired(required=false) 说明:false,对象可以为null;true,对象必须存对象,不能为null
@Qualifier
- @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
@Qualifier不能单独使用 ```xml <?xml version=”1.0” encoding=”UTF-8”?>
```java
public class Student {
@Autowired
@Qualifier("cat2")
private Cat cat;
@Autowired
@Qualifier("dog1")
private Dog dog;
private String name;
public void setCat(Cat cat) {
this.cat = cat;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
public String getName() {
return name;
}
}
//测试类
public class Test_Qualifier {
@Test
public void test4() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans_Qualifier.xml");
Student stu4 = context.getBean("stu4", Student.class);
stu4.getCat().shout();
stu4.getDog().shout();
}
}
@Resource
- @Resource如有指定的name属性,先按该属性进行byName方式查找装配
- 其次再进行默认的byName方式进行装配
- 如果以上都不成功,则按byType的方式自动装配
都不成功,则报异常 ```xml <?xml version=”1.0” encoding=”UTF-8”?>
**注意**:这里使用的@Resource注解来自于`javax.annotation`包,javax为Java扩展包,我这里使用的JDK版本为14,没有自带javax拓展包。解决方法:在maven项目的配置文件中导入依赖即可(亲测有效)
```xml
<dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
public class Student {
@Resource(name = "cat2")
private Cat cat;
@Resource
private Dog dog;
private String name;
public void setCat(Cat cat) {
this.cat = cat;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
public String getName() {
return name;
}
}
//测试类
public class Test_Resource {
@Test
public void test5() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans_Resource.xml");
Student stu5 = context.getBean("stu5", Student.class);
stu5.getCat().shout();
stu5.getDog().shout();
}
}