实例化 Bean 的三种方式

Bean(也就是 Spring IoC 中的对象)有3种实例化方式l 基于构造方法对象实例化,基于静态工厂实例化,基于工厂实例方法实例化。

基于构造方法对象实例化

工作中,绝大多数场景都可以使用 基于构造方法对象实例化。在Apple 类中新增 price 属性 ,getter, setter方法,和对应的 4参数 构造方法。

public class Apple {
    private String title;
    private String color;
    private String origin;
    private float price;

    public Apple(String title, String color, String origin) {
        System.out.println("使用带参构造方法(3个参数)创建对象," + this);
        this.title = title;
        this.color = color;
        this.origin = origin;
    }

    public Apple(String title, String color, String origin, float price) {
        System.out.println("使用带参构造方法(4个参数)创建对象 : " + this);
        this.title = title;
        this.color = color;
        this.origin = origin;
        this.price = price;
    }

    public Apple() {
        System.out.println("使用无参构造方法创建对象 : " + this);
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

     // 其他部分与上一节相同。


}

在 applicationContext.xml 中增加下面3个 bean。

    <!-- bean 标签默认通过默认构造方法创建对象 -->
    <bean id="apple1" class="indi.chester.spring.ioc.entity.Apple">

    </bean>

    <!-- bean 可以通过参数个数自动选择合适的构造方法 -->
    <bean id="apple2" class="indi.chester.spring.ioc.entity.Apple">
        <constructor-arg name="title" value="红富士"/>
        <constructor-arg name="color" value="红色"/>
        <constructor-arg name="origin" value="欧洲"/>
    </bean>

    <!-- bean 可以通过参数个数自动选择合适的构造方法 -->
    <bean id="apple3" class="indi.chester.spring.ioc.entity.Apple">
        <constructor-arg name="title" value="红富士"/>
        <constructor-arg name="color" value="红色"/>
        <constructor-arg name="origin" value="欧洲"/>
        <constructor-arg name="price" value="9.9"/>
    </bean>

Spring IoC 会根据 bean 中的参数个数,自动 选择对应的构造方法。类的创建顺序和 bean 的顺序相同。

基于静态工厂实例化

创建一个工厂类,工厂里面有一个静态方法,在静态方法中创建好对象,然后return 给 Spring IoC.

package indi.chester.spring.ioc.factory;

import indi.chester.spring.ioc.entity.Apple;

//静态工厂通过静态方法创建对象, 隐藏创建对象的细节
public class AppleStaticFactory {
    public static Apple createSweetApple(){
        Apple apple =new Apple();
        apple.setTitle("红富士");
        apple.setOrigin("欧洲");
        apple.setColor("红色");
        System.out.println("通过静态方法创建对象 : "+apple);
        return apple;
    }
}

在 applicationContext.xml中加入一个 新的 bean

<!-- bean 可以通过静态工厂创建对象 -->
<bean id="apple4" class="indi.chester.spring.ioc.factory.AppleStaticFactory" factory-method="createSweetApple"/>

在调用对象时和 基于 构造方法创建对象一样,直接使用 applicationContext 对象 的 getBean 方法获取即可。

基于工厂实例方法实例化

在Spring IoC容器中定义一个bean(工厂实例),在工厂实例中定义一个方法return 对象。在定义一个 bean 通过对工厂实例 bean 创建对象。

//工厂实例方法是指 IoC容器对工厂进行实例化并调用 对应的实例方法创建 对象
public class AppleFactoryInstance {
    public Apple createSweetApple(){
        Apple apple =new Apple();
        apple.setTitle("红富士");
        apple.setOrigin("欧洲");
        apple.setColor("红色");
        System.out.println("通过工厂实例方法创建对象 : " + apple);
        return apple;
    }
}

在 applicationContext.xml中加入两个 bean

<!-- 利用工厂实例方法获取对象 -->
    <bean id="factoryInstance" class="indi.chester.spring.ioc.factory.AppleFactoryInstance" />
    <bean id="apple5" factory-bean="factoryInstance" factory-method="createSweetApple"/>

在调用对象时和 基于 构造方法创建对象一样,直接使用 applicationContext 对象 的 getBean 方法获取即可。

多个 applicationContext.xml 文件

假设有多个 applicationContext 文件,里面定义了重复的id,则后创建的会覆盖掉前面创建的,创建的顺序由配置文件的顺序决定。比如在下面代码中, 如果有两个 id 相同的bean。applicationContext2.xml 里面的bean 就会覆盖掉 applicationContext.xml 里面的bean

// 如果有多个配置文件,后面的会覆盖掉前面的
String[] configLocations = new String[]{"classpath:applicationContext.xml","classpath:applicationContext2.xml"};
//创建 Spring IoC 容器, 并配置文件在容器中实例化对象
ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);

Last updated