Spring中的bean
1.定义和别名
定义一个bean可以为其制定如下属性
default-lazy-init:延迟初始化(默认false,即立即初始化)
default-merge:从父类合并继承属性值
default-autowire:可以按byName,byType等方式完成自动装配
default-autowire-candidates:自动装配时候排除此bean
bean可以使用id定义唯一名字,还可以使用name定义别名,例如<bean id="person" name="#abc,@123" />
还可以使用<alias>标签定义别名,例如<alias name="person" alias="jack" />
2.bean作用域
使用scope属性可以指定bean作用域,例如<bean id="person" class="spi.Person" scope="singleton" />
默认作用域为 singleton,即单例,可重复使用,也可以指定为prototype,每次使用bean时Spring都重新new出一个实例。
此外还有三种web中的作用域,分别是request (每个HTTP请求都创建一个新bean),session(每个HTTP session使用同一个bean),global session全局的HTTP session对应一个bean实例
3.设置普通属性值
使用value属性或者<value>标签可以为bean设置普通属性值,Spring自动判断数据类型,例如
1 <bean id="person" class="spi.Person"> 2 <!-- 使用value属性设置普通属性值,这里是int类型--> 3 <property name="personId" value="1"> 4 <!--使用嵌套 value 标签的方式设置普通属性值,这里是double类型 --> 5 <property name="high"> 6 <value>1.76</value> 7 </property> 8 </bean>
4.自动装配
如果指定了bena的autowire属性可以进行自动装配
如果在<beans>标签添加default-autowire属性,将对所有<bean>起作用,如果在<bean>标签添加autowire(注意这里不是default-autowire),则只对单个bean起作用。
autowire支持no, byName, byTye, constructor, autoetect值。
byName: 根据bean中setter方法的名称,去容器中查找对应的bean,例如Person类中有一个setter方法叫做 setSchool(), 那么就在容器中查找<bean id="school" ../>,找得到就进行注入。
1 class Person { 2 School school; 3 public setSchool(School school) { 4 this.school = school; 5 } 6 } 7 8 class School { 9 String schoolName; 10 }
1 <bean id="person" class="Person" autowire="byName" /> 2 <bean id="school" class="School" />
byType: 根据bean中setter方法的参数类型查找,还是上面的例子,Person的setSchool()方法需要一个School类型的参数,Spring就会在容器中查找类型为School的bean。配置如下。
1 <bean id="person" class="Person" autowire="byType" /> 2 <bean id="school" class="School" />
类似的,constructor会根据构造函数的参数类型,在容器中查找对应的bean
注意的是,对于byType和constructor两种自动装配, 在容器中查找对应的bean不能超过一个,否则Spring无法决定装配哪一个。
例如上面的例子,假如有第三个bean继承自School,叫做HighSchool,容器中配置了<bean id="highSchool" class="HighSchool" />,那么Spring就不知道要装配哪一个给Person了。
autodetect: 由容器自行决定自动装配策略。如果找到默认构造函数,则使用byTpye策略。
自动装配可以减少配置代码量,但是会增加不透明性,对于大型项目不推荐自动装配。
5.注入嵌套bean
<bean>中嵌套一个bean,嵌套的bean只能用来注入,其本质与ref注入是一样的,区别是嵌套的bean不能被容器访问,因此也不再需要id属性,例如下面,
1 <bean id="person" class="Person"> 2 <property name="school"> 3 <bean class="School"> 4 </property> 5 </bean>
6.注入集合值
如果类中定义了list, set, map, properties, array等集合属性,在bean中要为集合属性注入值时,可以在<property>标签下面嵌套<list>, <set> , <map> , <props> 等标签为其注入值。
下面是一个为集合属性注入值的例子,假如有如下类(bean),
1 public class CollectionBean { 2 private List<String> schools; 3 private Map scores; 4 private Map<String, Axe> phaseAxes; 5 private Properties health; 6 private Set axes; 7 private String[] books; 8 ... 9 }
则对应的XML配置如下,
1 <bean id="collectionBean" class="CollectionBean"> 2 <!-- 为schools注入list集合类型的值 --> 3 <property name="schools"> 4 <list> 5 <value>小学</value> 6 <value>中学</value> 7 </list> 8 </property> 9 10 <!-- 为scores注入map集合类型的值 --> 11 <property name="scores"> 12 <map> 13 <entry key="语文" value="89" /> 14 <entry key="数学" value="88" /> 15 </map> 16 </property> 17 18 <!-- 为phaseAxe注入map集合类型的值,key为String类型,value为Axe类型 ,复合类型的值使用value-ref进行引用--> 19 <property name="phaseAxe"> 20 <map> 21 <entry key="原始社会" value-ref="stoneAxe" /> 22 <entry key="农业社会" value-ref="steelAxe" /> 23 </map> 24 </property> 25 26 <!-- 为health注入properties集合类型的值 --> 27 <property name="health"> 28 <props> 29 <prop key="血压">正常</prop> 30 <prop key="身高">175</prop> 31 </props> 32 </property> 33 34 <!-- 为axes注入set集合类型的值 --> 35 <property name="axes"> 36 <set> 37 <!-- 每个value,ref,bean..都可以配置一个set元素 --> 38 <value>普通字符串</value> 39 <ref bean="stoneAxe" /> 40 <bean id="steelAxe" class="spi.SteelAxe" /> 41 <!-- 为set集合配置一个list集合作为一个元素 --> 42 <list> 43 <value>20</value> 44 <!-- 再次为list集合配置一个set集合作为元素 --> 45 <set> 46 <value type="int">30</value> 47 </set> 48 </list> 49 </set> 50 </property> 51 52 <!-- 为books注入一个数组值 --> 53 <property name="books"> 54 <!-- 数组和list使用一样的注入方法 --> 55 <list> 56 <value>语文</value> 57 <value>英语</value> 58 </list> 59 </property> 60 </bean>
7.注入组合属性
假如有一个类Person中有一个属性为School school,这里的school也是一个类对象,也包含属性,而相对于Person的对象来说,school对象的属性就是组合属性。
1 class Person { 2 School school = new School(); 3 } 4 5 class School { 6 String schoolName; 7 }
如果我们现在需要为组合数学注入值,那么在XML中的配置如下,
1 <bean id="person" class="Person"> 2 <property name="person.schoolName" value="北京大学" /> 3 </bean>
为组合属性注入值要注意两点,
一是组合属性对应的对象不能为空,例如上面的school对象,必须初始化。
二是组合属性除了最后一段可以为null,其他都不能,否则会出现空指针异常。例如假如有foo.bar.name,则name可以为null,bar和foo都不可以为null