[Spring实战系列](8)Spring注入方式之setter注入

通常,JavaBean 的属性是私有的,同时拥有一组存取器方法,以setXXX() 和getXXX() 形式存在。Spring 可以借助属性的set方法来配置属性的值,以实现setter方式的注入。

1. 注入简单值

在Spring 中我们可以使用<property> 元素配置Bean 的属性。<property>在许多方面都与<constructor-arg> 类似,只不过一个是通过构造参数来注入值,另一个是通过调用属性的setter 方法来注入值。

举例说明,让我们使用setter注入为Student学生赋予一些基本信息,setter注入必须借助setXXX方法来配置属性的值。Student类一共有两个属性,name和age,我们都提供了相应的set方法。


package com.sjf.bean;

 

/**

 * 学生实体类

 * @author sjf0115

 *

 */

public class Student {

	

	private String name;

	private int age;

	

	public void setName(String name) {

		this.name = name;

	}

 

	public void setAge(int age) {

		this.age = age;

	}

 

	@Override

	public String toString() {

		StringBuilder stringBuilder = new StringBuilder();

		stringBuilder.append("个人详细信息如下:" + "\n");

		stringBuilder.append("name:" + name + "\n");

		stringBuilder.append("age:" + age);

		return stringBuilder.toString();

	}

	

}

下面让我们使用setter注入为Student学生赋予一些基本信息,下面的XML展示了Bean 的配置:


<bean id = "yoona" class = "com.sjf.bean.Student">

	<property name="name"  value = "yoona"/>

	<property name="age" value = "24" />	

</bean>

一旦Student被实例化,Spring 就会调用<property> 元素所指定属性的setter方法为该属性注入值。在这段XML代码中,<property> 元素会指示Spring 调用setName() 方法将name属性的值设置为“yoona”,调用setAge()方法将age属性的值设为24。注意的是name="xxx"中的xxx必须跟setXXX()方法中XXX是一样的。<property>
元素并没有限制只能注入String 类型的值,value 属性同样可以指定数值型(int、float、java.lang.Double 等)以及boolen 型的值。

注意value 属性的使用,为它设置数字类型的值和设置String 类型的值并没有任何不同。Spring 将根据Bean 属性的类型自动判断value 值的正确类型。因为Bean的age 属性为int 类型,Spring 在调用setAge() 方法之前会自动将字符串“24”转换成int 型。

2. 引用其他Bean

在setter注入中引用其他Bean,跟构造器注入引用其他Bean基本一致,都要借助ref属性来实现。

我们来为Student设置一个学校School类:


public class School {

	

	private String name;

 

	public void setName(String name) {

		this.name = name;

	}

}

	private String name;

	private int age;

	private School school;

	

	

	public void setName(String name) {

		this.name = name;

	}

 

	public void setAge(int age) {

		this.age = age;

	}

 

	public void setSchool(School school) {

		this.school = school;

	}

使用之前要我们必须在Spring 中将它声明为一个Bean,同时为学校赋值一个名字西电:


<bean id = "xidian" class = "com.sjf.bean.School">

	<property name = "name" value = "西电"/>

</bean>

声明了school之后,那么现在就可以将它赋给Student了。使用setter 注入为school 属性设值:


	<bean id = "yoona" class = "com.sjf.bean.Student">

		<property name="name"  value = "yoona"/>

		<property name="age" value = "24" />	

		<property name="school" ref="xidian"></property>

	</bean>

	

	<bean id = "xidian" class = "com.sjf.bean.School">

		<property name = "name" value = "西电"/>

	</bean>

3. 注入内部Bean

我们已经看到yoona该学生有了考进西电大学。不仅yoona可以考上西电大学,其他学生也可以通过自己的努力考上该大学。所以说不同Student(学生)可以共享一个School(学校)。事实上,在应用中与其他Bean
共享Bean是非常普遍的。


<bean id = "yoona" class = "com.sjf.bean.Student">

	<property name="name"  value = "yoona"/>

	<property name="age" value = "24" />	

	<property name="school" ref="xidian"></property>

</bean>

 

<bean id = "xiaosi" class = "com.sjf.bean.Student">

	<property name="name"  value = "xiaosi"/>

	<property name="age" value = "21" />	

	<property name="school" ref="xidian"></property>

</bean>

	

<bean id = "xidian" class = "com.sjf.bean.School">

	<property name = "name" value = "西电"/>

</bean>

但是当我们说个人兴趣的时候,就不能与其他人共享了,每一个人都有自己的兴趣喜好,我们将使用一种很好用的Spring 技术:内部Bean(inner bean)。内部Bean 是定义在其他Bean 内部的Bean。


package com.sjf.bean;

 

public class Hobby {

	

	private String desc;

 

	public void setDesc(String desc) {

		this.desc = desc;

	}

 

	@Override

	public String toString() {

		return desc;

	}

}

package com.sjf.bean;

 

/**

 * 学生实体类

 * @author sjf0115

 *

 */

public class Student {

	

	private String name;

	private int age;

	private Hobby hobby;

	

	

	public void setName(String name) {

		this.name = name;

	}

 

	public void setAge(int age) {

		this.age = age;

	}

	

	public void setHobby(Hobby hobby) {

		this.hobby = hobby;

	}

 

	@Override

	public String toString() {

		StringBuilder stringBuilder = new StringBuilder();

		stringBuilder.append("个人详细信息如下:" + "\n");

		stringBuilder.append("name:" + name + "\n");

		stringBuilder.append("age:" + age + "\n");

		stringBuilder.append("hobby:" + hobby.toString());

		return stringBuilder.toString();

	}

	

}

