这一节主要讲解spring注入list或则set类型的属性
本blog举的例子是:不同的厨师使用不同个烤炉制作出不同的蛋糕。
(1)domain
蛋糕类:
package spring.ch1.topic11;
/**
* Created by louyuting on 17/1/20.
* 注入属性,记得属性必须要写setter方法 不然就会抛出异常,注入失败.
* 蛋糕类
*/
public class Cake {
private static int index = 0;
private final int id = index++;
private String name = "";
private double size = 0;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSize() {
return size;
}
public void setSize(double size) {
this.size = size;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "create the cake,its id:" + id + ", size:" + size + " inch ,name:" + name;
}
}
厨师类:
package spring.ch1.topic11;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
/**
* Created by louyuting on 17/1/20.
* 厨师类
*/
public class Chief {
private static int index = 0;
private List<Cake> cakes = null;
private final int id = index++;
private String name = "";
private HashSet<Oven> ovens = null;
public List<Cake> getCakes() {
return cakes;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public HashSet<Oven> getOvens() {
return ovens;
}
public void setCakes(List<Cake> cakes) {
this.cakes = cakes;
}
public void setName(String name) {
this.name = name;
}
public void setOvens(HashSet<Oven> ovens) {
this.ovens = ovens;
}
public List<Cake> makeCakes() {
for (Iterator<Cake> iterator = cakes.iterator(); iterator.hasNext();) {
Cake cake = iterator.next();
System.out.println(name + ": " + cake);
}
return getCakes();
}
public void userOvens() {
for (Iterator<Oven> iterator = ovens.iterator(); iterator.hasNext();) {
Oven oven = iterator.next();
System.out.println("use " + oven);
}
}
}
厨师类这里需要解释一下:
(1)为了使用不同的烤炉,我们加入了ovens,由于实际情况当中只有大小烤炉各一个,所以我们这里只是使用set,而不是使用list
(2)为了能够做出不同的蛋糕,我们使用一个list来放置不同的蛋糕,而这里允许重复,因此这里使用list
(3)为了输出方便,我在userOvens和makeCakes里面直接输出数据
烤炉类:
package spring.ch1.topic11;
/**
* Created by louyuting on 17/1/21.
* 烤炉类
*/
public class Oven {
private String name = "";
@Override
public String toString() {
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(2)配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--scope默认是单例的-->
<bean id="blueberryCheeseCake"
class="spring.ch1.topic11.Cake"
scope="prototype">
<property name="name" value="blueberry cheese cake"/>
<property name="size" value="5.0"/>
</bean>
<bean id="chocolateCheeseCake"
class="spring.ch1.topic11.Cake"
scope="prototype">
<property name="name" value="chocolate cheese cake"/>
<property name="size" value="6.0"/>
</bean>
<bean id="bananaAatmelMousseCake"
class="spring.ch1.topic11.Cake"
p:name="banana oatmel mousse cake" p:size="7"
scope="prototype">
</bean>
<bean id="vanillaEclair"
class="spring.ch1.topic11.Cake"
p:name="vanilla eclair" p:size="8"
scope="prototype">
</bean>
<bean id="ligueurPerfumedTripletCake"
class="spring.ch1.topic11.Cake"
p:name="ligueur perfumed triplet cake" p:size="5.5"
scope="prototype">
</bean>
<bean id="bigOven"
class="spring.ch1.topic11.Oven"
p:name="bigOven"
scope="singleton">
</bean>
<bean id="smallOven"
class="spring.ch1.topic11.Oven"
p:name="smallOven"
scope="singleton">
</bean>
<bean id="jack" class="spring.ch1.topic11.Chief" p:name="jack">
<property name="ovens">
<set>
<ref bean="bigOven"/>
<ref bean="bigOven"/>
<ref bean="smallOven"/>
</set>
</property>
<property name="cakes">
<list>
<ref bean="blueberryCheeseCake" />
<ref bean="chocolateCheeseCake" />
<ref bean="bananaAatmelMousseCake" />
<ref bean="vanillaEclair" />
</list>
</property>
</bean>
<bean id="rose" class="spring.ch1.topic11.Chief" p:name="rose">
<property name="ovens">
<set>
<ref bean="smallOven"/>
</set>
</property>
<property name="cakes">
<list>
<ref bean="vanillaEclair" />
<ref bean="ligueurPerfumedTripletCake" />
<ref bean="chocolateCheeseCake" />
</list>
</property>
</bean>
</beans>
需要解释一下的地方:
(1)我们利用一个蛋糕类,通过名称等属性的变化,来创建不同类别的蛋糕对象
(2)我们利用一个烤炉类,通过名称等属性的变化,来创建不同类别的烤炉对象
(3)我们利用一个厨师类,通过名称等属性的变化,来创建不同类别的厨师对象
注:上面这几点比较能够体现代码的复用
(4)每个蛋糕Bean都需要使用prototype的作用域,这样才能够每次创建的都是不同的蛋糕对象,不然后面get蛋糕的时候就会出现两个相同id的蛋糕,这个明显是不符合实际情况的。
(5)但是烤炉的情况不一样,由于对于面包铺来说,烤炉的数量是一定的,不能够出现多个烤炉,因此他们必须使用默认的单例模式
(6)配置厨师里面的烤炉属性时,我们使用了set,这样即便像上面配置多了,也不会重复出现,因为这个collection具备了set的特性;而配置蛋糕属性的时候我们使用list,由于每一个蛋糕都不一样,因此使用list比较合适
(7)list和set除了上面的能够放入Bean之外,还可以放入value,这个时候只需要使用标签即可,不是使用,但是由于注入值比较少,因此不作详细说明。
(3)测试类:
package spring.ch1.topic11;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Created by louyuting on 17/1/20.
* 注入List和Set
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/spring/ch1/topic11/ApplicationContext-test.xml"})
public class ChiefTest {
@Autowired
private ApplicationContext applicationContext;
@Test
public void testChief(){
Chief jack = (Chief)applicationContext.getBean("jack");
jack.userOvens();
jack.makeCakes();
Chief rose = (Chief)applicationContext.getBean("rose");
rose.userOvens();
rose.makeCakes();
}
}
从容器里面取出不同的厨师对象,然后厨师就开始使用烤炉制作蛋糕。
(4)输出结果:
/**
use bigOven
use smallOven
jack: create the cake,its id:0, size:5.0 inch ,name:blueberry cheese cake
jack: create the cake,its id:1, size:6.0 inch ,name:chocolate cheese cake
jack: create the cake,its id:2, size:7.0 inch ,name:banana oatmel mousse cake
jack: create the cake,its id:3, size:8.0 inch ,name:vanilla eclair
use smallOven
rose: create the cake,its id:4, size:8.0 inch ,name:vanilla eclair
rose: create the cake,its id:5, size:5.5 inch ,name:ligueur perfumed triplet cake
rose: create the cake,its id:6, size:6.0 inch ,name:chocolate cheese cake
*/
全部代码的github地址