Spring通过xml创建对象方式和为不同类型的属性赋值的几种方式

一、IOC创建对象的三种方式

  1、使用无参构造器,也是默认的创建方式

  2、使用有参构造器

    1)第一种:下标赋值 :  <constructor-arg index="0" value="zhangsan"/>

    2)第二种:类型赋值:  <constructor-arg type="java.lang.String" value="zhangsan"/>  不能处理两个参数类型一样的情况

    3)  第三种:直接通过参数名赋值 <constructor-arg name="name" value="zhangsan"/>

  3、利用工厂创建对象   

     静态工厂:工厂本身不需要创建对象;通过静态方法调用,对象=工厂类.工厂方法名();

       使用方法:

        class: 指定工厂全类名
        factory-method: 指定工厂方法
        constructor-arg: 可以为方法传参

        <bean id="airPlane01" class="com.lxy.factory.AirPlaneStaticFactory" factory-method="getAirPlane">
          <constructor-arg name="name" value="波音747"/>
        </bean>


     实例工厂:工厂本身需要创建对象
        工厂类 工厂对象 = new 工厂类();
        工厂对象.工厂方法名();
        区别就是 一个是静态的方法 一个不是 静态方法可以直接调用,不是静态需要先new  

       使用方法      

        1、先配置出实例工厂对象  <bean id="airPlaneInstaceFactory" class="com.lxy.factory.AirPlaneInstanceFactory"/>
        2、配置我们要创建的AirPlane使用哪个工厂创建
          1)、factory-bean指定使用哪个工厂创建
          2)、factory-method指定使用哪个工厂方法   

          <bean id="airPlane02" class="com.lxy.pojo.AirPlane" factory-bean="airPlaneInstaceFactory" factory-method="getAirPlane">
            <constructor-arg name="name" value="波音787"/>
          </bean>

     实现了FactoryBean的接口类是Spring可以认识的工厂类  自己写的工厂类需要继承FactoryBean
         Spring会自动的调用工厂方法创建实例
           1、编写一个FactoryBean的实现类
           2、在Spring配置文件中进行注册

        <bean id="myFactoryBeanImpl" class="com.lxy.factory.MyFactoryBeanImpl"/>

    

二、不同类型的赋值/注入方式

1、普通赋值

  <bean id="hello" class="com.lxy.pojo.Hello">

    <property name="str" value="Spring"/> 通过value

  </bean>

2、对象赋值

  <bean id="userServiceImpl" class="com.lxy.service.UserServiceImpl">

    <property name="userDao" ref="mysqlImpl"/>  通过ref

  <bean/>

3、bean注入 (以下<bean id=""><bean>等省略,只写了注入方式)

  <property name="address" ref="hello"/>

4、数组注入 

  <property name="books">

    <array>

      <value>西游记</value>

      <value>红楼梦</value>

      <value>三国演义</value>

      <value>水浒传</value>

    </array>

  </property>

5、list 注入(set同理  只是把标签换成<set>)

   1) list中添加普通值

   <property name="hobbies">

    <list>

      <value>敲代码</value>

      <value>听音乐</value>

      <value>打台球</value>

    </list>

  </property>

  2)  list中添加对象 (所有其他容器类型都可以通过这种方式进行对象添加)
  <property name="bookList">
    <list>
      <bean id="book01" class="com.lxy.pojo.Book" p:bookName="三体"/>
      <ref bean="book01"/>
    </list>
  </property>

6、map注入 

  1)不可引用注入    

    <property name="card">
      <map>
        <entry key="1" value="身份证"/>
        <entry key="2" value="校园卡"/>
        <entry key="3" value="医保卡"/>
      </map>
    </property>

  2)可以引用注入(list、set也可以通过这种方式进行可以引用注入)    

    <util:map id="map">
      <entry key="1" value="元素1"/>
      <entry key="2" value="元素2"/>
      <entry key="3" value="元素3"/>
    </util:map>

7、null注入(主要用在想把某个已经赋值的属性再赋值为null)

  <property name="wife">
    <null/>
  </property>

8、properties注入 

  <property name="info">
    <props>
      <prop key="学号">1111</prop>
      <prop key="姓名">张三</prop>
    </props>
  </property>

9、继承<bean>的配置信息(如果一个<bean>设置有abstract=true 那么这个bean只能被继承,不能实例化)

  <bean id="book02" class="com.lxy.pojo.Book" parent="book01" >
    <property name="price" value="100"/>
  </bean>

三、通过命名空间注入值  (c命名空间和p命名空间不能直接使用,需要导入xml约束)

  1)、p命名空间注入,可以直接注入属性的值: property
    singleton: 单例模式(spring默认机制)
    1、在容器启动完成之前就已经创建好对象,保存在容器中
    2、任何获取都是获取之前创建好的对象

    导入p命名空间 xmlns:p="http://www.springframework.org/schema/p"

    bean id="user" class="com.lxy.pojo.User" p:name="张三" p:age="24" scope="singleton" 

  2)、c命名空间注入,通过构造器注入: constructor-args

    prototype: 原型模式:每次从容器中get的时候,都会产生一个新的对象

    1、容器启动默认不会去创建多实例bean  
    2、获取的时候创建bean
    3、每次获取都会创建一个新的实例对象

    导入p命名空间 xmlns:p="http://www.springframework.org/schema/c"

    <bean id="user2" class="com.lxy.pojo.User" c:age="24" c:name="李四" scope="prototype"/>

 四、通过SpEL(Spring Expression Language)赋值  

  <bean id="student" class="com.lxy.pojo.Student">
    <property name="name" value="lisi"/>
  </bean>
  <bean id="book" class="com.lxy.pojo.Book">
    <property name="bookName" value="三体"/>
    <property name="price" value="100"/>
  </bean>
  <bean id="user" class="com.lxy.pojo.User">
    <!--字面量 #{} 可以在#{}里面直接写运算表达式-->
    <property name="salary" value="#{12345.97*12}"/>
    <!--引用其他bean的某个属性值-->
    <property name="studentName" value="#{student.name}" />
    <!--引用其他bean-->
    <property name="book" value="#{book}"/>
    <!--调用静态方法--> #{T(全类名).方法名}
    <property name="id" value="#{T(java.util.UUID).randomUUID().toString().substring(0,5)}"/>
    <!--调用非静态方法-->
    <property name="age" value="#{book.getPrice()}"/>
  </bean>

五、自动装配

  自动装配:仅限于对自定义类型的属性有效 前提是容器中必须有相对应的组件

    byName: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id  注意:不能够区分大小写,id都用小写
    byType: 会自动在容器上下文中查找,和自己对象属相同的bean (可以省略id)注意:需要保证类型全局唯一
    constructor: 按照有参构造器进行赋值
      1、先按照有参构造器参数的类型进行装配,没有装配null
      2、如果找到的类型有多个,参数的名作为id继续匹配
    如果属性是一个容器 例如list<book> 那么自动装配会把所有的book的bean装配进去

    <bean id="people" class="com.lxy.pojo.People" autowire="byName">
      <property name="name" value="张三"/>
    </bean>

  也可以通过注解的方式 在属性上添加@Autowired

  总之,自动装配的前提是spring容器中有对应的组件,才会把该组件的值装配/赋值到要自动装配的属性上去。没有就不赋值

原文地址:https://www.cnblogs.com/lxy-java/p/12817542.html