《Spring实战》第二章读书笔记

5 篇文章 0 订阅

装配Bean

定义表演者(Performer)接口,含有一个表演(Perform)方法:

package com.springinaction.springidol;

public interface Performer{
	void perform() throws PerformanceException;
}

定义一个具体的表演者(杂技师Juggler):

package com.springinaction.springidol;

public class Juggler implements Performer{
	private in beanBags = 3;

	public Juggler(){
	}
	
	//抛豆袋子的数量,可通过构造器传入,若不传则为默认值
	public Juggler(int beanBags){
		this.beanBags = beanBags;
	}

	//表演抛豆袋子
	public void perform() throws PerformanceException{
		System.out.println("Juggling" + beanBags + "BEANBAGS");
	}

}
在配置文件中定义该表演者:
<!-- 该表演者名为duke,职业为杂技师(Juggler) -->
<bean id="duke" class="com.springinaction.springidol.Juggler" />

通过构造器注入(豆子的数量):

<bean id="duke" class="com.springinaction.springidol.Juggler">
	<constuctor-arg value="15" />
</bean>

但是duke不只是杂技师,他还是一位会朗诵诗歌的杂技师,所以需要定义一个新的继承自Juggler的PoeticJuggler类来全面展现duke的才能:

public class PoeticJuggler extends Juggler{
	private Poem poem;
	
	public PoeticJuggler(Poem poem){
		sugar(beansBags);
		this.poem = poem;
	}
	
	//定义Poem接口
	public PoeticJuggler(int beanBags.Poem poem){
		super(beanBags);
		this.poem = poem;
	}

	public void perform() throws PerformanceException{
		super.perform();
		System.out.println("While reciting...");
		poem.recite();
	}
}

定义朗诵诗歌接口:

package com.springinaction.springidol;

public interface Poem{
	void recite();
}

表演朗诵诗歌的类:

package com.springinaction.springidol;

public class Sonnet29 implements Poem{
	private static String[] LINES = {
		"诗句第一行",
		"诗句第二行",
		"诗句第三行",
		"诗句第四行",
		"诗句第五行",
		"诗句第六行",
		"诗句第七行",
		"诗句第八行",
		"诗句第九行"};
	
	public Sonnet29(){
	}

	public void recite(){
		for(int i = 0;i<LINES.length;i++){
			System.out.println(LINES[i]);
		}
	}
	
}

声明表演诗歌的类:

<bean id="sonnet29" class="com.springinaction.springidol.sonnet29" />

将poem赋予Duke(调用PoeticJuggler有两个参数的构造器):

<bean id="poeticDuke" class="com.springinaction.springidol.PoeticJuggler">
	<constructor-arg value="15" />
	<constructor-arg ref="sonnet29" />
</bean>

<constructor-arg ref="sonnet29" />将id为sonnet29的bean当作引用传给PoeticJuggler的构造器。

通过工厂方法创建Bean

单例(舞台)类:
package com.springinaction.springidol;

public class Stage{
	//只有一个私有构造器,无法通过new创建Stage实例
	pvivate Stage(){
	}

	//延迟加载实例
	private static class StageSingletonHolder{
		static Stage instance = new Stage();
	}

	//返时实例
	public static Stage getInstance(){
		return StageSingletonHolder.instance;
	}
}

在Spring中,factory-method属性允许调用一个指定的静态方法,从而代替构造方法来创建一个类的实例,将没有公开构造方法的类配置为一个Bean:

<bean id="theStage" class="com.springinaction.springidol.Stage" factory-method="getInstance" />

2.1.4 Bean的作用域

当在Spring中配置<bean>元素时,可以为Bean声明一个作用域。为了让Spring在每次请求时都为Bean产生一个新的实例,只需要配置Bean的scope属性为prototype即可。例如,把演出门票声明为Spring bean:

<bean id="ticket" class="com.springinaction.springidol.Ticket" scope="prototype" />

以保证每个观看演出的人手里的票绝对唯一。

