`

Spring之IOC自动装配总结

阅读更多

  林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

     set注入和构造注入有时在做配置时比较麻烦。所以框架为了提高开发效率,提供自动装配功能,简化配置。Spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean>标签的autowire属性。自动装配属性有5个值可选,分别代表不同的含义。 

本文工程免费下载

1、byName

 从Spring环境中获取目标对象时,目标对象中的属性会根据名称在整个Spring环境中查找<bean>标签的id属性值。如果有相同的,那么获取这个对象,实现关联。

 整个Spring环境:表示所有的spring配置文件中查找,那么id不能有重复的。

 

2、byType

 从Spring环境中获取目标对象时,目标对象中的属性会根据类型在整个spring环境中查找<bean>标签的class属性值。如果有相同的,那么获取这个对象,实现关联。

        缺点:如果存在多个相同类型的bean对象,会出错。

如果属性为单一类型的数据,那么查找到多个关联对象会发生错误。

如果属性为数组或集合(泛型)类型,那么查找到多个关联对象不会发生异常。

3、constructor(3.x以上已不能用)

 使用构造方法完成对象注入,其实也是根据构造方法的参数类型进行对象查找,相当于采用byType的方式。如果没找到则抛出异常

4、autodetect

 自动选择:如果对象没有无参数的构造方法,那么自动选择constructor的自动装配方式进行构造注入。如果对象含有无参数的构造方法,那么自动选择byType的自动装配方式进行setter注入。                      

5、no

默认情况下,不自动装配,通过“ref”attribute手动设定。 

        <bean>标签的 autowire 属性,它负责自动装配<bean>标签定义 JavaBean 的属性。这样做可以省去很多配置 JavaBean 属性的标签代码,使代码整洁、美观。但是它也有负面影响,即使用自动装配之后,无法从配置文件中读懂 JavaBean 需要什么属性。自动装配存在很多不正确的装配问题,例如错误装载属性、“byType”属性和“constructor”属性对相同类型参数无法判断等。当然,将自动装配和手动装配混合使用也能解决此问题。下面通过一个实例来分析如何使用自动装配。

首先创建创建一个学生类 Student,定义学号、姓名、性别、年龄等属性,并添加对

应的 set()与 get()方法。程序代码如下。

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.autobean;  
  2.   
  3. public class Student {  
  4.     private String ID;  
  5.     private String name;  
  6.     private int age;  
  7.     private String sex;  
  8.   
  9.     public String getID() {  
  10.         return ID;  
  11.     }  
  12.   
  13.     public void setID(String iD) {  
  14.         ID = iD;  
  15.     }  
  16.   
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.   
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.   
  25.     public int getAge() {  
  26.         return age;  
  27.     }  
  28.   
  29.     public void setAge(int age) {  
  30.         this.age = age;  
  31.     }  
  32.   
  33.     public String getSex() {  
  34.         return sex;  
  35.     }  
  36.   
  37.     public void setSex(String sex) {  
  38.         this.sex = sex;  
  39.     }  
  40.   
  41. }  

同样创建一个教师类 Teacher,定义姓名、性别和年龄等属性,并添加对应的 set()与 get()方法。程序代码如下。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.autobean;  
  2.   
  3. public class Teacher {  
  4.     private String name;  
  5.     private int age;  
  6.     private String sex;  
  7.   
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.   
  12.     public void setName(String name) {  
  13.         this.name = name;  
  14.     }  
  15.   
  16.     public int getAge() {  
  17.         return age;  
  18.     }  
  19.   
  20.     public void setAge(int age) {  
  21.         this.age = age;  
  22.     }  
  23.   
  24.     public String getSex() {  
  25.         return sex;  
  26.     }  
  27.   
  28.     public void setSex(String sex) {  
  29.         this.sex = sex;  
  30.     }  
  31.   
  32. }  

创建教学档案类 TeachFile,定义 Teacher 和 Student 两个属性,并添加 print()方法。用于输出教师与学生的信息。程序代码如下。 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.autobean;  
  2.   
  3. public class TeachFile {  
  4.     private Teacher teacher;  
  5.     private Student student;  
  6.     public TeachFile() {  
  7.     }  
  8.     public TeachFile(Teacher teacher, Student student) {  
  9.         this.teacher = teacher;  
  10.         this.student = student;  
  11.     }  
  12.   
  13.     public Student getStudent() {  
  14.         return this.student;  
  15.     }  
  16.   
  17.     public void setStudent(Student student1) {  
  18.         this.student = student1;  
  19.     }  
  20.   
  21.     public Teacher getTeacher() {  
  22.         return teacher;  
  23.     }  
  24.   
  25.     public void setTeacher(Teacher teacher) {  
  26.         this.teacher = teacher;  
  27.     }  
  28.   
  29.     public void print() {  
  30.         System.out.println("------教师信息------");  
  31.         System.out.println("姓名:" + teacher.getName());  
  32.         System.out.println("年龄:" + teacher.getAge());  
  33.         System.out.println("性别:" + teacher.getSex());  
  34.         System.out.println();  
  35.         System.out.println("------学生信息------");  
  36.         System.out.println("学号:" + student.getID());  
  37.         System.out.println("姓名:" + student.getName());  
  38.         System.out.println("年龄:" + student.getAge());  
  39.         System.out.println("性别:" + student.getSex());  
  40.     }  
  41.   
  42. }  


在配置文件applicationContext.xml中定义刚刚创建的类,并为其赋值。其中 TeachFile 类采用了自动装配。程序代码如下。 

 

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  xmlns:p="http://www.springframework.org/schema/p"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans 
  6. http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">  
  7.   
  8.     <bean id="student" class="com.autobean.Student">  
  9.         <property name="ID" value="80" />   
  10.         <property name="name" value="阿王" />   
  11.         <property name="age" value="23" />   
  12.         <property name="sex" value="男" />   
  13.     </bean>  
  14.     <bean id="teacher" class="com.autobean.Teacher">  
  15.         <property name="name" value="何老师" />   
  16.         <property name="age" value="43" />   
  17.         <property name="sex" value="女" />   
  18.     </bean>  
  19.     <!-- 默认情况下,通过'ref’来装配bean -->  
  20.     <bean id="teachFile1" class="com.autobean.TeachFile" >  
  21.      <property name="teacher" ref="teacher" />  
  22.      <property name="student" ref="student" />  
  23.     </bean>  
  24.     <!--根据byName自动装配bean -->  
  25.     <bean id="teachFile2" autowire="byName"  class="com.autobean.TeachFile" />  
  26.       <!--根据byType自动装配bean -->  
  27.     <bean id="teachFile3" autowire="byType" class="com.autobean.TeachFile" />  
  28.       <!--根据constructor自动装配bean -->  
  29.     <bean id="teachFile4" autowire="constructor" class="com.autobean.TeachFile"/>  
  30. </beans>  


在这个配置文件中定义了 Student 类和 Teacher 类,并为姓名、年龄和性别属性赋值。在定义 TeachFile 类时,没有传递任何参数,而是采用了 autowire 属性自动配置 TeachFile类所需要的属性。下面编写一个主类 PrintInfo 类来输出档案信息。程序代码如下。

 

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.autobean;  
  2.   
  3. import org.springframework.beans.factory.BeanFactory;  
  4. import org.springframework.beans.factory.xml.XmlBeanFactory;  
  5. import org.springframework.core.io.ClassPathResource;  
  6. import org.springframework.core.io.Resource;  
  7.   
  8. public class PrintInfo {  
  9.   
  10.     public static void main(String[] args) {  
  11.         Resource res = new ClassPathResource("applicationContext.xml");  
  12.         BeanFactory bf = new XmlBeanFactory(res);  
  13.         TeachFile tf1 = (TeachFile) bf.getBean("teachFile1");  
  14.         TeachFile tf2 = (TeachFile) bf.getBean("teachFile2");  
  15.         TeachFile tf3 = (TeachFile) bf.getBean("teachFile3");  
  16.         TeachFile tf4 = (TeachFile) bf.getBean("teachFile4");  
  17.   
  18.       
  19.         System.out.println("默认情况下,通过'ref’来装配bean");  
  20.         tf1.print();  
  21.         System.out.println("根据byName自动装配bean");  
  22.         tf2.print();  
  23.         System.out.println("根据byType自动装配bean");  
  24.         tf3.print();  
  25.         System.out.println("根据constructor自动装配bean");  
  26.         tf4.print();  
  27.       
  28.     }  
  29.   
  30. }  

 

输出结果:

四月 02, 2015 8:16:48 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
默认情况下,通过'ref’来装配bean
------教师信息------
姓名:何老师
年龄:43
性别:女

------学生信息------
学号:80
姓名:阿王
年龄:23
性别:男
根据byName自动装配bean
------教师信息------
姓名:何老师
年龄:43
性别:女

------学生信息------
学号:80
姓名:阿王
年龄:23
性别:男
根据byType自动装配bean
------教师信息------
姓名:何老师
年龄:43
性别:女

------学生信息------
学号:80
姓名:阿王
年龄:23
性别:男
根据constructor自动装配bean
------教师信息------
姓名:何老师
年龄:43
性别:女

------学生信息------
学号:80
姓名:阿王
年龄:23
性别:男

 

在上面实例的配置文件 appContext.xml 中,TeachFile 类采用4种装配,将 Teacher
类和 Student 类注入到对应的属性中。语法格式如下。

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <bean autowire="byName" id="teachFile" class="TeachFile" />  

在 autowire 属性中指定类型为“byName”。autowire 属性共支持 5 种装配类型,下面
分别介绍每种装配类型的用法。
(1)no:autowire 采用的默认值,采用自动装配。必须使用 ref 直接引用其他 Bean,这样可以增加代码的可读性,并且不易出错。
(2)byName:以属性名区分自动装配。在容器中寻找与 JavaBean 的属性名相同的JavaBean,并将其自动装配到 JavaBean 中。如果用上面的实例来解释,TeachFile 类的实例对象 teachFile 包含的两个属性分别是 Teacher 类和 Student 类的实例对象,而配置文件中已经定义了这两个类的实例。在定义 teachFile 实例时指定了自动装配类型为“byName”,容器会自动寻找 teachFile 实例需要的属性(即 teacher 和 student 两个 JavaBean),并注入到 teachFile 实例中。此类自动装配类型存在错误装配 JavaBean 的可能,如果配置文件中定义了与需要自动装配的 JavaBean 属性相同而类型不同的 JavaBean,那么它会错误地注入不同类型的JavaBean。读者可以将上面实例中的配置文件修改一下,将 student 和 teacher 两个JavaBean 的类型保持不变,将名字调换一下,便会出现此问题。这时自动装配无法解决此问题,只能通过混合使用手动装配来指定装配哪个 JavaBean。
(3)byType:以属性类型区分自动装配。容器会自动寻找与 JavaBean 的属性类型相同的 JavaBean 的定义,并将其注入到需要自动装配的 JavaBean 中。如果将上面配置JavaBean 自动装配的类型修改为 byType,也可以实现相同的结果。这种自动装配类型也会出现无法自动装配的情况。例如在配置文件中再次添加一个Student 类或 Teacher 类的实现对象,byType 自动装配类型会因为无法自动识别装配哪一个 JavaBean 而抛出org.springframework.beans.factory.UnsatisfiedDependencyException 异常。要解决此
问题,只能通过混合使用手动装配来指定装配哪个 JavaBean。
(4)constructor:通过构造方法的参数类型自动装配。此类型会使容器自动寻找与JavaBean 的构造方法的参数类型相同的 Bean,并注入到需要自动装配的 JavaBean 中。它
与 byType 类型存在相同的无法识别自动装配的情况。
(5)autudetect:这是最后一个自动装配类型,它首先使用 constructor 方式自动装配,然后使用 byType 方式。当然它也存在与 byType 和 constructor 相同的异常情况。建

议在使用自动装配时,把容易出现问题的 JavaBean 使用手动装配注入依赖属性

分享到:
评论

相关推荐

    实现Spring那样的Ioc注解装配

    本文将深入探讨如何实现一个类似于Spring的IoC注解装配机制。 IoC是Spring的核心概念,它通过反转对象的创建和管理权,将这些任务交给容器来处理,从而使开发者可以更专注于业务逻辑。在Spring中,DI是IoC的一种...

    模拟Spring的IoC容器实现注解自动装配

    而注解自动装配(Autowired)是Spring IoC容器的一种高级特性,它允许我们通过注解来声明对象之间的依赖,无需手动编写XML配置。现在,我们将深入探讨如何模拟Spring的IoC容器实现注解自动装配。 首先,我们需要...

    Spring之IOC示例

    除了XML配置,Spring还支持注解驱动的配置,如`@Component`、`@Service`、`@Repository`和`@Controller`等,以及`@Autowired`来自动装配依赖。例如: ```java @Service public class UserRepository { // ... } @...

    Spring-ioc-jar

    Spring IOC,全称为Inversion of Control,中文常被称为“控制反转”,是Spring框架的核心特性之一。这个概念在软件设计中引入了一种新的依赖管理方式,它将对象的创建和管理权交给了容器,使得开发者可以更专注于...

    模拟实现Spring的IOC

    1、Spring主要两个作用:实例化Bean,动态装配Bean。并将所有的bean放到spring容器中,调用时从容器中取。Spring容器就是一个bean的Map:private Map, Object&gt; beans = new HashMap, Object&gt;(); 2、本工程,模拟...

    Spring源码分析_Spring_IOC

    在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色与地位。对于Spring的使用者而言,IOC容器不仅是管理Bean(即应用中的对象实例)生命周期的...

    以注解方式模拟Spring IoC AOP

    总结来说,模拟Spring的IoC和AOP主要是通过注解来管理和控制对象的生命周期及行为。虽然这种模拟简化了Spring的复杂性,但其核心思想是一致的:降低耦合,提高可维护性和可扩展性。理解并实践这些概念,对于掌握...

    Spring-IOC实现

    Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性,它将对象的创建和管理权交由Spring容器处理,使得开发者可以更专注于业务逻辑的编写,而不是对象的生命周期管理。下面,我们将深入探讨Spring...

    maven-spring-ioc

    理解并熟练运用Spring的IoC机制是成为一名优秀的Java开发者的关键步骤之一。在实际项目中,结合Maven进行项目构建和管理,可以更高效地组织和运行Spring应用。通过不断的实践和学习,你将能够充分利用Spring框架的...

    模拟Spring的IOC

    在Java世界中,Spring框架以其强大的依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IOC)能力,成为企业级应用开发的首选框架之一。理解并模拟Spring的IOC机制对于深入学习Spring...

    Spring的IoC实现案例

    总结来说,这个案例展示了Spring IoC如何帮助我们构建松散耦合的系统。通过IoC,我们可以轻松地更改`Priter`类使用的纸张类型,而无需修改`Priter`类本身的代码。这不仅提高了代码的可测试性,还增强了系统的可扩展...

    Spring的IOC原理

    总结,Spring的IOC原理是通过控制反转和依赖注入来降低对象间的耦合,提升系统的可扩展性和可维护性。它提供了一种高效的方式来管理和组合对象,使得开发者可以专注于业务逻辑的实现,而非对象的创建和管理。

    一个简单的模仿spring的ioc实现

    这个简单的实现可能没有Spring的全部功能,例如,它可能不支持自动扫描、AOP、属性占位符等高级特性。但它足以帮助我们理解IoC的基本思想:对象的创建和管理由外部容器负责,而不是由对象自己控制。 此外,通过查看...

    Spring4 IOC 示例源码

    Spring4 IOC(Inversion of Control,控制反转)是Spring框架的核心特性之一,它极大地简化了Java应用程序的开发。在这个示例源码中,我们可以深入理解并学习如何在实际项目中运用Spring的IOC容器来管理对象的生命...

    spring ioc和aop原理流程图(详细)

    Spring容器负责管理Bean的生命周期,并根据Bean之间的依赖关系进行实例化和装配。依赖可以通过属性注入、构造函数注入或方法注入等方式实现。 4. **Bean的作用域**:Spring提供了多种Bean的作用域,如单例...

    SpringIoc示例代码

    Spring IOC,全称Inversion of Control,即“控制反转”,是Spring框架的核心特性之一。在传统的Java应用程序中,对象的创建和管理通常由开发者自己控制。而在Spring IOC中,这种控制权被反转,对象的创建、初始化、...

    Spring IOC源码解读

    Spring IOC,即Inversion of Control(控制反转),是Spring框架的核心特性之一,它负责管理和装配应用程序中的对象。在传统的编程模式中,对象通常自行创建和管理它们所依赖的其他对象,这导致了代码间的高耦合。而...

    spring_ioc.docx

    【Spring 框架与控制反转 (IOC) 知识详解】 Spring 框架是 Java Web 开发中广泛使用的轻量级框架,其核心特性是控制反转 (IOC) 和依赖注入 (DI)。控制反转是指将对象的创建权从应用程序代码转移到框架,即不再由...

    spring_ioc spring ioc

    Spring的IoC容器主要负责对象的创建、装配、管理以及生命周期的维护等工作。 - **配置文件**:开发者可以通过XML文件或基于注解的方式声明对象的创建规则和依赖关系。这些规则告诉Spring IoC容器如何创建对象、何时...

    Spring IoC讲解PPT

    IoC(Inversion of Control)即控制反转,是 Spring 的核心特性之一。在传统的编程模式中,对象之间存在依赖关系,程序员需要手动创建和管理这些对象。而在 Spring 中,IoC 容器负责管理和创建对象,对象之间的依赖...

Global site tag (gtag.js) - Google Analytics