前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

1、引入

在使用Spring 开发时,我们都知道,所有bean都交给 Spring 容器来统一管理,其中包括每一个bean的加载和初始化。

有时候我们需要在Spring 加载和初始化所有 bean 后,接着执行一些任务或者启动需要的异步服务,这样我们可以使用 SmartLifecycle 来做到。

这个和 @PostConstruct@PreDestroybean 的初始化和销毁方法不同,Bean生命周期级别和容器生命周期级别在应用场景上是有区别的。

SmartLifecycle 是一个接口。当Spring容器加载所有bean并完成初始化之后,会接着回调实现该接口的类中对应的方法(start()方法)。

1.1、样例

package com.sankuai.windmill.riding.mafka.consumer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicBoolean;


@Slf4j
@Component
public class ConsumerSmartLifecycle implements SmartLifecycle {

  private AtomicBoolean isRunning = new AtomicBoolean(false);

  /**
     * 作用:启动任务或者其他异步服务,比如开启MQ接收消息
     * 调用时机:
     * 1、当上下文被刷新(所有对象已被实例化和初始化之后)时,将调用该方法
     * 2、默认生命周期处理器将检查每个SmartLifecycle对象的isAutoStartup()方法返回的布尔值(默认为true)。如果为“true”,则该方法会被调用,而不是等待显式调用自己的start()方法。
     */
  @Override
  public void start() {
    // 保证之初始化一次
    if (!isRunning.compareAndSet(false, true)) {
      return;
    }

    //TODO someThing

  }

  /**
     * 作用: 如果工程中有多个实现接口SmartLifecycle的类,则这些类的start的执行顺序按getPhase方法返回值从小到大执行。
     * 例如: 1比2先执行,-1比0先执行。 stop方法的执行顺序则相反,getPhase返回值较大类的stop方法先被调用,小的后被调用。(也就是说start先开始的后结束)
     * 是否重写:不一定 接口中有提供默认值
     */
  @Override
  public int getPhase() {
    return 0;
  }

  /**
     *
     * 作用:根据该方法的返回值决定是否执行start方法。
     * 使用:返回true时start方法会被自动执行,返回false则不会。
     * 是否重写:不一定,默认是true
     */
  @Override
  public boolean isAutoStartup() {
    return true;
  }


  /**
     * 1. 只有该方法返回false时,start方法才会被执行。
     * 2. 只有该方法返回true时, stop(Runnable callback)或stop()方法才会被执行。
     */
  @Override
  public boolean isRunning() {
    return isRunning.get();
  }



  /**
     * 说明:当isRunning方法返回true时,该方法才会被调用。
     * 时机:容器关闭后:
     * 1、如果容器里当前对象实现了SmartLifecycle接口,则调用stop ( Runnable );
     * 2、如果只实现了LifeCycle,就调用stop ( )
     */
  @Override
  public void stop() {
    try {
      // TODO close some source
    } catch (Exception e) {
      log.info("[ConsumerSmartLifecycle]========error", e);
    } finally {
      isRunning.set(false);
    }
  }

  /**
     * 说明:当isRunning方法返回true时,该方法才会被调用。
     * 时机:容器关闭后:
     * 1、如果容器里当前对象实现了SmartLifecycle接口,则调用stop ( Runnable );
     * 2、如果只实现了LifeCycle,就调用stop ( )
     */
  @Override
  public void stop(Runnable callback) {
    try {
      // TODO close some source
    } catch (Exception e) {
      log.info("[ConsumerSmartLifecycle]========error", e);
    } finally {
      isRunning.set(false);
    }
  }
}

ContactAuthor