前面的章节我们已经学习了如何使用bean元素在xml配置文件中声明一个bean.也学习了如何使用bean的子元素contructor-arg

和property进行bean的依赖项的注入.

之前bean的装配(依赖项的注入)都是我们手动进行了.我们之前使用contructor-arg元素指定使用bean的构造器参数进行依赖项

的注入;使用property元素指定使用bean的setter方法进行依赖项的注入.其实spring IOC容器支持bean的自动装配(依赖项的自

动注入).使用bean的自动装配功能可以大大缩减配置元数据的大小.

可以使用bean元素的autowire属性指定自动装配的类型,spring支持如下类型:

自动装配的类型 描述
no/default autowire="no"指定spring不使用自动装配,需要手动装配
byName 按照bean属性的名字从spring容器中找同名的bean进行注入,适用于setter注入
byType 按照bean属性的类型从spring容器中找相同类型的bean进行注入,适用于setter注入
constructor 按照类型装配,跟byType类似.适用于构造器参数注入

下面我们将分别讲解着四种装配类型

不使用自动装配-no

我们之前讲解的所有的例子都属于这种类型.在这种情况下所有bean的装配都是手动进行的.我们再用一个例子复习下

1.新建包com.tutorialspoint.autowire,并在包中新建Cat.java、Dog.java、Duck.java.后面所有例子都会用到这三个类:

//Cat.java
package com.tutorialspoint.autowire; public class Cat { public void sayHi(){
System.out.println("miao miao ... ");
}
} //Dog.java
package com.tutorialspoint.autowire; public class Dog { public void sayHi(){
System.out.println("wang wang ... ");
}
} //Duck.java
package com.tutorialspoint.autowire; public class Duck { public void sayHi(){
System.out.println("ga ga ... ");
}
}

2.新建包com.tutorialspoint.autowire.no,并在包中新建Zoo.java,内容如下:

package com.tutorialspoint.autowire.no;

import com.tutorialspoint.autowire.*;

public class Zoo {

    private Cat cat;
private Dog dog;
private Duck duck; public void setCat(Cat cat) {
this.cat = cat;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setDuck(Duck duck) {
this.duck = duck;
} public void print(){ if(cat==null){
System.out.println("cat is null");
}else{
cat.sayHi();
} if(dog==null){
System.out.println("dog is null");
}else{
dog.sayHi();
} if(duck==null){
System.out.println("duck is null");
}else{
duck.sayHi();
}
} }

3.在src目录下新建autowire_no.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"> <bean id="cat" class="com.tutorialspoint.autowire.Cat"></bean>
<bean id="dog" class="com.tutorialspoint.autowire.Dog"></bean>
<bean id="duck" class="com.tutorialspoint.autowire.Duck"></bean> <bean id="zoo" class="com.tutorialspoint.autowire.no.Zoo">
<property name="cat" ref="cat"></property>
<property name="dog" ref="dog"></property>
</bean> </beans>

4.在com.tutorialspoint.autowire.no包中新建MainApp.java.内容如下:

package com.tutorialspoint.autowire.no;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("autowire_no.xml"); Zoo zoo = (Zoo) context.getBean("zoo"); zoo.print();
}
}

5.运行程序,检查结果:

通过上面的程序我们可以得出如下结论:

手动装配bean,bean的所有依赖项都要在bean元素中明确指定.如果不进行指定spring容器就不会注入该属性.

按照名字进行自动装配-byName

在byName装配方式下,spring首先会反射autowire="byName"的bean,得到bean中的所有属性名(根据setter推算),然后从容

器中寻找同名的bean,最后把找到的bean注入到当前bean中.我们还是用代码说话:

1.新建包com.tutorialspoint.autowire.byname,并在包中新建Zoo.java类.内容如下:

package com.tutorialspoint.autowire.byname;

