为了更好的分析Spring的源码,上一篇我们已经搭建了一个新的Gradle模块,接下来我们就要分析IoC容器实例化Bean的过程,在此之前,先来温习一下Spring的一些基础知识,在接下来的几个小节中,我们会来介绍
这些都是在分析Spring源码之前,必须熟悉的基础知识,在本小节中我们先介绍第一点,Spring实例化bean的三种方式:构造函数实例化
,静态工厂实例化
,工厂方法实例化
构造函数实例化是最常见也是最简单的一种实例化bean的方式,该方式也有两种使用方法
我们先来分析默认构造函数实例化
package com.lyc.cn.day01;
/**
* @author LiYanChao
* @create: 2018-09-07 23:40
*/
public interface HelloApi {
void sayHello();
}
package com.lyc.cn.day01;
/**
* @author LiYanChao
* @create: 2018-09-07 23:40
*/
public class HelloImpl implements HelloApi {
/** 姓名 **/
private String name;
/** 年龄 **/
private int age;
/** 无参构造函数 **/
public HelloImpl() {
}
/**
* 有参构造函数
* @param name 姓名
* @param age 年龄
*/
public HelloImpl(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public void sayHello() {
System.out.println("大家好, 我叫" + getName() + ", 我今年" + getAge() + "岁了");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
<!-- ====================实例化bean的方式Begin==================== -->
<!-- 默认构造实例化 -->
<bean id="helloBean1" class="com.lyc.cn.day01.HelloImpl"/>
<!-- ====================实例化bean的方式End==================== -->
package com.lyc.cn.day01;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* @author: LiYanChao
* @create: 2018-09-07 23:40
*/
public class MyTest {
private XmlBeanFactory xmlBeanFactory;
@Before
public void initXmlBeanFactory() {
System.out.println("========测试方法开始=======\n");
xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("day01.xml"));
}
@After
public void after() {
System.out.println("\n========测试方法结束=======");
}
@Test
public void test1() {
// 默认构造器
HelloApi helloBean1 = xmlBeanFactory.getBean("helloBean1", HelloImpl.class);
helloBean1.sayHello();
}
}
========测试方法开始=======
大家好, 我叫null, 我今年0岁了
========测试方法结束=======
<!-- 指定构造器实例化 -->
<bean id="helloBean2" class="com.lyc.cn.day01.HelloImpl">
<!-- 指定构造器参数 index对应构造器中参数的位置 -->
<!-- 也可以通过指定参数类型,指定参数名称来注入属性-->
<constructor-arg index="0" value="小明"/>
<constructor-arg index="1" value="3"/>
</bean>
@Test
public void test2() {
// 指定构造器
HelloApi helloBean2 = xmlBeanFactory.getBean("helloBean2", HelloImpl.class);
helloBean2.sayHello();
}
========测试方法开始=======
大家好, 我叫小明, 我今年3岁了
========测试方法结束=======
package com.lyc.cn.day01;
/**
* 静态工厂实例化
* @author LiYanChao
* @create: 2018-09-07 23:40
*/
public class HelloApiStaticFactory {
// 静态工厂方法
public static HelloApi newInstance(String name, String message) {
// 返回需要的Bean实例
return new HelloImpl("小明", 3);
}
}
<!-- 静态工厂方法实例化 -->
<bean id="helloBean3" class="com.lyc.cn.day01.HelloApiStaticFactory" factory-method="newInstance">
<!-- 指定构造器参数 index对应构造器中参数的位置 -->
<constructor-arg index="0" value="小明"/>
<constructor-arg index="1" value="3"/>
</bean>
@Test
public void test3() {
// 静态工厂
HelloApi helloBean3 = xmlBeanFactory.getBean("helloBean3", HelloImpl.class);
helloBean3.sayHello();
}
========测试方法开始=======
大家好, 我叫小明, 我今年3岁了
========测试方法结束=======
package com.lyc.cn.day01;
/**
* 工厂方法实例化
* @author LiYanChao
* @create: 2018-09-07 23:40
*/
public class HelloApiInstanceFactory {
public HelloApi newInstance(String name, String message) {
return new HelloImpl("小明", 3);
}
}
<!-- 实例工厂方法实例化 -->
<bean id="helloApiInstanceFactory" class="com.lyc.cn.day01.HelloApiInstanceFactory"/>
<!-- 不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法 -->
<bean id="helloBean4" factory-bean="helloApiInstanceFactory" factory-method="newInstance">
<constructor-arg index="0" value="小明"/>
<constructor-arg index="1" value="3"/>
</bean>
@Test
public void test4() {
// 实例工厂
HelloApi helloBean4 = xmlBeanFactory.getBean("helloBean4", HelloImpl.class);
helloBean4.sayHello();
}
========测试方法开始=======
大家好, 我叫小明, 我今年3岁了
========测试方法结束=======
Spring实例化bean的三种方式就讲到这里了,本章节的内容比较简单,不再做过多的分析,但是其中的源码细节比较复杂,会在接下来的博客中分析。