10--Spring 实例化bean的三种方式


新版连接 01–Spring源码深度解析目录


为了更好的分析Spring的源码,上一篇我们已经搭建了一个新的Gradle模块,接下来我们就要分析IoC容器实例化Bean的过程,在此之前,先来温习一下Spring的一些基础知识,在接下来的几个小节中,我们会来介绍

  • Spring 实例化bean的三种方式
  • Spring Bean的生命周期
  • Spring BeanFactory和FactoryBean的区别
  • Spring 构造函数注入和Setter方法注入(一)
  • Spring lookup-method注入和replace-method注入(二)
  • Spring BeanPostProcessor和BeanFactoryPostProcessor的区别

这些都是在分析Spring源码之前,必须熟悉的基础知识,在本小节中我们先介绍第一点,Spring实例化bean的三种方式:构造函数实例化静态工厂实例化工厂方法实例化

1.构造函数实例化

构造函数实例化是最常见也是最简单的一种实例化bean的方式,该方式也有两种使用方法

  • 默认构造函数实例化
  • 指定构造函数实例化,我们只需配置参数即可,Spring会自动识别对应的构造函数

我们先来分析默认构造函数实例化

1.1 默认构造函数实例化
  • 创建一个接口及其实现类作为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;
	}
}
  • 在resources目录下新建day01.xml配置文件
<!-- ====================实例化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岁了

========测试方法结束=======
1.2 指定构造函数实例化
  • 配置文件
<!-- 指定构造器实例化 -->
<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岁了

========测试方法结束=======
2. 静态工厂实例化
  • Bean
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岁了

========测试方法结束=======
3.实例工厂方法实例化
  • bean
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的三种方式就讲到这里了,本章节的内容比较简单,不再做过多的分析,但是其中的源码细节比较复杂,会在接下来的博客中分析。

你可能感兴趣的:(Spring5.0源码解析)