import com.tutorialspoint.autowire.Cat;
import com.tutorialspoint.autowire.Dog;
import com.tutorialspoint.autowire.Duck; public class Zoo { private Cat cat;
private Dog dog;
private Duck duck;
// 自动装配并不适用于原始类型.这时候我们可以对该属性进行手动装配
private String zooName; public void setZooName(String zooName) {
this.zooName = zooName;
} public void setCat(Cat cat) {
this.cat = cat;
} public void setDog(Dog dog) {
this.dog = dog;
} public void setDuck(Duck duck) {
this.duck = duck;
} public void print() { if (cat == null) {
System.out.println("cat is null");
} else {
cat.sayHi();
} if (dog == null) {
System.out.println("dog is null");
} else {
dog.sayHi();
} if (duck == null) {
System.out.println("duck is null");
} else {
duck.sayHi();
} System.out.println(zooName);
} }

2.在src目录下新建autowire_byName.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"> <!-- 名为zoo的bean在按照byName进行装配的时候,可以适配名字为cat、dog
的bean,不能适配名字为duck1的bean。所以最终zoo中会注入进cat和dog
不会注入duck. -->
<bean id="cat" class="com.tutorialspoint.autowire.Cat"></bean>
<bean id="dog" class="com.tutorialspoint.autowire.Dog"></bean>
<bean id="duck1" class="com.tutorialspoint.autowire.Duck"></bean> <bean id="zoo" class="com.tutorialspoint.autowire.byname.Zoo" autowire="byName">
<!-- 由于自动装配仅适用于引用类型,普通类型还需要手动进行注入 -->
<property name="zooName" value="international_zoo"></property>
</bean> </beans>

3.在包com.tutorialspoint.autowire.byname中新建MainApp.java.内容如下:

package com.tutorialspoint.autowire.byname;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("autowire_byName.xml"); Zoo zoo = (Zoo)context.getBean("zoo"); zoo.print();
}
}

4.运行代码,检查结果:

分析结果可以看到cat和dog已经按照属性名字自动装配到了zoo中.duck1由于没有匹配的属性名所以没有进行装配.zooName是

我们手动进行注入的。

按照类型进行自动装配-byType

在byType装配方式下,spring首先会反射autowire="byType"的bean,得到bean属性的返回类型,然后去spring容器中按照类

型去匹配,最后把匹配到的bean注入到当前bean中.看个例子就明白了:

1.新建包com.tutorialspoint.autowire.bytype,并在包中新建Zoo.java类,内容如下:

package com.tutorialspoint.autowire.bytype;

import com.tutorialspoint.autowire.Cat;
import com.tutorialspoint.autowire.Dog;
import com.tutorialspoint.autowire.Duck; public class Zoo { private Cat cat;
private Dog dog;
private Duck duck;
// 自动装配并不适用于原始类型.这时候我们可以对该属性进行手动装配
private String zooName; public void setZooName(String zooName) {
this.zooName = zooName;
} public void setCat(Cat cat) {
this.cat = cat;
} public void setDog(Dog dog) {
this.dog = dog;
} public void setDuck(Duck duck) {
this.duck = duck;
} public void print() { if (cat == null) {
System.out.println("cat is null");
} else {
cat.sayHi();
} if (dog == null) {
System.out.println("dog is null");
} else {
dog.sayHi();
} if (duck == null) {
System.out.println("duck is null");
} else {
duck.sayHi();
} System.out.println(zooName);
} }

2.在src目录下新建配置文件autowire_byType.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"> <!-- 名为zoo的bean在按照byType进行装配的时候,可以适配名字为cat1、dog1、duck1
的bean的类型。所以最终cat1、dog1、duck1会被分别注入进zoo的cat、dog、duck属性。
在按照类型进行装配的时候,如过有两个bean的类型符合的话,spring就不知道最终该使用哪个,这时候我们
可以使用primary="true"告诉spring优先使用本bean
-->
<bean id="cat1" class="com.tutorialspoint.autowire.Cat" primary="true"></bean>
<bean id="cat2" class="com.tutorialspoint.autowire.Cat"></bean>
<bean id="dog1" class="com.tutorialspoint.autowire.Dog"></bean>
<bean id="duck1" class="com.tutorialspoint.autowire.Duck"></bean> <bean id="zoo" class="com.tutorialspoint.autowire.bytype.Zoo" autowire="byType">
<!-- 由于自动装配仅适用于引用类型,普通类型还需要手动进行注入 -->
<property name="zooName" value="international_zoo"></property>
</bean> </beans>

