系统学习Spring之Spring in action(三)
每日一叨:
今天加班,本来想多留点时间放在博客上的,计划永远敢不上变化快,所有只能在变化中尽自己最大的努力去做原本计划过的事,哪怕只记录了一个知识点,那也是一种积累,一般情况下,理性要大于感性,否则你的一个念头可以破坏整个计划.
文章导读:
1.InnerBean(内部bean)
2.用Spring的命名空间p去实现bean中properties标签的功能
3.装配Collection
4.装配null
知识点:
经常玩游戏的人应该知道什么叫专署这个概念吧,就算你不经常玩游戏,我想从字面也可以理解这个词.还是用我自己的语言解释下吧,
专署:最简单的解释就是指一件事物只属于另一件事物(想想一对一关系应该可以理解).通过下一个知识点,更形象的讲解专署.
1.InnerBean(内部bean)
回顾上一篇文章,我们可以通过properties标签中的ref属性注入一个对象类型,但是这个ref对象的bean是共享给Spring Container中的
其它所有bean.每个bean都可以注入这个bean.怎么样能让一个bean只专署于另外一个bean?Spring给我们提供了一个解决方案是使用InnerBean来解决
专署问题.请下如下事例:
Spring提供了两种InnerBean,一种是properties标签下的InnerBean,另一种是constructor-arg标签下的InnerBean.
1)Properties InnerBean
创建一个手机类:
public class Phone { //手机主人 private String master; //手机品牌 private String brand; //无参构造方法 public Phone() { } //有参构造方法 public Phone(String master, String brand) { this.master = master; this.brand = brand; } public String getMaster() { return master; } public void setMaster(String master) { this.master = master; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } }
然后创建一个手机的专署类,
public class LiuShuai { //LiuShuai的专署电话 private Phone phone; //无参构造方法 public LiuShuai() {} //有参构造方法 public LiuShuai(Phone phone) {
this.phone = phone; } public Phone getPhone() { return phone; } public void setPhone(Phone phone) { this.phone = phone; } public void find(){ System.out.println(this.phone.getMaster() + " 主人,您的专署 " + this.phone.getBrand() + " 手机在这呢."); } }
配置Spring configuration
<bean id="liushuai" class="com.ricky.zero.pojo.LiuShuai"> <property name="phone"> <bean class="com.ricky.zero.pojo.Phone"> <property name="master" value="刘帅"></property> <property name="brand" value="诺基亚"></property> </bean> </property> </bean>
把以前properties的ref属性和ref的bean先清除,然后写成上图格式,我想你们应该能看得懂,properties下bean替换了ref属性和ref的bean,记着InnerBean
没有id或者name属性.
配置完成后开始测试,
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml"); LiuShuai liushuai = (LiuShuai)ctx.getBean("liushuai"); liushuai.find();
测试运行后得到结果如下:
刘帅 主人,您的专署 诺基亚 手机在这呢.
得到这个结果后,说明成功的完成了properties的InnerBean的测试.由于InnerBean的生命周期只是在id="liushuai"的bean中,所有其它的bean无法共享注入.
2)constructor-arg InnerBean
根据上面的准备,只需要修改Spring Configuration的配置文件就可以实现constructor-arg的innerBean
<bean id="liushuai" class="com.ricky.zero.pojo.LiuShuai"> <constructor-arg> <bean class="com.ricky.zero.pojo.Phone"> <property name="master" value="刘帅"></property> <property name="brand" value="诺基亚"></property> </bean> </constructor-arg> </bean>
修改完成后,直接运行测试.
测试结果:
刘帅 主人,您的专署 诺基亚 手机在这呢.
测试成功,Inner Bean到这里就结束了.
2.用Spring的命名空间p去实现bean中properties标签的功能
上一篇文章中描述如何使用Properties,但是每次使用properties总是要打一堆的尖括号,不方便.Spring给提供了一个使用命名空间p去简化properties
的实现.直接看事例.
注意,在使用命名空间p之前,要在beans标签中添加 xmlns:p="http://www.springframework.org/schema/p"
这是properties的用法
<bean id="war3" class="com.ricky.zero.pojo.War3"></bean> <bean id="dota" class="com.ricky.zero.pojo.Dota"> <property name="author" value="冰蛙"></property> <property name="war3" ref="war3"></property> </bean>
这是使用命名空间p后的代码
一定要记着要在beans标签中添加 xmlns:p="http://www.springframework.org/schema/p" 如果少加了这段话则会抛出
与元素类型 "bean" 相关联的属性 "p:author" 的前缀 "p" 未绑定
<bean id="war3" class="com.ricky.zero.pojo.War3"></bean> <bean id="dota" class="com.ricky.zero.pojo.Dota" p:author="冰蛙" p:war3-ref="war3" />
两次配置后运行的测试结果都是:
大家好,我们名字叫Dota,来自 冰蛙 之手
大家好,我的名字叫魔兽争霸,相信你们很多人都已经认识我了.
3.装配Collection
Spring提供了通过properties装配四种集合类型.四种集合类型分别是List、Set、Map、Props.
直接上事例:
首先建一个游戏接口,方便下面使用.
public interface Game { //获取游戏名称 public void getGameName(); }
建立实现接口的3个游戏类.
public class CYHX implements Game { //穿越火线 @Override public void getGameName() { // TODO Auto-generated method stub System.out.println("大家好,我的名字叫穿越火线."); } }
public class MSSJ implements Game { //魔兽世界 @Override public void getGameName() { // TODO Auto-generated method stub System.out.println("大家好,我的名字叫魔兽世界."); } }
public class YXLM implements Game { //英雄联盟 @Override public void getGameName() { // TODO Auto-generated method stub System.out.println("大家好,我的名字叫英雄联盟."); } }
建立一个集合类:
public class GameCollection { //游戏集合 private Collection<Game> games; public Collection<Game> getGames() { return games; } public void setGames(Collection<Game> games) { this.games = games; } public void launch(){ for(Game game:games){ game.getGameName(); } }
配置Spring container:
<bean id="mssj" class="com.ricky.zero.pojo.MSSJ"></bean> <bean id="cyhx" class="com.ricky.zero.pojo.CYHX"></bean> <bean id="yxlm" class="com.ricky.zero.pojo.YXLM"></bean> <bean id="gameCollection" class="com.ricky.zero.pojo.GameCollection"> <property name="games"> <list> <ref bean="mssj" /> <ref bean="cyhx" /> <ref bean="yxlm" /> <ref bean="yxlm" /> </list> </property> </bean>
前面3个bean应该很熟悉,最后一个bean中的properties实例化的不是在一个基本类型,或者是一个实现bean,而变成了一个集体类型.list标签表明该集合是list
类型.list集合中的元素通过ref标签取得已经存在的bean,在list集合中,存放的元素是可以重复的.
下面进行测试:
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml"); GameCollection gameCollection = (GameCollection)ctx.getBean("gameCollection"); gameCollection.launch();
测试结果:
大家好,我的名字叫魔兽世界.
大家好,我的名字叫穿越火线.
大家好,我的名字叫英雄联盟.
大家好,我的名字叫英雄联盟.
测试List集合注入成功.
Set集合与List集合用法一样,下面我们只需要把Spring Configuration中list标签替换成set标签即可.
<bean id="mssj" class="com.ricky.zero.pojo.MSSJ"></bean> <bean id="cyhx" class="com.ricky.zero.pojo.CYHX"></bean> <bean id="yxlm" class="com.ricky.zero.pojo.YXLM"></bean> <bean id="gameCollection" class="com.ricky.zero.pojo.GameCollection"> <property name="games"> <set> <ref bean="mssj" /> <ref bean="cyhx" /> <ref bean="yxlm" /> <ref bean="yxlm" /> </set> </property> </bean>
测试运行.运行结果如下:
大家好,我的名字叫魔兽世界.
大家好,我的名字叫穿越火线.
大家好,我的名字叫英雄联盟.
4个ref标签,为什么只出来了3个结果?
因为Set集合中的元素是不可以重复的,所有两个英雄联盟只能显示一个.
Map集合与Props集合:
修改游戏集合类:
public class GameCollection { //游戏集合 private Map<String,Game> games; public Map<String, Game> getGames() { return games; } public void setGames(Map<String, Game> games) { this.games = games; } public void launch(){ for(String key :games.keySet()){ Game game = games.get(key); game.getGameName(); } } }
修改Spring Configuration配置文件:
<bean id="mssj" class="com.ricky.zero.pojo.MSSJ"></bean> <bean id="cyhx" class="com.ricky.zero.pojo.CYHX"></bean> <bean id="yxlm" class="com.ricky.zero.pojo.YXLM"></bean> <bean id="gameCollection" class="com.ricky.zero.pojo.GameCollection"> <property name="games"> <map> <entry key="MSSJ" value-ref="mssj"/> <entry key="CYHX" value-ref="cyhx"/> <entry key="YXLM" value-ref="yxlm"/> </map> </property> </bean>
在Java中Map集合是用键值对来描述Map集合内的元素的,在上述配置充分的体现了Map的键值对元素模式.
运行测试,结果如下.
大家好,我的名字叫魔兽世界.
大家好,我的名字叫穿越火线.
大家好,我的名字叫英雄联盟.
Props与Map的不同之处就是Map的键和值的类型可以是任意类型,而Props的键和值必须是String类型.由于时间关系不在演示.
4.装配null
Spring中,可以注入基本类型和bean的实例类型到参数列表中,Spring也提供了直接向参数列表中注入null值.
注入方法如下:
<property name="test"><null/></property>
由于明天还要上班,最后几个事例没有测试~~实在抱歉了.
--------------------------------申明----------------------------
本文可以免费阅读以及转载,转载时请注明出处.
本人邮箱:Ricky_LS@163.com
Thank you for your corporation.