进行如下配置,我们把Hobby声明为内部Bean:


	<bean id = "yoona" class = "com.sjf.bean.Student">

		<property name="name"  value = "xiaosi"/>

		<property name="age" value = "21" />	

		<property name="hobby">

			<bean class = "com.sjf.bean.Hobby">

				<property name="desc" value = "喜欢踢足球,打羽毛球"/>

			</bean>

		</property>

	</bean>

正如你所见到的,内部Bean 是通过直接声明一个<bean> 元素作为<property>元素的子节点而定义的。内部Bean 并不仅限于setter 注入,我们还可以把内部Bean 装配到构造方法的入参中。

注意到内部Bean 没有ID 属性。虽然为内部Bean 配置一个ID 属性是完全合法的,但是并没有太大必要,因为我们永远不会通过名字来引用内部Bean。这也突出了使用内部Bean 的最大缺点:它们不能被复用。内部Bean 仅适用于一次注入,而且也不能被其他Bean 所引用。

参考:《Spring实战》

时间: 2024-08-02 15:10:27

[Spring实战系列](8)Spring注入方式之setter注入的相关文章

Spring基础系列6 -- Spring表达式语言(Spring EL)

Spring基础系列6 -- Spring表达式语言(Spring EL) 转载:http://www.cnblogs.com/leiOOlei/p/3543222.html 本篇讲述了Spring Expression Language —— 即Spring3中功能丰富强大的表达式语言,简称SpEL.SpEL是类似于OGNL和JSF EL的表达式语言,能够在运行时构建复杂表达式,存取对象属性.对象方法调用等.所有的SpEL都支持XML和Annotation两种方式,格式:#{ SpEL exp

Spring Data 系列(三) Spring+JPA(spring-data-commons)

本章是Spring Data系列的第三篇.系列文章,重点不是讲解JPA语法,所以跑开了JPA的很多语法等,重点放在环境搭建,通过对比方式,快速体会Spring 对JPA的强大功能. 准备代码过程中,保持了每个例子的独立性,和简单性,准备的源码包,下载即可使用.如果,对JPA语法想深入研究的话,直接下载在此基础上进行测试. 前言 Spring Data 系列(一) 入门:简单介绍了原生态的SQL使用,以及JdbcTemplate的使用,在这里写SQL的活还需要自己准备. Spring Data 系

Spring基础系列12 -- Spring AOP AspectJ

Spring基础系列12 -- Spring AOP AspectJ 转载:http://www.cnblogs.com/leiOOlei/p/3613352.html 本文讲述使用AspectJ框架实现Spring AOP. 再重复一下Spring AOP中的三个概念, Advice:向程序内部注入的代码. Pointcut:注入Advice的位置,切入点,一般为某方法. Advisor:Advice和Pointcut的结合单元,以便将Advice和Pointcut分开实现灵活配置. Aspe

Spring基础系列8 -- Spring自动装配bean

Spring基础系列8 -- Spring自动装配bean 转载:http://www.cnblogs.com/leiOOlei/p/3548290.html 1.      Auto-Wiring ‘no’ 2.      Auto-Wiring ‘byName’ 3.      Auto-Wiring ‘byType 4.      Auto-Wiring ‘constructor’ 5.      Auto-Wiring ‘autodetect’ Spring Auto-Wiring Be

Spring基础系列10 -- Spring AOP-----------Pointcut, Advisor

Spring基础系列10 -- Spring AOP-----------Pointcut, Advisor 转载:http://www.cnblogs.com/leiOOlei/p/3557643.html 上一篇的Spring AOP Advice例子中,Class(CustomerService)中的全部method都被自动的拦截了.但是大多情况下,你只需要一个方法去拦截一两个method.这样就引入了Pointcut(切入点)的概念,它允许你根据method的名字去拦截指定的method

Spring基础系列9 -- Spring AOP

Spring基础系列9 -- Spring AOP 转载:http://www.cnblogs.com/leiOOlei/p/3556054.html Spring AOP即Aspect-oriented programming,面向切面编程,是作为面向对象编程的一种补充,专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题.简单地说,就是一个拦截器(interceptor)拦截一些处理过程.例如,当一个method被执行,Spring AOP能够劫持正在运行的method,在met

[Spring实战系列](11)SpEL使用表达式装配

到目前为止,我们为Bean 的属性和构造器参数装配的所有东西都是在Spring 的XML 配置文件中静态定义的. <bean id = "yoona" class = "com.sjf.bean.Student"> <property name="name" value = "yoona"/> <property name="hobby" value = "踢足球,打

[Spring实战系列](15)使用Spring基于Java的配置

并不是所有的开发人员都喜欢使用XML,所以Spring3.0 为这些人准备了一些特别的东西.可以几乎不使用XML而使用纯粹的Java代码来配置Spring应用.并且基于Java的配置拥有一些XML配置所不具有的技巧. 1. 创建基于Java的配置 即使Spring的Java配置可以让我们不使用XML就可以编写大多数的Spring配置,但是我们仍然需要极少量的XML来启用Java配置. <?xml version="1.0" encoding="UTF-8"?&

[Spring实战系列](18)注解切面

使用注解来创建切面是AspectJ 5所引入的关键特性.在AspectJ 5之前,编写AspectJ切面需要学习一种Java语言的扩展,但是AspectJ面向注解的模型可以非常简单的通过少量注解把任意类转变为切面. 回顾一下Audience类,没有任何地方让它成为一个切面,我们不得不使用XML声明通知和切点. 我们通过@AspectJ注解,我们再看看Audience类,不需要任何额外的类或Bean声明就能将它转换为一个切面. package com.sjf.bean; /** * 歌手实体类 *