3依赖注入
Spring bean
的依赖注入有两种形式,通过构造方法注入和通过set
方法注入。构造方法注入是通过constructor-arg
元素来指定的,而set
方法注入是通过property
元素来指定的。
3.1构造方法注入
先来看一个简单的示例:
<bean id="hello" class="com.app.Hello">
<constructor-arg value="hello"/>
</bean>
上述配置定义了一个类型为com.app.Hello
的bean
,我们通过constructor-arg
指定了其第一个构造参数的值为字符串“hello”
,这就是一个简单的通过构造方法进行注入的示例。
当参数类型为基本数据类型时可以直接通过constructor-arg
元素的value
属性指定对应的值,更确切的讲应该是Spring
能够通过String
进行转换的类型,默认Spring
能将String
转换成对应的基本数据类型,其它的需要自己指定转换规则了。如上面示例中的value=”hello”
就是这样的。
当有多个构造参数时就需要使用多个constructor-arg
进行定义,默认会将定义的顺序作为参数的顺序。
public class Hello {
public Hello(String str1, boolean b2, int i3) {
}
}
如上Class
,我们在定义对应的bean
时可以如下定义,这个时候默认会按照定义的顺序将第一个参数赋值给构造方法的第一个参数,第二个给第二个,第n个给第n个。
<bean id="hello" class="com.app.Hello">
<constructor-arg value="str1"/><!-- str1 -->
<constructor-arg value="true"/><!-- b2 -->
<constructor-arg value="3"/><!-- i3 -->
</bean>
当然,我们也可以明确的利用index
来指定constructor-arg
对应参数的位置,index
是从0开始的,即第一个参数对应的index
为0。使用index
时,Hello
对应的bean
可以如下定义。
<bean id="hello" class="com.app.Hello">
<constructor-arg index="1" value="true"/><!-- b2 -->
<constructor-arg index="0" value="str1"/><!-- str1 -->
<constructor-arg index="2" value="3"/><!-- i3 -->
</bean>
当构造参数对应于ApplicationContext
中的一个bean
时,我们也可以通过ref
属性关联对应的bean
,即注入的不再是普通的字符串,而是对应的bean
。
public class Hello {
public Hello(World world1) {
}
}
<bean id="world" class="com.app.World"/>
<bean id="hello" class="com.app.Hello">
<constructor-arg ref="world"/>
</bean>
我们还可以通过constructor-arg
元素的name
属性来指定对应constructor-arg
对应的参数,如:
public class Hello {
public Hello(String s1, int i2) {
}
}
<bean id="hello" class="com.app.Hello">
<constructor-arg name="i2" value="2"/><!-- 对应参数i2 -->
<constructor-arg name="s1" value="1"/><!-- 对应参数s1 -->
</bean>
但是这需要我们的class
是通过debug
方式进行编译的,这样Spring
才能识别出对应的参数名称。当然我们也可以通过JDK
提供的@ConstructorProperties
注解来指定构造参数对应的名称。如:
public class Hello {
@ConstructorProperties({"s1", "i2"})
public Hello(String s1, int i2) {
}
}
当我们的构造参数比较复杂,比如是一个array、list、set、map
等或者需要定义一个内部的bean
时,我们可以直接在constructor-arg
元素中间进行定义,如:
<bean id="hello" class="com.app.Hello">
<constructor-arg>
<bean class="com.app.World"/>
</constructor-arg>
</bean>
3.2set方法注入
set
方法注入是通过property
元素定义的。定义时我们需要指定property
元素的name
属性,其对应的值并非bean
需要进行注入的属性名称,而是对应set
方法去掉set
前缀后首字母小写的结果。
public class Hello {
private String prop1;
public void setProp(String prop) {
this.prop1 = prop;
}
}
对于上述class
定义,如果现在我们需要定义对应的bean
,并通过setProp()
方法将字符串“Value”
注入给其私有属性prop1
,那么我们的bean
应该如下定义:
<bean id="hello" class="com.app.Hello">
<property name="prop" value="Value"/>
</bean>
在上述示例中property
元素对应的语义是setProp(“value”)
,即我们的注入虽然是通过property
元素进行的,但其不是通过bean
的某属性进行注入的,而是通过对应的set
方法进行注入的。
对于基本数据类型值我们可以直接通过property
元素的value
属性进行注入,如果需要注入其它bean
,我们可以通过在property
元素下定义ref
元素进行引用或者通过property
元素的ref
属性进行引用,也可以在property
元素下定义bean
元素进行注入。对于其它集合类型,如Set、List、Map、Array、Properties
等则可以在property
元素下通过set、list
等元素进行定义。
3.3idref
当我们需要通过构造方法或者set
方法给bean
注入一个普通的字符串类型的值时,我们可以直接进行注入,如下就是直接将字符串“Value1”
通过setP1()
方法注入对应的bean
的示例。
<bean id="hello" class="com.app.Hello">
<property name="p1" value="Value1"/>
</bean>
当我们需要注入的普通字符串是bean
容器中另一个bean
的beanName
时,我们还可以通过idref
元素来指定对应的值,此时对应的值是通过idref
元素的bean
属性来指定的。当使用idref
元素来指定对应的值时Spring
将检查ApplicationContext
中是否存在id
或name
为idref
元素的bean
属性值的bean
,所以当我们使用idref
元素时需要我们的ApplicationContext
中存在idref
对应的bean
。当我们需要指定的值确实是ApplicationContext
中一个bean
的id
或name
时,这可以帮助我们在Spring
初始化对应的bean
时就发现对应的错误。
<bean id="world" class="com.app.World"/>
<bean id="hello" class="com.app.Hello">
<!-- 将字符串world通过bean的setP1()方法进行注入 -->
<property name="p1">
<!-- 注入的是字符串world,但是Spring将检查ApplicationContext中是否存在id或name为world的bean -->
<idref bean="world"/>
</property>
</bean>
在上述配置中我们给id
为hello
的bean
通过setP1()
方法注入的是字符串world
,而不是其对应的bean
。由于我们是通过idref
元素来注入字符串world
的,Spring
将检查ApplicationContext
中是否存在id
或name
为world
的bean
。
3.4ref元素关联其它bean
不管是通过构造方法注入还是通过set
方法注入依赖项,我们都可以通过ref
元素关联其它的bean
。ref
元素可以用来定义对应的关联项,而真正的关联项是通过ref
元素的bean
属性或parent
属性来指定的,它们对应的是目标bean
的id
或name
。
<bean id="hello" class="com.app.Hello">
<property name="world">
<ref bean="world"/><!-- 关联id或name为world的bean -->
</property>
</bean>
<bean id="world" class="com.app.World"/>
ref
的bean
属性关联和parent
属性关联是不同的。通过bean
属性指定关联时会在当前容器及其父容器中寻找关联项,而通过parent
属性指定关联时只会在当前容器的父容器中寻找关联项。
<!-- 假设是定义在父容器中的bean -->
<bean id="parenWorld" class="com.app.World"/>
<bean id="hello" class="com.app.Hello">
<property name="world">
<ref parent="parentWorld"/><!-- 关联父容器中id或name为world的bean -->
</property>
</bean>
不管是通过构造方法注入还是通过set
方法注入,我们都可以通过属性ref
来替代<ref bean=”…”/>
,如上面的示例我们就可以替换成如下这样:
<bean id="hello" class="com.app.Hello">
<property name="world" ref="world"/><!-- 使用ref属性替代<ref bean="..."/> -->
</bean>
<bean id="world" class="com.app.World"/>
3.5复合属性的注入
设想一下我们的beanA
有一个属性beanB
,而beanB
又有一个属性beanC
,beanC
又有一个属性propD
,我们可以直接在定义beanA
的时候指定对应的beanB
的属性beanC
的属性propD
的值,如:
<bean id="beanA" class="com.app.beanA">
<property name="beanB.beanC.propD" value="ValueD"/>
</bean>
其对应的语义是beanA.getBeanB().getBeanC().setPropD(“ValueD”)
,所以能够成功指定propD
值的条件是getBeanB()
不能为null
,getBeanB()
的getBeanC()
也不能为null
。当然,最终要注入的不一定是基本数据类型,换成是一个bean
也是可以的,如:
<bean id="beanA" class="com.app.beanA">
<property name="beanB.beanC.beanD" ref="beanD"/>
</bean>
(注:本文是基于Spring4.1.0所写)
相关推荐
Spring Boot引入了一种更智能的依赖注入方式——自动配置。自动配置是通过`@EnableAutoConfiguration`注解启动的,它根据项目中的类路径和特定条件自动配置Bean。例如,如果类路径下存在`MongoClient`的jar,Spring ...
在Java开发领域,Spring框架是应用最广泛的轻量级框架之一,它提供了强大的依赖注入(Dependency Injection,简称DI)功能,极大地简化了组件之间的耦合。本知识点将深入探讨Spring框架如何通过注解方式实现依赖注入...
### Spring核心机制——依赖注入详解 #### 一、引言 Spring框架作为一款优秀的轻量级Java应用开发框架,其核心理念之一就是依赖注入(Dependency Injection, DI)。依赖注入不仅能够帮助开发者降低代码间的耦合度...
在Spring框架中,依赖注入(Dependency Injection,简称DI)是一种重要的设计模式,它允许对象之间的耦合性降低,使得代码更易于测试和维护。依赖注入的核心思想是将一个对象依赖的其他对象通过构造函数、setter方法...
标题 "Spring 简单案例(依赖注入)_02" 暗示我们将探讨的是Spring框架中的一个重要概念——依赖注入(Dependency Injection,简称DI)。在Spring框架中,依赖注入是一种设计模式,它允许我们解耦组件,使得代码更加...
本项目以"Spring_依赖注入_面向接口编程_不同加载方式"为主题,旨在帮助初学者理解Spring的核心特性——依赖注入(Dependency Injection,简称DI),以及如何通过面向接口编程来提高代码的可维护性和可扩展性。...
使用Spring框架能够为开发者带来许多好处,例如通过依赖注入(Dependency Injection, DI)方法,能够清晰地管理对象间的依赖关系,相比于EJB容器,Spring的IoC容器更为轻量级,更适合在有限的内存和CPU资源下进行...
本文将深入探讨Spring框架中的核心特性——依赖注入(Dependency Injection,简称DI),以及如何在项目中实现和利用这一特性。 依赖注入是Spring的核心概念之一,它的主要目标是降低组件之间的耦合性,提高代码的可...
本篇将详细讲解如何使用构造器注入作为Spring依赖注入的一种方式,并通过一个完整的可运行示例——"SpringIOCTest2"来加深理解。 首先,理解依赖注入的概念。依赖注入允许我们不在类内部创建对象,而是通过外部源...
在本教程中,我们将深入探讨Spring框架中的一个重要概念——依赖注入(Dependency Injection,简称DI),以及如何通过XML配置实现这一机制。Spring是一个流行的Java企业级应用程序框架,它提供了丰富的功能,包括...
当我们把Quartz与Spring整合时,可以利用Spring的依赖注入(DI)和管理上下文来更方便地控制和管理定时任务。 在"Quartz Spring整合——附带webservice Demo"的项目中,我们可以看到如何将这两个强大的工具结合在...
Spring框架中的IOC(控制反转)和DI(依赖注入)是两种关键的设计模式,它们极大地提升了软件的可维护性和可扩展性。控制反转是一种设计思想,它改变了传统的对象创建方式,将对象的创建和管理权从应用程序自身转移...
- **Spring.NET**:Spring.NET是.NET平台上的Spring框架,它提供了一整套企业级开发所需的工具和框架,包括依赖注入支持。 - **Unity**:Unity是一个由Microsoft开发的轻量级IoC Container,支持多种依赖注入模式,...
本文将深入探讨Spring框架的核心特性——依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP),以及如何解决循环依赖问题。 首先,依赖注入是Spring框架的核心理念之一,它的...
【依赖注入 (DI) 实现】 DI 是 IoC 的具体体现,通过将依赖对象的创建和管理交由 IoC 容器处理,使得应用组件只需关注自身职责,而不需关心依赖对象的实例化。Spring 提供了两种方式实现 DI: 1. **构造器注入**:...
在Spring框架中,Aware接口系列是其核心特性之一,它为Spring容器提供了向bean注入上下文信息的能力。这些接口让bean能够感知到Spring容器的存在,从而获取必要的服务或配置信息。下面我们将深入探讨Spring的Aware...
标题 "03_mvc和依赖注入部分实现_源码" 暗示了这是一个关于Java Web开发中的关键概念——Model-View-Controller(MVC)架构以及依赖注入(Dependency Injection,DI)技术的实践项目。在Java开发中,MVC模式被广泛...
《ProSpring——Spring专业开发指南》是一本深入探讨Spring框架的专业书籍,旨在帮助开发者全面理解和掌握Spring的核心概念、功能及最佳实践。通过阅读本书,你可以深入理解Spring如何为Java应用程序提供强大的依赖...
Spring 提供了一个强大的依赖注入容器,可以自动地将依赖项注入到 Bean 中,从而简化了系统的开发和维护。 依赖注入模式的优点包括: * 松散耦合:依赖注入模式使得组件之间的依赖关系变得松散,提高了系统的灵活...