Spring- Bean的实例化

Posted RZ_Lee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring- Bean的实例化相关的知识,希望对你有一定的参考价值。

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

使用构造器实例化Bean

使用静态工厂方式实例化Bean

使用实例工厂方法实例化Bean

 

使用空构造器实例化时,该类必须含有空参构造器,如果不存在的话在实例化过程中将会抛出异常。

样例结构

 

HelloWorld接口

package com.zc.spring.chapter04.instance;

public interface HelloWorld {
	public void sayHello();
}

接口实现类

package com.zc.spring.chapter04.instance;

public class HelloWorldImpl implements HelloWorld {

	private String message;
	
	/**
	 * 空构造器
	 */
	public HelloWorldImpl() {
		this.message = "hello world!";
	}

	/**
	 * 带参构造器
	 * @param message
	 */
	public HelloWorldImpl(String message) {
		
		this.message = message;
	}

	@Override
	public void sayHello() {
		System.out.println(message);

	}

}

src下的conf/conf-instance.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    
    xsi:schemaLocation="
    	http://www.springframework.org/schema/beans 
    	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <!-- 使用默认构造参数 -->
        <bean id="helloWorldWithNoArgs" class="com.zc.spring.chapter04.instance.HelloWorldImpl" />
        
        <!-- 使用有参构造参数 -->
        <bean id="helloWorldWithArgs" class="com.zc.spring.chapter04.instance.HelloWorldImpl" >
        	<!-- 指定构造器参数 -->
        	<constructor-arg index="0" value="Hello Args!" />
        </bean>
        
        <!-- 静态工厂方法 -->
        <bean id="helloWorldStaticFactory" 
        class="com.zc.spring.chapter04.instance.HelloWorldStaticFactory" factory-method="newInstance">
        	<!-- 指定构造器参数 -->
        	<constructor-arg index="0" value="Hello Static Factory!" />
        </bean>
        
        
        <!-- 1.定义实例工厂Bean -->
        <bean id="helloWorldInstanceFactory" 
        class="com.zc.spring.chapter04.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>
       
</beans>

  静态工厂

使用静态工厂的方式除了指定必须的class属性,还要指定factory-method属性来指定实例化Bean的方法,而且使用静态工厂方法也允许指定方法参数,Spring Ioc容器将调用此属性指定的方法来获取Bean。

package com.zc.spring.chapter04.instance;

public class HelloWorldStaticFactory {

	/**
	 * 工厂方法
	 * @param message
	 * @return
	 */
	public static HelloWorld newInstance(String message) {
		//返回需要的Bean实例
		return new HelloWorldImpl(message);
	}
}

  实例工厂

使用实例工厂方式不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法,而且使用实例化工厂方法允许指定方法参数,方式和使用构造器方式一样。

package com.zc.spring.chapter04.instance;

public class HelloWorldInstanceFactory {
	/**
	 * 工厂方法
	 * @param message
	 * @return
	 */
	public HelloWorld newInstance(String message) {
		// 返回需要的Bean实例
		return new HelloWorldImpl(message);
	}
}

  Main

package com.zc.spring.chapter04.instance;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		sayHelloWithNoArgs();
		sayHelloWithArgs();
		sayHelloStaticFactory();
		helloWorldInstanceFactory();
	}
	
	//使用无参数构造器来实例化Bean
	public static void sayHelloWithNoArgs() {
		BeanFactory beanFactory =  new ClassPathXmlApplicationContext("conf/conf-instance.xml");
		HelloWorld helloWorld = beanFactory.getBean("helloWorldWithNoArgs",HelloWorld.class);
		helloWorld.sayHello();
	}
	
	//使用有参数构造器来实例化Bean
	public static void sayHelloWithArgs() {
		BeanFactory beanFactory =  new ClassPathXmlApplicationContext("conf/conf-instance.xml");
		HelloWorld helloWorld = beanFactory.getBean("helloWorldWithArgs",HelloWorld.class);
		helloWorld.sayHello();
	}
	
	//使用静态工厂方法来实例化Bean
	public static void 	sayHelloStaticFactory() {
		// 1.读取配置文件实例化一个IOC容器
		BeanFactory beanFactory =  new ClassPathXmlApplicationContext("conf/conf-instance.xml");
		
		// 2.从容器中获取Bean,注意此处完全“面向接口编程,而不是面向实现”
		HelloWorld helloWorld = beanFactory.getBean("helloWorldStaticFactory",HelloWorld.class);
		
		// 3.执行业务逻辑
		helloWorld.sayHello();
	}
	
	// 使用实例工厂方法来实例化Bean 
	public static void helloWorldInstanceFactory() {
		// 1.读取配置文件实例化一个IOC容器
		BeanFactory beanFactory =  new ClassPathXmlApplicationContext("conf/conf-instance.xml");
				
		// 2.从容器中获取Bean,注意此处完全“面向接口编程,而不是面向实现”
		HelloWorld helloWorld = beanFactory.getBean("helloWorldInstance",HelloWorld.class);
				
		// 3.执行业务逻辑
		helloWorld.sayHello();
	}

}

  

 

以上是关于Spring- Bean的实例化的主要内容,如果未能解决你的问题,请参考以下文章

Spring 实例化bean的三种方式

Spring源码分析非懒加载的Bean实例化过程(下篇)

当没有代码的时候,Spring之Bean实例化过程是什么样子的呢?

Spring bean管理器 bean实例化的三种方式

spring-bean实例化三种方式

无法实例化Spring bean存储库