Spring 自动装配
Spring实现自动装配的方式有两种:xml文件和注解
方式一:使用xml文件实现自动装配
需要在bean标签中加入autowire属性
autowire属性的5种装配方式:
- no:默认装配方式,需要手动通过ref属性设定与bean的依赖关系
- byName:根据与自己对象set方法后面的值对应的id名进行自动装配
- byType:根据与和自己对象属性类型相同的bean进行自动装配
- constructor:根据构造器中属性类型相同的bean进行自动装配
- default:根据父级标签的默认装配方式进行自动装配
autodetect方法在3.0版本以后已被遗弃
1、no手动装配
<?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="wolf" class="com.spring.pojo.Wolf"/>
<bean id="people" class="com.spring.pojo.People">
<property name="wolf" ref="wolf"></property>
</bean>
</beans>
前提必须要有构造方法,否则无法装配
public class People {
private Wolf wolf;
public People() {
}
public Wolf getWolf() {
return wolf;
}
public void setWolf(Wolf wolf) {
this.wolf = wolf;
}
@Override
public String toString() {
return "People [wolf=" + wolf + " ]";
}
}
2、byName自动装配
只需要在bean标签内加上autowire=“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="wolf" class="com.spring.pojo.Wolf"/>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid!
-->
<bean id="people" class="com.spring.pojo.People" autowire="byName"/>
</beans>
注:使用byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!否则装配失败,报异常
3、byType自动装配
只需要将autowire="byName"改为autowire=“byType”
<!--
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
-->
<bean id="people1" class="com.spring.pojo.People" autowire="byType"/>
注:使用byType的时候,需要保证所有的bean和class唯一,并且这个bean需要和自动注入的属性的类型一致!否则装配失败,报异常
4、constructor自动装配
将autowire="byType"改为autowire=“constructor”,必须要在该类中加入需要装配类的构造方法
<bean id="people2" class="com.spring.pojo.People" autowire="constructor"/>
public class People {
private Wolf wolf;
public People() {
}
public People(Wolf wolf) {
this.wolf = wolf;
}
public Wolf getWolf() {
return wolf;
}
public void setWolf(Wolf wolf) {
this.wolf = wolf;
}
@Override
public String toString() {
return "People [wolf=" + wolf + " ]";
}
}
5、default自动装配
只需要将autowire="constructor"改为autowire=“default”
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName"
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="wolf" class="com.spring.pojo.Wolf"/>
<bean id="people2" class="com.spring.pojo.People" autowire="default"/>
</beans>
default是根据父级标签的默认装配方式进行自动装配,所以当前bean的装配方式是和beans的装配方式一样,装配方式为byName
方式二:使用注解实现自动装配
jdk1.5支持的注解,Spring2.5就支持注解了!
使用注解的前提:
- 导入约束。context约束
- 配置注解的支持:context:annoation-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>
@Autowired
直接在属性上使用即可!也可以在set方式上使用!
使用Autowired我们可以不用编写set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byname!但是编写了set方法也需要自动装配的属性在IOC(Spring)容器中存在。
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value=“xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!
public class People {
private String name;
@Autowired
@Qualifier(value="dogg")
private Dog dog;
@Autowired
private Cat cat;
}
扩展
@Nullable 字段标明了这个注解说明这个属性可以为空
@Autowired中的required属性的功能和@Nullable注解的功能一样,默认值为true,说明这个对象不允许为空,为false可以为空
public @interface Autowired{
boolean required() default true;
}
public class People {
private String name;
//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Dog dog;
@Autowired
private Cat cat;
}
@Resource
public class People
private String name;
@Resource(name="doggg")
private Dog dog;
@Resource
private Cat cat;
}
name属性与@Autowired注解的value属性作用相似
@Resource和@Autowired的区别:
- 都是用来自动装配的,都可以放在属性字段上
- @Autowired默认通过byType的方式实现,如果找到多个同类型的,则通过byName实现,并且这个对象必须存在
- @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下就报错!
- 执行顺序不同:@Autowired通过byType的方式实现。@Resource默认通过byname的方式实现。
- @Autowired是Spring定义的,@Autowired是java规范