3.在包com.tutorialspoint.autowire.bytype中新建MainApp.java。内容如下:

package com.tutorialspoint.autowire.bytype;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("autowire_byType.xml"); Zoo zoo = (Zoo)context.getBean("zoo"); zoo.print();
}
}

4.运行程序,检查结果:

构造器参数类型自动装配-constructor

在constructor自动装配模式下,spring首先会反射bean的构造函数,得出构造函数的参数的类型,然后起spring容器中匹配合适的

类型的bean,最后使用构造器参数注入的方法把符合的bean注入到当前bean中。看代码:

1.新建包com.tutorialspoint.autowire.constructor,并在包中新建Zoo.java。内容如下:

package com.tutorialspoint.autowire.constructor;

import com.tutorialspoint.autowire.*;

public class Zoo {

    private Cat cat;
private Dog dog;
private Duck duck;
private String zooName; public Zoo(Cat cat, Dog dog, Duck duck, String zooName) {
this.cat = cat;
this.dog = dog;
this.duck = duck;
this.zooName = zooName;
} public void print() { if (cat == null) {
System.out.println("cat is null");
} else {
cat.sayHi();
} if (dog == null) {
System.out.println("dog is null");
} else {
dog.sayHi();
} if (duck == null) {
System.out.println("duck is null");
} else {
duck.sayHi();
} System.out.println(zooName);
} }

2.在src目录下新建autowire_constructor.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"> <!-- constructor跟byType十分相似.
名为zoo的bean在按照constructor进行装配的时候,可以适配名字为cat1、dog1、duck1
的bean的类型。所以最终cat1、dog1、duck1会被分别注入进zoo的cat、dog、duck属性(使用
构造器参数进行注入)。
在按照constructor进行装配的时候,如过有两个bean的类型符合的话,spring就不知道最终该使用哪个,这时候我们
可以使用primary="true"告诉spring优先使用本bean
-->
<bean id="cat1" class="com.tutorialspoint.autowire.Cat" primary="true"></bean>
<bean id="cat2" class="com.tutorialspoint.autowire.Cat"></bean>
<bean id="dog" class="com.tutorialspoint.autowire.Dog"></bean>
<bean id="duck1" class="com.tutorialspoint.autowire.Duck"></bean> <bean id="zoo" class="com.tutorialspoint.autowire.constructor.Zoo" autowire="constructor">
<!-- 由于自动装配仅适用于引用类型,普通类型还需要手动进行注入 -->
<constructor-arg name="zooName" value="international_zoo"></constructor-arg>
</bean> </beans>

3.在com.tutorialspoint.autowire.constructor包中新建MainApp.java。内容如下:

package com.tutorialspoint.autowire.constructor;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("autowire_constructor.xml"); Zoo zoo = (Zoo)context.getBean("zoo"); zoo.print();
}
}

4.运行程序,检查结果:

如果使用sping的自动装配,本人不推荐使用xml的配置方式.最好使用注解的配置方式。原因如下:

1.基于xml的自动装配粒度态度。默认会装配所有符合条件的bean.不能指定哪个属性不进行自动装配

2.不能指定哪些属性必须进行装配,否则抛出异常.

以上两点使用spring的注解配置元数据都是可以做到的。我们下节就讲解spring注解配置元数据。

