Spring Bean 自动装配
7. Bean的自动装配
- 自动装配是Spring满足bean依赖一种方式
- Spring会在上下文中自动寻找,并自动给bean装配属性
在Spring中有三种装配的方式
- 在xml中显示的配置
- 在java中显示配置
- 隐式的自动装配bean ※
7.1 测试
环境搭建:一个人有两个宠物
package com.peng.pojo;
public class Cat {
public void shout(){
System.out.println("miao~");
}
}
public class Dog {
public void shout(){
System.out.println("wang~");
}
}
package com.peng.pojo;
public class People {
private Cat cat;
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "People{" +
"cat=" + cat +
", dog=" + dog +
", name='" + name + '\'' +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.peng.pojo.Cat"/>
<bean id="dog" class="com.peng.pojo.Dog"/>
<bean id="people" class="com.peng.pojo.People">
<property name="name" value="peng"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
</beans>
import com.peng.pojo.People;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
People people = context.getBean("people",People.class);
System.out.println(people.toString());
people.getCat().shout();
people.getDog().shout();
}
}
7.2 自动装配
-
<!--byName:会自动在容器上下文中查线,和白己对象set方法后面的值对应的beanid !--> <bean id="people" class="com.peng.pojo.People" autowire="byName"> <property name="name" value="peng"/> </bean>
-
<bean class="com.peng.pojo.Cat"/> <bean class="com.peng.pojo.Dog"/> <!--byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!--> <bean id="people" class="com.peng.pojo.People" autowire="byType"> <property name="name" value="peng"/> </bean>
小结:
byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
7.3 使用注解实现自动装配
jdk1.5支持的注解,Spring2.5就支持注解了!
官网介绍:The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.
要使用注解须知:
-
导入约束:context约束
-
配置注解的支持:context:annotation-config/
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
-
@Autowired 在属性上用:使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在I0C (Spring) 容器中存在,且符合名字,即 byName!
public class People { @Autowired private Cat cat; @Autowired private Dog dog; private String name; public Cat getCat() { return cat;} public Dog getDog() {return dog;} public String getName() {return name;} public void setName(String name) {this.name = name;} @Override public String toString() { return "People{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
@Autowired 在set方法上用
import org.springframework.beans.factory.annotation.Autowired; public class People { private Cat cat; private Dog dog; private String name; public Cat getCat() {return cat;} @Autowired public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() {return dog;} @Autowired public void setDog(Dog dog) { this.dog = dog; } public String getName() {return name;} public void setName(String name) {this.name = name;} @Override public String toString() { return "People{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
构造器中加注解 @Nullable name可以为空,在初始化时不给name赋值也不会报错
public People(@Nullable String name) { this.name = name; }
如果显示定义了Autowired的required属性为false, 说明这个对象可以为mull,否则不允许为空
@Autowired(required = false) private Cat cat;
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用 @Qualifier(value="xxx") 去配合@Autowired的使用, 指定一个唯一的bean对象注入!
public class People { @Autowired @Qualifier(value="dog222") private Dog dog; }
@Resource注解
public class People { @Resource(name="dog222") private Dog dog; @Resource private Cat cat; }
@Resource和@ Autowired的区别:
- 都是用来自动装配的,都可以放在属性字段上
- @Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用]】
- @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错! 【常用】
- 执行顺序不同:@Autowired:类型、名字;@Resource:名字、类型