所谓自动装配,就是将一个Bean注入到其他Bean的Property中,类似于以下:

在beans.xml:

<bean id="user" class="com" autowire=" autowire方式" />

Spring支持5种自动装配模式( autowire方式),如下:

  1. no            ——默认情况下,不自动装配,通过“ref”attribute手动设定。
  2. buName       ——根据Property的Name自动装配,如果一个bean的name,和另一个bean中的Property的name相同,则自动装配这个bean到Property中。
  3. byType     ——根据Property的数据类型(Type)自动装配,如果一个bean的数据类型,兼容另一个bean中Property的数据类型,则自动装配。
  4. constructor   ——根据构造函数参数的数据类型,进行byType模式的自动装配。
  5. autodetect   ——如果发现默认的构造函数,用constructor模式,否则,用byType模式。

 

实例:

一.目录结构

spring map properties注入_spring

二.代码

A.java

package com;

public class A {
	
	private B bbb;
	private C ccc;
	

	public void setBbb(B bbb) {
		this.bbb = bbb;
	}


	public void setCcc(C ccc) {
		this.ccc = ccc;
	}


	@Override
	public String toString() {
		bbb.testB();
		ccc.testC();
		
		return "我是A对象";
	}
	
	
}

B.java

package com;

public class B {
	
	public void testB() {
		System.out.println("我是B对象");
	}

}

C.java

package com;

public class C {

	public void testC() {
		System.out.println("我是C对象");
	}
	
}

Test.java

package test;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.A;

public class Test {

	public static void main(String[] args) {
		BeanFactory bf=new ClassPathXmlApplicationContext("beans.xml");
		A a=(A)bf.getBean("aaa");
		
		System.out.println(a);
	}
}

打印结果:

spring map properties注入_xml_02

1.当没有autowire:有两种方式的写法

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-3.0.xsd">
	
	<!-- 方法一:没有autowire的效果 -->
	<bean id="aaa" class="com.A">
		<property name="bbb"> <bean class="com.B"/></property>
		<property name="ccc"> <bean class="com.C"/></property>
	</bean>
	
	<!-- 方法二:用ref引用的方式来写,可以写为:
	<bean id="aaa" class="com.A" autowire="default">
		<property name="bbb" ref="bbb"></property>
		<property name="ccc" ref="cccc"></property>
	</bean>
	<bean id="bbb" class="com.B"></bean>
	<bean id="cccc" class="com.C"></bean>
	 -->
	 
</beans>

 

2.当autowire="byName" 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-3.0.xsd">

	<!-- autowire="byName",如果 -->
	<bean id="aaa" class="com.A" autowire="byName"></bean>
	<bean id="bbb" class="com.B"></bean>
	<bean id="ccc" class="com.C"></bean>
		 
</beans>

问题:如果根据 ccc name找不到对应的bean配置,如下

<!-- autowire="byName" id的属性必须-->
	<bean id="aaa" class="com.A" autowire="byName"></bean>
	<bean id="bbb" class="com.B"></bean>
	<bean id="ccc123" class="com.C"></bean>

配置文件中找不到ccc,只有ccc123,这时就会装配失败,运行后,A中ccc=null就会出错

 

3.当autowire="byType" 

设置了autowire="byType",Spring会总动寻找与属性类型相同的bean,找到后,通过调用setBbb(B bbb),setCcc(C ccc)将其注入。

<?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-3.0.xsd">

	<!-- autowire="byType" id的属性必须-->
	<bean id="aaa" class="com.A" autowire="byType"></bean>
	<bean id="bbb" class="com.B"></bean>
	<bean id="ccc123" class="com.C"></bean>
		 
</beans>

问题:如果配置文件中有两个类型相同的bean会怎样呢?如下:

spring map properties注入_自动装配_03

一旦配置如上,有两种相同数据类型的bean被配置,将抛出UnsatisfiedDependencyException异常,见以下:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: 
所以,一旦选择了’byType’类型的自动装配,请确认你的配置文件中每个数据类型定义一个唯一的bean。

 

4.当autowire="constructor " 

这种情况下,Spring会寻找与参数数据类型相同的bean,通过构造函数public A(B bbb, C ccc)将其注入。

A.java

package com;

public class A {
	
	private B bbb;
	private C ccc;
	

	public void setBbb(B bbb) {
		this.bbb = bbb;
	}


	public void setCcc(C ccc) {
		this.ccc = ccc;
	}
	
	public A(B bbb, C ccc) {
		this.bbb = bbb;
		this.ccc = ccc;
	}


	@Override
	public String toString() {
		bbb.testB();
		ccc.testC();
		
		return "我是A对象";
	}
	
	
}

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-3.0.xsd">

	<!-- autowire="constructor" -->
	<bean id="aaa" class="com.A" autowire="constructor"></bean>
	<bean id="bbb" class="com.B"></bean>
	<bean id="ccc" class="com.C"></bean>
	
		 
</beans>

5.当autowire="autodetect"

这种情况下,Spring会先寻找A中是否有默认的构造函数,如果有相当于上边的’constructor’这种情况,用构造函数注入,否则,用’byType’这种方式注入,所以,此例中通过调用public A(B bbb, C ccc)将其注入。

<!-- autowire="autodetect" -->
	<bean id="aaa" class="com.A" autowire="autodetect"></bean>
	<bean id="bbb" class="com.B"></bean>
	<bean id="ccc" class="com.C"></bean>

配置文件用手工装配才是最实用的。