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" />
- <bean id="helloServiceWithArgs" class=" cn.lovepi.***.HelloWorldmpl">
- <!-- 指定构造器参数 -->
- <constructor-arg index="0" value="Hello Spring!"/>
- </bean>
接下以一个简单的例子来介绍:
在项目中创建一个instance包,在包中创建一个HelloWorld接口:
- public interface HelloWorld {
- public void sayHello();
- }
- 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);
- }
- }
- <!--使用默认构造参数-->
- <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 id="helloWorldStaticFactory"
- class="cn.lovepi.chapter03.instance.HelloWorldStaticFactory"
- factory-method="newInstance" >
- <!-- 指定构造器参数 -->
- <constructor-arg index="0" value="Hello Static Factory!"/>
- </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的三种方式的不同之处仅仅在于其配置文件的格式上,其使用方式都是一样的。