Spring IoC容器如何实例化Bean呢?

传统应用程序可以通过new反射方式进行实例化Bean。而Spring IoC 容器则需要根据Bean定义里的配置元数据使用反射机制来创建Bean。在Spring IoC 容器中主要有以下几种创建Bean实例的方式:

一.构造器实例化
构造器实例化 Bean 是最简单的方式,Spring IoC容器既能使用默认空构造器也能使用有参数构造器两种方式创建Bean,如以下方式指定要创建的Bean类型:

1. 空构造器实例化:

<bean id="helloServiceNoWithArgs" class="cn.lovepi.***.HelloWorldImpl" />
2. 有参数构造器实例化:

<bean id="helloServiceWithArgs" class=" cn.lovepi.***.HelloWorldmpl">
    <!-- 指定构造器参数 -->
    <constructor-arg index="0" value="Hello Spring!"/>
</bean>

接下以一个简单的例子来介绍:
在项目中创建一个instance包,在包中创建一个HelloWorld接口:
public interface HelloWorld {
    public  void sayHello();
}
接下来为这个接口创建一个实现类HelloWorldImpl:

public class HelloWorldImpl implements HelloWorld{
    private String message;

    /**
    * 空构造器
    */
    HelloWorldImpl(){
        message="Hello World";
    }

    /**
    * 带参数的构造器
    * @param message
    */
    HelloWorldImpl(String message){
        this.message=message;
    }
    public void sayHello() {
        System.out.println(message);
    }
}
编写配置文件conf-instance.xml:
<!--使用默认构造参数-->
<bean id="helloWorldWithNoArgs"
class="cn.lovepi.chapter03.instance.HelloWorldImpl" />

<!--使用有参数构造参数-->
<bean id="helloWorldWithArgs"
class="cn.lovepi.chapter03.instance.HelloWorldImpl" >
    <!-- 指定构造器参数 -->
    <constructor-arg index="0" value="Hello Args!"/>
</bean>

接下来创建Main.java,作为程序入口
/**
* 使用无参数的构造函数来实例化bean
*/
public static void sayHelloWordWithNoArgs(){
    BeanFactory factory=
            new FileSystemXmlApplicationContext("src/conf/conf-instance.xml");
    HelloWorld helloWorld=factory.getBean("helloWorldWithNoArgs",HelloWorldImpl.class);
    helloWorld.sayHello();
}

/**
* 使用有参数的构造函数来实例化bean
*/
public static void sayHelloWorldWithArgs(){
    BeanFactory factory=
            new FileSystemXmlApplicationContext("src/conf/conf-instance.xml");
    HelloWorld helloWorld=factory.getBean("helloWorldWithArgs",HelloWorldImpl.class);
    helloWorld.sayHello();
}
二.使用静态工厂来实例化Bean
使用静态工厂的方式除了指定必须的class属性,还要指定factory-method属性来指定实例化Bean的方法,而且使用静态工厂方法也允许指定方法参数,Spring IoC容器将调用此属性指定的方法来获取Bean,配置如下:
<!--使用有参数构造参数-->
<bean id="helloServiceStaticFactory"  class="cn.lovepi.***.HelloWorldStaticFactory"
factory-method="newInstance">
     <!-- 指定构造器参数 -->
     <constructor-arg index="0" value="Hello Static Factory!"/>
</bean>
接下来我们在项目中实现:
首先编写静态工厂方法类HelloWorldStaticFactory
public class HelloWorldStaticFactory {
    /**
    * 工厂方法
    * @param message
    * @return
    */
    public static HelloWorld newInstance(String message){
        //返回带参数的HelloWorldImpl构造的helloWorld实例
        return new HelloWorldImpl(message);
    }
}
接下来在配置文件中来配置当前bean

<!--静态工厂方式-->
<bean id="helloWorldStaticFactory"
class="cn.lovepi.chapter03.instance.HelloWorldStaticFactory"
factory-method="newInstance" >
    <!-- 指定构造器参数 -->
    <constructor-arg index="0" value="Hello Static Factory!"/>
</bean>
在Main中实例化Bean
public static void sayHelloWordStaticFactory(){
    //读取配置文件,实例化一个IoC容器
    BeanFactory factory=
            new FileSystemXmlApplicationContext("src/conf/conf-instance.xml");
    //从容器中获取bean,注意此处完全“面向接口编程而不是面向实现”
    HelloWorld helloWorld=factory.getBean("helloWorldStaticFactory",HelloWorld.class);
    //执行业务逻辑
    helloWorld.sayHello();
}

三.使用实例工厂来实例化bean
使用实例工厂方式不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法,而且使用实例工厂方法允许指定方法参数,方式和使用构造器方式一样,配置如下:
<!-- 1、定义实例工厂Bean -->
<bean id="beanInstanceFactory" class="cn.lovepi.***.HelloWorldInstanceFactory" />
<!-- 2、使用实例工厂Bean创建Bean -->
    <bean id=“helloWorldInstance" factory-bean="beanInstanceFactory"
                              factory-method="newInstance">
         <constructor-arg index="0" value="Hello  Instance Factory!"></constructor-arg>
    </bean>
接下来在项目中实现
首先我们编写实例化工厂方法HelloWorldInstanceFactory
public class HelloWorldInstanceFactory {
    /**
    * 工厂方法
    * @param message
    * @return
    */
    public HelloWorld newInstance(String message){
        //需要返回的bean实例
        return new HelloWorldImpl(message);
    }
}
在配置文件中配置相关属性:
<!-- 1、定义实例工厂Bean -->
<bean id="helloWorldInstanceFactory"
class="cn.lovepi.chapter03.instance.HelloWorldInstanceFactory" />
<!-- 2、使用实例工厂Bean创建Bean -->
<bean id="helloWorldInstance"
      factory-bean="helloWorldInstanceFactory"
      factory-method="newInstance">
    <constructor-arg index="0"
                      value="Hello Instance Factory!">

    </constructor-arg>
</bean>
在Main中实例化Bean
public static void sayHelloWorldInstanceFactory(){
    //读取配置文件,实例化一个IoC容器
    BeanFactory factory=
            new FileSystemXmlApplicationContext("src/conf/conf-instance.xml");
    //从容器中获取bean,注意此处完全“面向接口编程而不是面向实现”
    HelloWorld helloWorld=factory.getBean("helloWorldInstance",HelloWorld.class);
    //执行业务逻辑
    helloWorld.sayHello();
}
总结:
实例化Bean的三种方式的不同之处仅仅在于其配置文件的格式上,其使用方式都是一样的。










Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