[译]15-spring 自动装配的更多相关文章

  1. Spring自动装配(二)

    为什么Spring要支持Autowire(自动装配) 先写几个类,首先定义一个Animal接口表示动物: 1 public interface Animal { 2 3 public void eat ...

  2. Spring 自动装配 Bean

    Spring3系列8- Spring 自动装配 Bean 1.      Auto-Wiring ‘no’ 2.      Auto-Wiring ‘byName’ 3.      Auto-Wiri ...

  3. spring 自动装配 default-autowire=&quot;byName/byType&quot;

    <PRE class=html name="code">spring 自动装配 default-autowire="byName/byType"   ...

  4. Spring自动装配Bean详解

    1.      Auto-Wiring ‘no’ 2.      Auto-Wiring ‘byName’ 3.      Auto-Wiring ‘byType 4.      Auto-Wirin ...

  5. Spring自动装配----注解装配----Spring自带的@Autowired注解

    Spring自动装配----注解装配----Spring自带的@Autowired注解 父类 package cn.ychx; public interface Person { public voi ...

  6. Spring系列七:Spring 自动装配

    相思相见知何日?此时此夜难为情. 概述 在Spring框架中,在配置文件中声明bean的依赖关系是一个很好的做法,因为Spring容器能够自动装配协作bean之间的关系.这称为spring自动装配. ...

  7. Spring自动装配歧义性笔记

    Spring自动装配歧义性笔记 如果系统中存在两个都实现了同一接口的类,Spring在进行@Autowired自动装配的时候,会选择哪一个?如下: // 一下两个类均被标记为bean @Compone ...

  8. Spring 自动装配;方法注入

    通过配置defalut—autowire属性,Spring IOC容器可以自动为程序注入Bean:默认是no(不启用自动装配). default—autowire的类型有: byName:通过名称自动 ...

  9. spring自动装配

    spring提供了自动装配(autowiring)和自动检测(autodiscovery)用来减少XML的配置数量. 自动装配bean属性 byName——把与Bean的属性具有相同名字(或ID)的其 ...

  10. Spring自动装配与扫描注解

    1 javabean的自动装配 自动注入,减少xml文件的配置信息. <?xml version="1.0" encoding="UTF-8"?> ...

随机推荐

  1. php一个类引用另一个类的方法的写法

    default.php: <?php namespace SiteInfo{ class Site{ var $url; var $title; function setUrl($par){ $ ...

  2. Vsftpd服务传输文件(转)

    本章节先通过介绍文件传输协议来帮助读者理解FTP协议的用处,安装vsftpd服务程序并逐条分析服务文件的配置参数. 完整演示vsftpd服务匿名访问模式.本地用户模式及虚拟用户模式的配置方法,介绍PA ...

  3. 高精度水题(POJ2109)

    题目链接:http://poj.org/problem?id=2109 double 可以虽然可以表示10^-307~~~10^208,但是精确度只有16位,这个题有bug. #include < ...

  4. (转载)Fiddler模拟post四种请求数据

    https://www.cnblogs.com/xiaoxi-3-/p/7612254.html https://blog.csdn.net/qq_15283475/article/details/5 ...

  5. C/C++语言代码规范

    1.标识符名称: 标识符名称包括函数名.常量名.变量名等.这些名字应该能反映它所代表的实际东西,具有一定的意义,使其能 够见名知义,有助于对程序功能的理解.规则如下: 所有宏定义.枚举常数和const ...

  6. Nginx + uWSGI + web.py 搭建示例

    (1)安装Nginx1.1 下载nginx-1.0.5.tar.gz并解压1.2 ./configure (也可以增加--prefix= path指定安装路径)此时有可能会提示缺少pcre支持,如果要 ...

  7. Android笔记(adb命令--reboot loader)

    Android 的机器通过adb进入升级模式的方法 # adb shell # reboot loader 通过上面两个命令就进入升级模式了,通过工具升级就好了 为什么会写这简单的一篇呢?因为今天干了 ...

  8. Linq to Entity 时间差作为筛选条件产生的问题

    前言 在使用 Linq to Entity 的時候,會把之前 Linq to SQL 的想法就帶進去,寫好之後編譯也都不會出錯,但是實際上在跑的時候就會出現錯誤訊息了,這點真的要注意了.這次我遇到問題 ...

  9. 学习JavaScript一些资料时,记录一些规范小记

    最近工作不是很忙,所以再深入学学JavaScript,顺便提升一下自己,嘿嘿!主要记录一下学习到的一下编写代码的规范小记吧! 1.声明变量时一定带上var,避免一些错误发生,如变量提升时遇见的问题发生 ...

  10. 没有CTO的Netflix有哪些值得我们学习的工程文化?

    作者介绍: 杨波,拍拍贷基础框架研发总监.具有超过 10 年的互联网分布式系统研发和架构经验,曾先后就职于:eBay 中国研发中心(eBay CDC),任资深研发工程师,参与亿贝开放 API 平台研发 ...