作用域表:

作用域                                                                     定义
singleton 在每一个Spring容器中,一个Bean定义只有一个对象实例(默认)
prototype允许Bean的定义可以被实例化任意次(每次调用都创建一个实例)
request在一次HTTP请求中,每个Bean定义对应一个实例。该作用域仅在基于web的Spring上下文(例如Spring MVC中才有效)
session在一个HTTP Session中,每个Bean定义对应一个实例。该作用域仅在基于web的Spring上下文(例如Spring MVC中才有效)
global-session

在一个全局HTTP Session中,每个Bean定义对应一个实例。该作用域尽在Portlet上下文中才有效。

2.1.5 初始化和销毁Bean

表演大厅(Auditorium)类:

public class Auditorium{

	//表演开始时开灯
	public void turnOnLights(){
		...
	}
	
	//表演结束时关灯
	public void turnOffLights(){
	}
}

在配置文件中定义Bean时,使用init-method方法和destroy-method方法指定初始化bean和销毁bean时要调用的方法:

<bean id="auditorium" 
	class="com.springinaction.springidol.Auditorium"
	init-method="turnOnLights"
	destroy-method="turnOffLights" />

2.2 注入Bean属性

package com.springinaction.springidol;

public class Instrumentalist implements Performer{
	public Instrumentalist (){
	}

	public void perform() throws PerformancException{
		System.out.println("Playing" + song + " : ");
		instrument.play();
	}

	//定义歌曲名字
	private String song;
	
	//注入歌曲
	public void setSong(String song){
		this.song = song;
	}

	public String getSong(){
		return song;
	}

	public String screamSong(){
		return song;
	}

	private Instrument instrument;

	//注入乐器
	public void setInstrument(Instrument instrument){
		this.instrument = instrument;
	}
}
乐器接口:
package com.springinaction.springidol;


public interface instrument{
	public void play();
}

实现了乐器接口的saxophone乐器类:

package com.springinaction.springidol;

public class Saxophone implements Instrument{
	public Saxophone{
	}

	public void play(){
		System.out.println("TOOT TOOT TOOT");
	}
}

在配置中声明Saxophone对应的Bean:

<bean id="saxophone" class="com.springinaction.springidol.Saxophone" />

配置(将Jinggle Bells这首歌和Saxophone乐器的引用注入到名为kenny的音乐演奏家instrument类对应的属性中):

<bean id="kenny" class=com.springinaction.springidol.Instrumentalist">
	<property name ="song" value="Jingle Bells" />
	<property name="instrument" ref="saxophone"
</bean>

注入内部Bean:

<bean id="kenny" class=com.springinaction.springidol.Instrumentalist">
	<property name ="song" value="Jingle Bells" />
	<property name="instrument">
		<bean class="org.springinaction.springidol.Saxophone" />
	</property>
</bean>

也可以将内部Bean装配到构造方法的入参中:

<bean id="duke" class=com.springinaction.springidol.PoeticJuggler">
	<constructor-arg value="15" />
	<constructor-arg>
		<bean class="com.springinaction.springidol.Sonnet29" />
	</constructor-arg>
</bean>
内部Bean没有ID属性,虽然可以但没有必要,因为永远不会通过名字来引用内部Bean。内部Bean不能被复用,仅用于一次注入,而且也不能被其他Bean引用。

装配集合属性:

集合元素                                    用途
<list>装配list类型的值,允许重复
<set>装配set类型的值,不允许重复
<map>装配map类型的值,名称和值可以是任意类型
<props>装配properties类型的值,名称和值必须都是String型
package com.springinaction.springidol;

import java.util.Collection;

public class OneManBand implements Performer{
	public OneManBand(){
	}

	public void perform() throws PerformanceException{
		for (Instrument instrument : instruments){
			instrument.play();
		}
	}

	private Collection<Instrument> instruments;

	public void setInstruments(Collection<Instrument> instruments){
		//注入instrument集合
		this.instruments = instruments;
	}
}
装配List






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值