文章目录
一、Spring
1. Bean的生命周期
- 测试Bean
public class TestBean {
private String name = "test";
public TestBean() {
System.out.println("Bean被创建了");
}
public void init(){
System.out.println("这是初始化方法");
}
public void destroy(){
System.out.println("这是销毁方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1.1 创建和销毁的时机
1.1.1 单例Bean
spring.xml
<bean class="ace.gjh.TestBean" id="testBean" init-method="init" destroy-method="destroy" scope="singleton"/>
- 测试方法
public static void main( String[] args )
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
TestBean testBean1 = (TestBean) context.getBean("testBean");
System.out.println(testBean1.getName());
TestBean testBean2 = (TestBean) context.getBean("testBean");
System.out.println(testBean2.getName());
context.destroy();
}
运行后的打印结果:
Bean被创建了
这是初始化方法
test
test
这是销毁方法
此时还看不出创建时机,我们把使用Bean的地方注释一下,看看Bean的创建是不是随着spring上下文一起创建的。
public static void main( String[] args )
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
/* TestBean testBean1 = (TestBean) context.getBean("testBean");
System.out.println(testBean1.getName());
TestBean testBean2 = (TestBean) context.getBean("testBean");
System.out.println(testBean2.getName());*/
context.destroy();
}
打印结果:
Bean被创建了
这是初始化方法
这是销毁方法
结论
Spring的单例Bean的创建随着Spring上下文的创建一起创建,且自动调用Bean的初始化方法,在Spring上下文销毁时,执行Bean的销毁方法。
1.1.2 多例Bean
将spring.xml
配置文件中的cope="singleton"
改为scope="prototype"
,如下:
<bean class="ace.gjh.TestBean" id="testBean" init-method="init" destroy-method="destroy" scope="prototype"/>
再分别执行下面两个主程序:
public static void main( String[] args )
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
context.destroy();
}
结果什么都没有打印。再看下面这个:
public static void main( String[] args )
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
TestBean testBean1 = (TestBean) context.getBean("testBean");
System.out.println(testBean1.getName());
TestBean testBean2 = (TestBean) context.getBean("testBean");
System.out.println(testBean2.getName());
context.destroy();
}
打印结果:
Bean被创建了
这是初始化方法
test
Bean被创建了
这是初始化方法
test
结论
Spring的多例Bean只在使用的时候才会创建,且创建后自动调用每一个Bean实例的初始化方法,在Spring上下文销毁时,所有Bean的销毁方法都不主动执行。
2. Spring循环依赖
循环依赖就是循环引用,就是两个或多个Bean之间持有对方,比如A引用了B,B引用了C,C引用了A,最终他们反映为一个环。Spring的循环依赖主要分为下面三种
2.1 构造器循环依赖
该情况无法解决,只能抛出BeanCurrentlyInCreationException
异常表示循环依赖。
2.2 setter循环依赖(单例)
这种情况通过Spring容器提前暴露刚完成的构造器注入但未完成其他步骤(如:setter注入)的bean来完成的,而且只能解决
2.3 setter循环依赖(多例)
对于prototype作用域的bean,Spring容器无法完成依赖注入,因为Spring作用域不进行缓存prototype作用域的bean,因此无法提前暴露一个创建中的bean。
二、Spring Boot
1. SpringBoot启动过程
- 构造一个StopWatch计时器,观察SpringApplication的执行。
- 将args参数封装到SpringApplicationRunListeners中并启动,用于监听run方法的执行。
- 创建并初始化ApplicationArguments,获取run方法传递的args参数。
- 创建并初始化环境配置ConfigurationEnvironment
- 打印banner
- 构造Spring容器(ApplicationContext)上下文
- SpringApplicationRunListeners结束
- StopWatch停止计时
[ 持续更新中… ]