2021-04-14

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就支持注解了!

使用注解的前提:

  1. 导入约束。context约束
  2. 配置注解的支持: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规范
上一篇:Spring体系之核心容器篇


下一篇:@Autowired 与@Resource的区别