SpringBoot @PostConstruct和@PreDestroy的使用说明

目录
  • 1. @PostConstruct
    • 1.1 概述
    • 1.2 验证执行顺序
  • 2. @PreDestroy

1. @PostConstruct

1.1 概述

@PostConstruct标记在方法上,在当前类的实例加入到容器之前,会先执行@PostConstruct标记的方法。它的执行顺序是这样的:

  • 先执行当前类的构造函数
  • 然后执行@Autowired标记对象的初始化
  • 最后执行@PostConstruct标记的方法
  • 如果没有抛出异常,则该对象加入Spring管理容器

1.2 验证执行顺序

创建一个空的Spring Boot项目,这步不演示了

创建TestComponent

@Component
public class TestComponent {
    public TestComponent(){
        System.out.println("TestComponent 构造函数");
    }
    @PostConstruct
    public void init(){
        System.out.println("TestComponent PostConstruct");
    }
}

创建MyService

public interface MyService {
    void Hello(String name);
}

创建MyServiceImpl

@Service
public class MyServiceImpl implements MyService {
    public MyServiceImpl(){
        System.out.println("MyServiceImpl 构造函数");
    }
    @PostConstruct
    public void init(){
        System.out.println("MyServiceImpl PostConstruct");
    }
    @Override
    public void Hello(String name) {
        System.out.println("Hello " + name);
    }
}

运行项目,看下输出结果。

TestComponent和MyServiceImpl分别独自初始化,构造函数优先执行

请记住这个执行顺序

TestComponent 构造函数

TestComponent PostConstruct

MyServiceImpl 构造函数

MyServiceImpl PostConstruct

还没完,改一下TestComponent,加入引用MyService

    @Autowired
    private MyService myService;

再执行一下,看看结果有什么变化

TestComponent 构造函数

MyServiceImpl 构造函数

MyServiceImpl PostConstruct

TestComponent PostConstruct

MyServiceImpl执行顺序往前移动了,证明@Autowired顺序在@PostConstruct之前

因此,如果要在TestComponent初始化的时候调用MyService方法,要写在@PostConstruct内部,不能在构造函数处理(这时候MyServiceImpl还没初始化,会抛出空指针异常)

@Component
public class TestComponent {
    @Autowired
    private MyService myService;
    public TestComponent(){
        System.out.println("TestComponent 构造函数");
        //写在这里必定抛出异常,此时 myService == null
		//myService.Hello("张三");
    }
    @PostConstruct
    public void init(){
        System.out.println("TestComponent PostConstruct");
        //在这里调用MySerice方法才正确
        myService.Hello("张三");
    }
}

2. @PreDestroy

首先,来看下Java Doc对这个注解的说明

1: 在对象实例被容器移除的时候,会回调调用@PreDestroy标记的方法

2: 通常用来释放该实例占用的资源

修改上面的TestComponent代码,加上@PreDestroy代码

    @PreDestroy
    public void destroy(){
        System.out.println("TestComponent 对象被销毁了");
    }

修改Application main方法,启动10秒后退出程序

@SpringBootApplication
public class AnnotationTestApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(AnnotationTestApplication.class, args);

        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ctx.close();
    }
}

启动程序,查看输出信息

