前言
传统应用程序可以通过new和反射的方式来实例化Bean。而Spring Ioc容器则需要根据配置元数据使用反射机制来创建Bean。在Spring Ioc容器中根据Bean创建Bean实例有以下几种方式。
(1)、使用构造器实例化Bean
(2)、使用静态工厂实例化Bean
(3)、使用实例工厂实例化Bean
一、使用构造器实例化Bean:Spring IoC容器能使用默认空构造器也能使用有参数构造器两种方式创建Bean。
(a)、使用空构造器进行定义,使用此种方式,class属性指定的类必须有空构造器
(b)、使用有参数构造器进行定义,使用此中方式,可以使用< constructor-arg >标签指定构造器参数值,其中index表示位置,value表示常量值,也可以指定引用,指定引用使用ref来引用另一个Bean定义
配置文件:
<!-- 默认构造器 --> <bean name="bean1" class="cn.javass.spring.ioc01.helloword.HelloImpl"></bean> <!-- 有参数构造器 --> <bean name="bean2" class="cn.javass.spring.ioc01.helloword.HelloImpl"> <!-- 指定构造器参数 --> <constructor-arg index="0" value="Hello Spring"/> </bean>
定义接口HelloApi.java
package cn.javass.spring.ioc01.helloword; public interface HelloApi { public void sayHello(); }
定义实现类HelloImpl.java
package cn.javass.spring.ioc01.helloword; public class HelloImpl implements HelloApi { private String message; public HelloImpl(){ this.message = "helloword!"; } public HelloImpl(String message){ this.message = message; } public void sayHello() { System.out.println(message); } }
测试类
package cn.javass.spring.ioc01.helloword; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloTest { @Test public void testHelloWord(){ // 1、读取配置文件,实例化ioc容器 ApplicationContext context = new ClassPathXmlApplicationContext("helloword.xml"); // 2、从容器中获取bean,注意此处完全面向接口编程,而不是面向实现 // 通过构造方法实例化bean:默认无参构造 HelloApi bean1 = context.getBean("bean1",HelloApi.class); // 通过构造方法实例化bean:带参数实例化bean HelloApi bean2 = context.getBean("bean2",HelloApi.class); // 3、执行方法 bean1.sayHello(); bean2.sayHello(); } }
二、使用静态工厂方式实例化Bean:使用这种方式除了指定必须的class属性,还要指定factory-method属性来指定实例化Bean的方法,而且使用静态工厂方法也允许指定方法参数,spring IoC容器将调用此属性指定的方法来获取Bean,配置如下:
配置文件
<!-- 二、通过静态工厂实例化bean --> <bean name="bean3" class="cn.javass.spring.ioc01.helloword.HelloApiStaticFactory" factory-method="newInstance"> <constructor-arg index="0" value="Hello Static Factory!"/> </bean>
静态工厂类
package cn.javass.spring.ioc01.helloword; public class HelloApiStaticFactory { public static HelloApi newInstance(String message) { return new HelloImpl(message); } }
测试方法
package cn.javass.spring.ioc01.helloword; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloTest { @Test public void testHelloWord(){ // 1、读取配置文件,实例化ioc容器 ApplicationContext context = new ClassPathXmlApplicationContext("helloword.xml"); // 2、从容器中获取bean,注意此处完全面向接口编程,而不是面向实现// 通过静态工厂实例化bean: HelloApi helloApiStaticFactory = context.getBean("helloApiStaticFactory",HelloApi.class);// 3、执行方法 helloApiStaticFactory.sayHello(); } }
三、使用实例工厂方法实例化Bean,使用这种方式不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法,而且使用实例工厂方法允许指定方法参数,方式和使用构造器方式一样,配置如下:
配置文件
<!-- 先创建一个工厂bean --> <bean id="beanInstanceFactory" class="cn.javass.spring.ioc01.helloword.HelloApiInstanceFactory"></bean> <!--常见并实例化工厂bean--> <bean id="bean4" factory-bean="beanInstanceFactory" factory-method="newInstance"> <constructor-arg index="0" value="Hello Instance Factory!"/> </bean>
实例工厂
package cn.javass.spring.ioc01.helloword; public class HelloApiInstanceFactory { public HelloApi newInstance(String message) { return new HelloImpl(message); } }
测试方法
package cn.javass.spring.ioc01.helloword; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloTest { @Test public void testHelloWord(){ // 1、读取配置文件,实例化ioc容器 ApplicationContext context = new ClassPathXmlApplicationContext("helloword.xml"); // 2、从容器中获取bean,注意此处完全面向接口编程,而不是面向实现// 通过实例工厂实例化bean: HelloApi bean4 = context.getBean("bean4",HelloApi.class); // 3、执行方法 bean4.sayHello(); } }