今天我来学习学习Spring中Bean。
在Spring中原来还有<beans.../>标签啊,它相当于<bean.../>标签的老爸,老爸可以有很多个儿子,但是老爸只有一个哦。
也就是说一个<beans.../>标签内可以有多个<bean...>标签,每个<bean.../>标签代表一个java实例。
定义<bean...>时,需要注意两个属性,一个是id,一个是class。
id是<bean.../>标签的唯一标示符,容器对其的访问、管理、注入都通过这个属性来完成,所以它也是唯一的。
class呢,是该bean的具体实现类,因为Spring要通过class来完成对bean的实例化,所以其必须是完整的类名,不能是接口哦!
还可以用name属性为其增加一个别名。
当Spring创建一个bean实例时,还为其指定了特定的作用域:
singleton:单例模式,使用singleton定义的bean只有一个实例。
prototype:原型模式,每次通过容器的getbean方法去调用prototype定义的bean时,都会创建一个实例。
request:每次http请求都会产生一个bean实例。
seesion:与request相似,每次http session请求时,都会产生一个bean实例。
global session:(这个不太懂啊)每个全局的http session对应一个bean实例。
不指定作用域时,默认为singleton模式。
举个例子:<bean id="test" class="..." scope="singleton"/>
session和request作用域的范围很相似,不同的是session指每次Http Session请求都会有效,而request则是每次Http请求都有效。
为此,我们需要有两种配置方式:采用Listener或者Filter配置。
当使用Servlet2.4以上规范的Web容器时,可在Web容器下的web.xml文件中增加如下配置,该Listerner负责为request作用域负责:
1 <web-app> 2 ... 3 <listener> 4 <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 5 </listener> 6 ... 7 </web-app>
当使用2.4以下规范的就不能用这个配置了,只能改为Filter配置:
1 <web-app> 2 ... 3 <filter> 4 <filter-name>requestContextFilter</filter-name> 5 <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> 6 <filter-mapping> 7 <filter-name>requestContextFilter</filter-name> 8 <url-pattern>/*</url-pattern> 9 </filter-mapping> 10 </filter> 11 ... 12 </web-app>
一旦配置上面二者之一,就可以在Spring配置文件中使用request和session作用域了。
如果需要为Bean属性值是容器中另一个bean实例,需要使用<ref...>元素,使用该元素会有两个属性:
bean:引用不在同一个XML文件中的另一个bean实例的id属性值。
local:引用在同一个XML文件中其他bean实例的id属性值。举一个例子:
1 <bean id="A" class="com.basic.test.A"/> 2 <bean id="B" class="com.basic.test.B"> 3 <property name="c"> 4 <!-- 引用容器中另一个bean--> 5 <ref local="A"/> 6 </property> 7 </bean>
它还有一种简洁的写法:
1 <bean id="A" class="com.basic.test.A"/> 2 <bean id="B" class="com.basic.test.B"> 3 <property name="c" ref="A"/> 4 </bean>
此处简洁了ref元素,将它并入了property的属性中,当然这么写也就不区分ref元素中的local和bean属性了。
此外,如果bean的属性值是个集合的话,则需要使用集合元素,<list.../>、<set.../>、<map.../>和<props.../>分别用来设置类型为List、Set、Map和Properties的集合属性值。
下面我们来改造一个之前写的com/sep/basic/service/impl/Lenovo类,将其中包含多个集合属性。
1 package com.sep.basic.service.impl; 2 3 import java.util.List; 4 import java.util.Map; 5 import java.util.Properties; 6 import java.util.Set; 7 8 import com.sep.basic.service.Computer; 9 import com.sep.basic.service.Key; 10 11 public class Lenovo implements Computer{ 12 //下面是集合属性 13 private List<String> size; 14 private Set price; 15 private Map<String , Key> key; 16 private Properties health; 17 //private Key key; 18 19 //各属性的setter方法 20 public void setSize(List<String> size) { 21 this.size = size; 22 } 23 24 25 public void setPrice(Set price) { 26 this.price = price; 27 } 28 29 30 public void setKey(Map<String, Key> key) { 31 this.key = key; 32 } 33 34 35 public void setHealth(Properties health) { 36 this.health = health; 37 } 38 39 @Override 40 public void useKey() { 41 System.out.println(size); 42 System.out.println(price); 43 System.out.println(key); 44 System.out.println(health); 45 } 46 47 }
下面来看一下我们的applicationContext.xml的配置代码:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:p="http://www.springframework.org/schema/p" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> 7 <!-- 将配置Lenovo实例 --> 8 <bean id="lenovo" class="com.sep.basic.service.impl.Lenovo"> 9 <property name="size"> 10 <!-- 为list属性配置属性值 --> 11 <list> 12 <!-- 为每个value、ref、bean配置一个List元素 --> 13 <value>17'</value> 14 <value>21'</value> 15 <value>30'</value> 16 </list> 17 </property> 18 <property name="key"> 19 <!-- 为Set设置属性值 --> 20 <set> 21 <!-- 为每个value、ref、bean配置一个Set元素 --> 22 <value>普通的字符串</value> 23 <bean class="com.sep.basic.service.impl.LogicTech"/> 24 <ref local="logicTech"/> 25 </set> 26 </property> 27 <property name="cpu"> 28 <!-- 为Map类型设置属性值 --> 29 <map> 30 <!-- 每个entry配置一个key-value对 --> 31 <entry key="cpu1" value="intel"/> 32 <entry key="cpu2" value="amd"/> 33 <entry key="cpu3" value="other"/> 34 </map> 35 </property> 36 <property name="keyType"> 37 <!-- 为Map类型设置属性值 --> 38 <map> 39 <!-- 每个entry配置一个key-value对 --> 40 <entry key="罗技键盘" value-ref="logicTech"/> 41 </map> 42 </property> 43 <property name="health"> 44 <!-- 为properties类型设置属性值 --> 45 <!-- 为每一个prop元素配置一个属性项,其中key指定属性名 --> 46 <props> 47 <prop key="温度">正常</prop> 48 <prop key="存取速度">正常</prop> 49 </props> 50 </property> 51 </bean> 52 <!-- 将配置LogicTech实例--> 53 <bean id="logicTech" class="com.sep.basic.service.impl.LogicTech"/> 54 55 </beans>
这样我们就成功地将所有集合属性赋值了。