上一篇我们已经搭建了一个新的Gradle模块,接下来我们就要分析IoC容器实例化Bean的过程,在此之前,先来温习一下Spring实例化bean的三种方式,构造函数实例化,静态工厂实例化,工厂实例化
1.构造函数实例化
构造函数实例化是最常见也是最简单的一种实例化bean的方式,该方式也有两种使用方法
- 默认构造函数实例化
- 指定构造函数实例化
我们先来分析默认构造函数实例化
1.1 默认构造函数实例化
- 创建一个接口及其实现类作为bean
package org.springframework.beans;
/**
* @author LiYanChao
* @since 4.3
*/
public interface HelloApi {
void sayHello();
void sayListNames();
void saySetNames();
void sayArrayNames();
void sayMapNames();
void sayPropertiesNames();
}
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.springframework.util.CollectionUtils;
/**
*
* @author LiYanChao
* @since 4.3
*/
public class HelloImpl implements HelloApi {
private String message;
private String name;
private List<String> listNames;
private Set<String> setNames;
private Properties propertiesNames;
private Map<String, String> mapNames;
private String[] arrayNames;
public HelloImpl() {
}
public HelloImpl(String name) {
this.name = name;
}
public HelloImpl(String name, String message) {
this.name = name;
this.message = message;
}
public void sayArrayNames() {
System.out.println("DI array properties");
if (arrayNames != null && arrayNames.length > 0) {
for (int i = 0; i < arrayNames.length; i++) {
System.out.println(arrayNames[i]);
}
}
System.out.println();
}
public void sayMapNames() {
if (null != mapNames && mapNames.size() > 0) {
System.out.println("DI map properties");
for (Map.Entry<String, String> entry : mapNames.entrySet()) {
System.out.println("key= " + entry.getKey() + " value= "
+ entry.getValue());
}
System.out.println();
}
}
public void sayPropertiesNames() {
if (null != propertiesNames) {
System.out.println("DI properties properties");
System.out.println(propertiesNames.get("name"));
System.out.println(propertiesNames.get("age"));
System.out.println();
}
}
public void sayListNames() {
if (!CollectionUtils.isEmpty(listNames)) {
System.out.println("DI list properties");
for (String string : listNames) {
System.out.println(string);
}
System.out.println();
}
}
public void saySetNames() {
if (!CollectionUtils.isEmpty(setNames)) {
System.out.println("DI set properties");
Iterator<String> iterator = setNames.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println();
}
}
@Override
public void sayHello() {
System.out.println(message + name);
}
// 省略get/set方法
- 在resources目录下新建myTestBean.xml配置文件
<!-- ====================实例化bean的方式Begin==================== -->
<!-- 默认构造函数 -->
<bean id="helloBean1" class="org.springframework.beans.HelloImpl"/>
<!-- ====================实例化bean的方式End==================== -->
- 新建测试用例
package org.springframework.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.HelloApi;
import org.springframework.beans.HelloImpl;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Assert;
import static org.junit.Assert.assertEquals;
/**
* @author LiYanChao
* @since 4.3
*/
public class BeanTest {
private XmlBeanFactory xmlBeanFactory;
HelloApi helloApi;
@Before
public void initXmlBeanFactory() {
xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("myTestBean.xml"));
}
@Test
public void testDefaultConstructor() {
helloApi = xmlBeanFactory.getBean("helloBean1", HelloImpl.class);
System.out.println(helloApi);
}
}
1.2 指定构造函数实例化
- 配置文件
<!-- 指定构造器实例化 -->
<bean id="helloBean2" class="org.springframework.beans.HelloImpl">
<!-- 指定构造器参数 index对应构造器中参数的位置 -->
<constructor-arg index="0" value="I am a constructor"/>
<constructor-arg index="1" value="Hello, "/>
</bean>
- 测试用例
@Test
public void testConstructor() {
helloApi = xmlBeanFactory.getBean("helloBean2", HelloImpl.class);
helloApi.sayHello();
}
输出Hello, I am a constructor
2. 静态工厂实例化
- Bean
package org.springframework.beans;
/**
*
* @author LiYanChao
* @since 4.3
*/
public class HelloApiStaticFactory {
// 静态工厂方法
public static HelloApi newInstance(String name, String message) {
// 返回需要的Bean实例
return new HelloImpl(name, message);
}
}
- 配置文件
<!-- 静态工厂方法实例化 -->
<bean id="helloBean3" class="org.springframework.beans.HelloApiStaticFactory" factory-method="newInstance">
<!-- 指定构造器参数 index对应构造器中参数的位置 -->
<constructor-arg index="0" value="I am a static factory"/>
<constructor-arg index="1" value="Hello, "/>
</bean>
- 测试用例
@Test
public void testStaticFactory() {
helloApi = xmlBeanFactory.getBean("helloBean3", HelloImpl.class);
helloApi.sayHello();
}
输出Hello, I am a static factory
3.实例工厂方法实例化
- bean
package org.springframework.beans;
/**
*
* @author LiYanChao
* @since 4.3
*/
public class HelloApiInstanceFactory {
// 工厂方法
public HelloApi newInstance(String name, String message) {
return new HelloImpl(name, message);
}
}
- 配置文件
<!-- 实例工厂方法实例化 -->
<bean id="helloApiInstanceFactory" class="org.springframework.beans.HelloApiInstanceFactory"/>
<!-- 不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法 -->
<bean id="helloBean4" factory-bean="helloApiInstanceFactory" factory-method="newInstance">
<constructor-arg index="0" value="I am a instance factory"/>
<constructor-arg index="1" value="Hello, "/>
</bean>
- 测试用例
@Test
public void testFactory() {
helloApi = xmlBeanFactory.getBean("helloBean4", HelloImpl.class);
helloApi.sayHello();
}
输出:Hello, I am a instance factory
Spring实例化bean的三种方式就讲到这里了,比较简单,但是其中的源码细节比较复杂,会在接下来的博客中分析