自动装配模式
Mode | Explanation |
---|---|
no | (默认)无自动装配。 Bean 引用必须由ref元素定义。对于大型部署,建议不要更改默认设置,因为明确指定协作者可以提供更好的控制和清晰度。在某种程度上,它记录了系统的结构。 |
byName | 按属性名称自动布线。 Spring 寻找与需要自动装配的属性同名的 bean。例如,如果一个 bean 定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(..)方法),那么 Spring 将查找一个名为master的 bean 定义并使用它来设置属性。 |
byType | 如果容器中恰好存在一个该属性类型的 bean,则使该属性自动装配。如果存在多个错误,则会引发致命异常,这表明您可能不对该 bean 使用byType自动装配。如果没有匹配的 bean,则什么也不会发生(未设置该属性)。 |
constructor | 类似于byType,但适用于构造函数参数。如果容器中不存在构造函数参数类型的一个 bean,则将引发致命错误。 |
- 自动装配:Spring满足bean依赖的一种方式
- Spring会在上下文中自动寻找,并自动给bean装配属性
在Spring中有三种装配的方式
- 在xml中显式的配置
- 在Java中显式配置
- 隐式 的自动装配bean【重要】
(一)测试
- 环境搭配: 一个人有两个宠物
- Cat.java
public class Cat {
public void show() {
System.out.println("mao~");
}
}
- Dog.java
public class Dog {
public void show() {
System.out.println("hu~");
}
}
- Person.java
public class Person {
private Cat cat;
private Dog dog;
private String name;
}
- beans.xml
<?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="dog" class="com.vigil.pojo.Dog"></bean>
<bean id="cat" class="com.vigil.pojo.Cat"></bean>
<bean id="person" class="com.vigil.pojo.Person">
<property name="name" value="鱼佬"></property>
<property name="cat" ref="cat"></property>
<property name="dog" ref="dog"></property>
</bean>
</beans>
- Test.java
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
System.out.println(person.getName());
person.getDog().show();
person.getCat().show();
}
}
(二)ByName自动装配
<bean id="dog" class="com.vigil.pojo.Dog"></bean>
<bean id="cat" class="com.vigil.pojo.Cat"></bean>
<!--byName:会自动在容器上下文中查找,和该对象set方法后面的值所对应的 beanid
经检验,确实是SET后面的字符串,和形参、类型都没关系-->
<bean id="person" class="com.vigil.pojo.Person" autowire="byName">
<property name="name" value="鱼佬"></property>
</bean>
(三)ByType自动装配
<bean class="com.vigil.pojo.Dog"></bean>
<bean class="com.vigil.pojo.Cat"></bean>
<!--byType:会自动在容器上下文中查找,和该对象属性类型相同的bean
所以上下文中要保证该类型全局唯一-->
<bean id="person" class="com.vigil.pojo.Person" autowire="byType">
<property name="name" value="鱼佬"></property>
</bean>
- 小结
- 使用byName:需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
- 使用byType:需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
(四)使用注解实现自动装配
- 导入约束: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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
1)@Autowired
public @interface Autowired {
boolean required() default true;
}
直接在属性上使用即可,也可以在set方式上使用
使用 Autowired ,则可以不用编写set方法,前提是:这个自动装配的属性在 IOC(Spring)容器中存在,且符合名字byname
2)@Qualifier
public @interface Qualifier {
String value() default "";
}
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,可以使用@Qualifier (value = "xxx") 去配合@Autowired的使用,指定唯一的bean对象注入(value是beanid)
3)@Resource
@Resource和@Autowired的区别
- 都是用来自动装配的,都可以放到属性字段上
- @Autowired 通过byType的方式实现,而且必须要求这个对象存在,常用
- @Resource 默认通过byName的方式实现,如果找不到名字,则通过byType实现。如果两种方式都无法找到,会报错
- 执行顺序不同:@Autowired 通过byType的方式实现;@Resource 通过byName方式实现
- Test
- beans.xml
<bean id="cat" class="com.vigil.pojo.Cat"></bean>
<bean id="cat2" class="com.vigil.pojo.Cat"></bean>
<bean id="dog" class="com.vigil.pojo.Dog"></bean>
<bean id="dog23" class="com.vigil.pojo.Dog"></bean>
<bean id="person" class="com.vigil.pojo.Person"></bean>
- Person.java
public class Person {
@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Resource(name = "dog")
private Dog dog;
private String name;
}