程序退出时会销毁对象,所以会触发我们刚写的@PreDestroy方法,测试通过。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring定时任务中@PostConstruct被多次执行异常的分析与解决

    发现问题 最近在项目中刚刚修改一个功能,代码正准备验证,启动Idea的debug模式,运行项目,发现启动失败,查看日志发现定时任务被重复执行,导致异常.debug定时任务的初始化类,发现启动定时任务是在@PostConstruct方法中执行的,网上查询,有说Spring在某种情况下初始化有bug,注解@Component可能出现多次执行.把@Component修改为@Service就行了! 结果我改了也没解决问题! 无赖更一步跟进日志,发现以下内容: [ERROR][2017-06-20 19:

  • Spring实战之使用@POSTConstruct和@PreDestroy定制生命周期行为操作示例

    本文实例讲述了Spring实战之使用@POSTConstruct和@PreDestroy定制生命周期行为操作.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLS

  • SpringBoot @PostConstruct原理用法解析

    前言 本节我们将学习一下@PostConstruct的用法. 概述 @PostContruct是spring框架的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法. /** * 项目启动时,初始化定时器 */ @PostConstruct public void init() { List<Job> jobList = jobDao.selectJobAll(); for (Job job : jobList) { CronTrigger

  • SpringBoot @PostConstruct和@PreDestroy的使用说明

    目录 1. @PostConstruct 1.1 概述 1.2 验证执行顺序 2. @PreDestroy 1. @PostConstruct 1.1 概述 @PostConstruct标记在方法上,在当前类的实例加入到容器之前,会先执行@PostConstruct标记的方法.它的执行顺序是这样的: 先执行当前类的构造函数 然后执行@Autowired标记对象的初始化 最后执行@PostConstruct标记的方法 如果没有抛出异常,则该对象加入Spring管理容器 1.2 验证执行顺序 创建一

  • springboot @PostConstruct无效的解决

    目录 springboot @PostConstruct无效 解决办法 spring @PostConstruct的踩坑 在springboot程序启动过程中出现一个问题 springboot @PostConstruct无效 springboot 1.5.18,jdk9 @PostConstruct的方法并不执行,原因是jdk8以上的jdk使用了新的module系统,javax.annotation默认不可见. 解决办法 1.用jdk1.8 2.使用springboot 2.x 3.POM添加

  • SpringBoot使用@PostConstruct注解导入配置方式

    目录 使用@PostConstruct注解导入配置 使用@PostConstruct注解,完成静态对象注入 为什么static对象不可直接使用@Autowired注入? @PostConstruct和@PreDestroy 使用@PostConstruct注解导入配置 通过@PostConstruct注解能够通过一种更友好的方式将配置进行导入 代码如下: /** * 引导类 * * @author zhangzhixiang * @date 2018/09/18 14:51:39 */ @Con

  • 浅谈SpringBoot中的Bean初始化方法 @PostConstruct

    目录 注解说明 代码示例 注解示例 错误示例 正确示例 SpringBoot @PostConstruct虽好,也要慎用 1 问题的产生 2 案例模拟 3 总结 注解说明 使用注解: @PostConstruct 效果:在Bean初始化之后(构造方法和@Autowired之后)执行指定操作.经常用在将构造方法中的动作延迟. 备注:Bean初始化时候的执行顺序: 构造方法 -> @Autowired -> @PostConstruct 代码示例 注解示例 @Component public cl

  • Idea工具中创建 SpringBoot工程及入门详解

    SpringBoot 项目创建 创建Module 基于IDEA创建项目Module,模块名为04-springboot-start,组id和包名为com.cy,如图所示: 填写module信息,如图所示: 选择项目module版本,暂时不需要自己手动添加任何依赖,如图所示: 填写Module名称,完成module创建,如图所示 项目结构分析 项目Module创建好以后,其代码结构分析,如图所示: SpringBoot 项目启动分析 启动入口 SpringBoot 工程中由SpringBootAp

  • SpringBoot中的Bean的初始化与销毁顺序解析

    我今天学习到SpringBoot里面自定义Bean的初始化与销毁方法 我先总结一下我学到的四种方法: 方法一: 指定init-method 和 destory-method 方法二: 通过让 Bean 实现 InitializingBean 接口,定义初始化逻辑 DisposableBean 接口,定义销毁逻辑 方法三: 用 @PostConstruct,在 Bean 创建完成并且赋值完成后,执行该注解标注的方法 @PreDestroy,在容器销毁 Bean 之前,执行该注解标注的方法 方法四:

  • 聊聊SpringBoot中组件无法被注入的问题

    目录 SpringBoot中组件无法被注入 1.描述问题 2.解决问题 3.总结问题 解决在@Component注入为null SpringBoot中组件无法被注入 1.描述问题 在SpringBoot中,无法通过注解@AutoWired来自动绑定实体bean或者组件component. 2.解决问题 首先检查自己的是否在实体类上加上了@Component这样的注解,@ComponentScan可以扫描的有@Service.@Repository.@Componnet.@Controller.@

  • 浅谈@PostConstruct不被调用的原因

    目录 @PostConstruct不被调用的原因 如图 @PostConstruct详解 定义 用法 作用 执行顺序 @PostConstruct不被调用的原因 如果在配置文件中配置使用,延迟加载的话 如图 被@Service等注解的类,需要在注入使用的时候,才会被初始化.如果TableInit类只是被定义而没有在其他地方引用的话,@PostConstrut注释的方法是不会执行的. @PostConstruct详解 定义 @PostContruct是Java自带的注解,在方法上加该注解会在项目启

随机推荐