spring IOC容器中装配Bean(XML)

Posted Tiger Expensive

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring IOC容器中装配Bean(XML)相关的知识,希望对你有一定的参考价值。

——基于XML的配置

依赖注入

  spring 依赖注入的方式有,属性注入和构造函数注入,还有不常用到的工厂方法注入。

  (1)属性注入

  属性注入要求 Bean 提供默认的构造函数,并为需要的属性提供 set 方法,spring 先调用 Bean 的默认构造函数实例化 Bean 对象,然后通过反射的方法调用 set 方法注入属性值。如下简单的范例:

public class Phone {
    private int id;
    private String name;
    private double price;

    public Phone() {
    }

    public Phone(int id, double price, String name) {
        this.id = id;
        this.price = price;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
Phone
<bean id="phone" class="com.bean.Phone" >
        <property name="id"><value>007</value></property>
        <property name="name"><value>"华为"</value></property>
        <property name="price"><value>4999</value></property>
 </bean>

  简化书写:

<bean id="phone" class="com.bean.Phone" >
        <property name="id" value="007"/>
        <property name="name" value="华为"/>
        <property name="price" value="4999" />
</bean>

  通过命名空间 p 进一步简化,   xmlns:p="http://www.springframework.org/schema/p"

  如下:  

<bean id="phone" class="com.bean.Phone" 
          p:id="007" p:name="华为" p:price="4999" p:time-ref="date" />

  p:属性-ref  表示引用。

  (2)构造函数注入

  使用构造注入的前提存在对应的有参构造函数。

public Phone(int id, double price, String name) {
        this.id = id;
        this.price = price;
        this.name = name;
}

  1、按类型匹配入参

<bean id="phone" class="com.bean.Phone" >
       <constructor-arg type="int" value="007"/>
        <constructor-arg type="java.lang.String" value="华为"/>
        <constructor-arg type="double" value="4999"/>
 </bean>

       2、按索引匹配入参

  第一个参数的索引是 0 

    <bean id="phone" class="com.bean.Phone" >
       <constructor-arg index="0" value="007"/>
        <constructor-arg index="2"   value="华为"/>
        <constructor-arg index="1" value="4999"/>
    </bean>

  3、按类型和索引匹配入参

  带参的构造函数很多时,容易发生歧义,用这种联合的方式匹配入参会更加的明确。

<constructor-arg index="2" type="java.lang.String" value="华为"/>

  4、自动类型反射匹配入参

  当类型都是可以辨别,不会产生歧义,才能这样使用。

<bean id="time" class="java.util.Date"/>
    <bean id="phone" class="com.bean.Phone" >
        <constructor-arg  type="java.util.Date" ref="time" />
        <constructor-arg  value="华为"/>
</bean>    

  以上都是对应基本数据类型,当属性是引用类型应采用如下的配置方式。

      给 Phone 添加属性: Date time;

 <constructor-arg  type="java.util.Date" ref="time" />

   或

<constructor-arg  type="java.util.Date">
            <ref bean="time"/>
        </constructor-arg>

  当构造函数配置 Bean A 的实例化,需要引用一个Bean B 的实例化,而 Bean B 也采用构造函数注入并且需要引用一Bean A 的实例化,这样就容易造成循环依赖发生死锁。——用属性注入就不会产生这个问题。

  (3)工厂方法注入

  工厂类对外屏蔽类的具体实例化步骤,调用者甚至无需知道具体的目标类是什么。

  1、非静态工厂方法

  实例化工厂类才可以调用工厂类中的方法。工厂方法如下:

public class PhoneFactory {
    public Phone creatPhone(){
        Phone phone = new Phone(“007”,"华为",“4999”);
        return phone;
    }
}

  通过工作方法注入。

<bean id="factory" class="com.bean.PhoneFactory"/>
<bean id="phone" factory-bean="factory" factory-method="creatPhone"/>

  实例化工厂类,factory-bean 引用这个工厂的实例化,通过 factory-method 指定对应的工厂方法。

  2、静态工厂方法

public class PhoneFactory {
    public static Phone creatPhone(){
        Phone phone = new Phone("华为",new Date());
        return phone;
    }
}

  使用静态工厂的方法,无须在配置文件实例化工厂类,按如下配置即可:

 <bean id="phone" class="com.bean.PhoneFactory" factory-method="creatPhone"/>

  class 属性指定工厂类的全包名,然后通过 factory-bean 指定对应的工厂方法。

注入参数详解

  在 spring 配置文件中,不仅可以将基本数据类型、String、等字面量注入 Bean ,还可以将集合(List、Map)和其它定义的 Bean 注入 Bean 中。

  (1)字面值

  指的是可以用字符串表示值,这些值可以通过<value></value>进行注入。一般情况下,基本数据类型及其封装类、Sring等类型均可以采用字面值注入的方式,spring 容器为字面值提供了编辑器,将以字符串表示的字面值转换相应的内部变量类型。

  XML中共有5个特殊的字符,分别是 & 、< 、> 、" 、’ 。如果需要注入值包含这些特殊字符,就需要用 <value>![CDATA[   ]]</value>

  (2)引用其它 Bean

Person
 <bean id="phone" class="com.bean.Phone">
        <constructor-arg index="0" value="007"/>
        <constructor-arg index="2"   value="华为"/>
        <constructor-arg index="1" value="4999"/>
    </bean>
    <bean id="person" class="com.bean.Person">
        <property name="name" value="张三"/>
        <property name="phone" ref="phone"/>
    </bean>

   (3)null 值

  用 <null/> 标签。 <property name="name"><null/></property>

  (4)级联属性

  

 <bean id="person" class="com.bean.Person">
        <property name="name" value="张三"></property>
        <property name="phone.name" value="华为"/>
        <property name="phone.price" value="4999" />
    </bean>

  (5)内部 Bean 

<bean id="person" class="com.bean.Person">
        <property name="name" value="张三"></property>
        <property name="phone">
            <bean class="com.bean.Phone">
                <property name="name" value="华为"/>
                <property name="price" value="4999" />
            </bean>
        </property>
 </bean>

   (6)集合属性

  

  <bean id="person" class="com.bean.Person">
       <property name="names">
           <set>
               <value>张三</value>
               <value>李四</value>
           </set>
       </property>
        <property name="phoneList">
            <list>
                <ref bean="phone"/>
                <ref bean="phone2"/>
            </list>
        </property>
        <property name="map">
            <map>
                <entry>
                    <key><value>9527</value></key>
                    <value>9527</value>
                </entry>
            </map>
        </property>
    </bean>

   通过 util 命名空间,配置集合类型的 Bean。 xmlns:util="http://www.springframework.org/schema/util"

  如下:

<bean id="person" class="com.bean.Person">
        <property name="map">
            <ref bean="map"/>
        </property>
    </bean>
    <util:map id="map">
        <entry>
            <key><value>9527</value></key>
            <value>9527</value>
        </entry>
    </util:map>

  (7)自动装配

  <bean> 元素提供了一个自动装配的属性:autowire="【自动装配的类型】”

1.       no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。

2.       byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

3.       byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

4.       constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。

5.       autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。

  <beans>元素标签中 default-autowire 属性可以配置全局自动匹配。(byName,byType,constructor)

Bean 之间的关系

  (1)继承 

<bean id="phone1" class="com.bean.Phone"
          p:id="007" p:name="华为" p:price="4999" abstract="true"/>
    <!-- abstract true 表示Bean 不需要实例化 -->
 <bean id="phone3" parent="phone1" p:id="110"  />

   子类会继承父类Bean 的属性值,相同时子类将覆盖父类的值。

  (2)依赖

  Bean A 实例化是需要 Bean B 先实例化完成,才可以得到正常结果,那么在 Bean A 配置 <bean  ......   depends-on = "a" /> ,这种方式就是显示指定 Bean A 的前置依赖。如果前置依赖多个可以通过空格、逗号、分号连接。

  (3)引用  

  一个 bean 要引用另为一个 bean 的 id 属性值。

<bean id="phone" class="com.bean.Phone"
          p:id="007" p:name="华为" p:price="4999" />
    <bean id="person" class="com.bean.Person">
        <property name="phoneId">
            <idref bean="phone"></idref>
        </property>
    </bean>

  也就是说:phoneId = phone

Bean 的作用域

  single 单实例    prototype 每次调用都产生一个新实例

以上是关于spring IOC容器中装配Bean(XML)的主要内容,如果未能解决你的问题,请参考以下文章

在IOC中装配Bean

学习笔记——Spring中的注解;Spring中装配对象的注解;使用注解配置对象中属性

Spring-IOC容器-Bean管理-基于XML方式超详解!

想找基于J2EE的网站设计找我们代做

想找基于J2EE的网站设计找我们代做

Spring5——IOC操作Bean管理(基于xml文件)