Spring全家桶-疑难问题收录

一、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停止计时

[ 持续更新中… ]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭建華

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值