• 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 每次调用都产生一个新实例

  • 相关阅读:
    Silverlight数据绑定之DataGrid
    演练:使用属性自定义 DataGrid 控件
    [开源下载] 【开源项目】EasySL for Silverlight 4
    Expression Blend实例中文教程(13)
    Expression Blend实例中文教程(12)
    Expression Blend实例中文教程(11)
    Expression Blend实例中文教程(10)
    Expression Blend实例中文教程(8)
    Expression Blend实例中文教程(7)
    Expression Blend实例中文教程(6)
  • 原文地址:https://www.cnblogs.com/SacredOdysseyHD/p/8495541.html
Copyright © 2020-2023  润新知