Springboot 定制容器中Bean的生命周期

前面我们粗略地了解到了容器Bean的四种类型和生命周期,其中Singleton和prototype类型的Bean使用的比较频繁。对于单例Bean,在容器初始化前被创建;而对于多实例Bean在调用时创建,也是在容器初始化后创建。在这篇博客,我们来了解如何详细地了解Bean的生命周期和如何定制其生命周期。

  • 对于单例Bean的生命周期可分为创建、注入、销毁;创建在容器初始化前进行,我们可以定制一些在Bean初始化期间的业务逻辑;注入由容器决定,在容器初始化之后;销毁在容器销毁后进行,同样我们可以定制一些在Bean销毁期间的业务逻辑。

  • 创建POJO类,并实现初始化和销毁方法。

public class Student {
        public void initial(){
            System.err.println("The initial method is calling.");
        }

        public void destroy(){
            System.err.println("The destroy method is calling.");
        }
}
  • 在Configuration类中注入Bean,并通过@Bean注解的参数指定初始化和销毁的方法:
import com.michael.annotation.demo.POJO.Student;
import org.springframework.context.annotation.*;

@Configuration
@Import({Student.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MyConfig {
    @Bean(name = "stu1",initMethod = "initial", destroyMethod = "destroy")
    public Student student(){
        return new Student();
    }
}
  • 测试代码:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import static java.lang.System.out;
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
        out.println("The container has been initialized.");
         for(String name : applicationContext.getBeanDefinitionNames()){
             if(!name.contains("."))
                out.println(name);
        }
        out.println("The container has been destroyed.");
    }
}
  • 输出:
The initial method is calling.
2020-03-24 17:26:10.643  INFO 24392 --- [           main] c.m.annotation.demo.DemoApplication      : Started DemoApplication in 0.636 seconds (JVM running for 0.955)
The container has been initialized.
demoApplication
test
myConfig
personService
stu1
Class
propertySourcesPlaceholderConfigurer
taskExecutorBuilder
applicationTaskExecutor
taskSchedulerBuilder
The container has been destroyed.
The destroy method is calling.
  • 从输出来看,其结果和我们预期的基本一致。

  • 对于多实例Bean,它在被调用时被创建时可重复创建,而且容器不管其销毁过程。

  • 修改添加@Scope注解,value为"prototype":

import com.michael.annotation.demo.POJO.Student;
import org.springframework.context.annotation.*;

@Configuration
@Import({Student.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MyConfig {
    @Scope("prototype")
    @Bean(name = "stu1",initMethod = "initial", destroyMethod = "destroy")
    public Student student(){
        System.out.println("The Bean is created.");
        return new Student();
    }
}
  • 测试代码:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import static java.lang.System.out;
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
        out.println("The container has been initialized.");
        applicationContext.getBean("stu1");
         for(String name : applicationContext.getBeanDefinitionNames()){
             if(!name.contains("."))
                out.println(name);
        }
        out.println("The container has been destroyed.");
    }
}
  • 输出:
The container has been initialized.
The Bean is created.
demoApplication
test
myConfig
personService
stu1
Class
propertySourcesPlaceholderConfigurer
taskExecutorBuilder
applicationTaskExecutor
taskSchedulerBuilder
The container has been destroyed.
The initial method is calling.

Process finished with exit code 0
  • 从输出,我们可以看到initial和destroy方法都没有被调用。这里可以知道,容器只负责创建多实例Bean。除此之外,我还测试不调用getBean方法,"stu1"仍被打印了出来;这说明当Bean为多实例时,容器就会创建一个对应Bean的对象,拥有ID,但是为null。
发布了70 篇原创文章 · 获赞 4 · 访问量 3027

猜你喜欢

转载自blog.csdn.net/qq_34515959/article/details/105086025