4.1 Spring beans的创建和配置(XML方式)

来源:互联网 发布:淘宝魔术贴 编辑:程序博客网 时间:2024/05/16 05:17

准备

//--Classes.javapackage com.erick.d1.hello;public class Classes {    private String name;    private int number;    public Classes() { }    public Classes(String name, int number) {        super();        this.name = name;        this.number = number;    }    @Override    public String toString() {        return "Classes [name=" + name + ", number=" + number + "]";    }    //getter and setter    //...}//--Student.java    package com.erick.d1.hello;public class Student {    private int age;    private String name;    //爱好    private List<String> hobby;    private Classes classes;    //getter and setter    //...}

1. 创建bean

spring支持使用 构造器、静态工厂、实例工厂 三种方式来创建bean

构造器创建bean

构造器创建bean是比较常见的,如果不采用构造注入,Spring会调用bean的午餐构造器来创建实例,
所以该Bean必须提供无参的构造器,使用这种方式配置时,class属性是必须的。

下面的配置(classes)使用了构造器创建,并且采用了构造注入方式

<!-- Beans.xml --><bean id="student" class="com.erick.d1.hello.Student">    <property name="name" value="tom" />    <property name="age" value="12" />    <property name="classes" ref="classes"/></bean><bean id="classes" class="com.erick.d1.hello.Classes">    <!-- 构造器注入 -->    <constructor-arg type = "String" name="name">        <value>正音班1</value>    </constructor-arg>    <constructor-arg name="number">        <value>20</value>    </constructor-arg></bean>

静态/实例工厂方法创建bean

后面会单独介绍使用工厂方法创建Bean

2. 配置Bean

使用内部bean

<bean id="student" class="com.erick.d1.hello.Student">    <property name="name" value="tom" />    <property name="age" value="12" />    <property name="classes">        <!-- 内部bean不能被其他bean引用 -->        <bean class="com.erick.d1.hello.Classes">            <property name="name" value="08级一班"/>            <property name="number" value="31" />        </bean>    </property></bean>

级联属性配置

<bean id="student" class="com.erick.d1.hello.Student">    <property name="name" value="tom" />    <property name="age" value="12" />    <!-- 必须先有一个班级对象才能级联赋值,否则报错 -->    <property name="classes" ref="classes"/>    <property name="classes.name" value = "08级一班" />    <property name="classes.number" value="31" /></bean>

配置集合属性

<!-- List集合 --><property name="hobby">    <list>        <value>网球</value>        <value>网游</value>    </list></property><!-- Map集合 --><property name="hobby">    <map>        <entry key="" value="" />        <entry key="" value="" />    </map></property><!-- propertie 配置 --><bean id = "dataSource" class="">    <property name="properties">        <props>            <prop key="user">root</prop>            <prop key="password">123</prop>        </props>    </property></bean>

集合配置时需要在<property>元素内。若想配置公用的需要添加util命名空间

<beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"       xmlns:util="http://www.springframework.org/schema/util"       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="student" class="com.erick.d1.hello.Student">    <property name="name" value="tom" />    <property name="age" value="12" />    <property name="hobby" ref="hobby" /></bean><util:list id="hobby">    <value>网球</value>    <value>网游</value></util:list>

自动装配

使用autowire属性进行自动装配,自动装配有三种方式:

  1. byName 通过属性名装配,属性名必须完全匹配才能注入。
  2. byType 通过类型装配,注入的类型若容器中有两个bean则注入失败。
  3. 构造器注入,比较复杂,不推荐使用。
<bean id="student" class="com.erick.d1.hello.Student" autowire="byType">    <property name="name" value="tom" />    <property name="age" value="12" /></bean><bean id="classes" class="com.erick.d1.hello.Classes">    <constructor-arg type="String" name="name">        <value>正音班1</value>    </constructor-arg>    <constructor-arg name="number">        <value>20</value>    </constructor-arg></bean>

bean配置继承

<bean id="studentAbs" abstract="true" class="com.erick.d1.hello.Student">    <property name="name" value="cat"/>    <property name="age" value="99"/></bean><bean id="student"  autowire="byType" parent="studentAbs">    <property name="age" value="12" /></bean>
  • 继承的是配置!类似模板,而非真正的父子关系。
  • 子bean可以覆盖从父bean中继承的配置
  • 父bean可以作为配置模板,也可以作为Bean实例。abstract属性设置为true,这样spring容器不会实例化这个bean。
  • 可以继承的配置包括bean的属性配置,但不是所有的属性都会被继承,比如autowire abstract等。
  • 当父bean属性配置为abstract=trueclass属性可以不指定,让子bean指定。

依赖bean配置

<bean id="student" class="com.erick.d1.hello.Student" depends-on="classes">    <property name="name" value="tom" />    <property name="age" value="12" /></bean>

若bean A 依赖于 bean B ,向容器请求bean A时,容器会先创建bean A,发现需要bean B注入,再创建bean B,并将其注入,然后将bean A返回。若指定depends-on则先创建bean B后创建bean A。

  • Spring允许用户通过depends-on属性设定bean的前置依赖的bean,前置依赖的bean会在本bean实例化之前创建。
  • 若前置依赖于多个bean,则可以通过逗号、空格的方式指定多个bean。

bean的别名

由于XML规范规定了id属性必须由字母和数字组成,且只能以字母开头,但在某些特殊情况下,例如与struts1整合时,必须为某些bean指定特殊标识名,测试就必须为其指定别名。

定义别名两种方式:

  • 设置<bean/>的属性name,若需要指定多个别名则可以在name中使用 逗号、冒号或者空格来分隔。通过任何一个别名都可以访问该bean实例。
  • 通过<alias/>元素为已有的bean指定别名。
<!-- 为person bean指定三个别名 --><bean id="person" class="..." name="#abc,@123,abc*"/><!-- 为已有的person bean指指定别名 --><alias name="person" alias="jack"/><alias name="person" alias="jackee"/>

bean的作用域

使用scop属性来配置bean的作用域。

  • singleton:单例的,整个容器的生命周期内只创建一次该bean。默认情况是单例的。单例情况默认是非懒加载,即容器启动时创建该bean。可以指定lazy-init=true改为懒加载。

  • prototype:原型的,每次用到该bean时,容器都会创建一个新的bean。该模式加载模式为懒加载,并且修改lazy-init=false不会起任何作用。

  • request:对于一次http请求,request作用域的bean将只生成一个实例。这意味着在同一次http请求内,每次请求该bean,得到的总是同一个实例。只有在Web应用中使用Spring时该作用域才真正有效。

  • session:对于一次http会话,session作用域的bean只生成一个实例,只有在Web应用中使用Spring时该作用域才真正有效。

  • global session:每个全局的http session 对应一个bean实例,在典型的情况下,仅在使用portlet context的时候有效。只有在Web应用中使用Spring时该作用域才真正有效。

默认情况为singleton.

为使request 和 session 作用域生效,必须将http请求对象绑定到为该请求提供服务的线程上,这使具有request 或 session作用域的bean实例能够在后面的调用链中被访问到。需要在web.xml中增加下面Listener配置,该Listener负责使request作用域生效。

<listener>    <listener-class>        org.springframework.web.context.request.RequestContextListener    </listener-class></listener>

若web应用直接使用spring MVC作为MVC框架,即用SpringDispatcherServletDispatcherPortlet 来拦截用户请求,则无需这些额外配置,因为SpringDispatcherServletDispatcherPortlet已经处理了所有和请求有关的状态处理。

0 0
原创粉丝点击