SpringBean生命周期

# 使用场景


  @PostConstruct和@PreDestroy分别作用在Bean的生命周期的开始和结束阶段, 如果想要在容器启动和停止分别处理业务时,应该怎么办?spring提供了org.springframework.context.Lifecycle接口和 org.springframework.context.SmartLifecycle接口;CommandLineRunner由spring boot提供,并且只能在程序启动后织入逻辑,Life可以在应用停止前 写入逻辑。

# org.springframework.context.Lifecycle


方法详解

public interface Lifecycle {
	void start();
	void stop();
	boolean isRunning();
}
1
2
3
4
5

  start方法:org.springframework.context.ConfigurableApplicationContext实现了Lifecycle接口, 容器在启动过程不会调用start方法,只有context#start显式调用才会执行。
  isRunning方法:只有当应用在退出时才会执行isRunning方法,来判断该Lifecycle是否还在执行,如果isRunning返回true, 则会调用stop方法;
  stop方法:当应用退出并且isRunning返回true时,才会调用stop方法.

# org.springframework.context.Lifecycle


方法详解

public interface SmartLifecycle extends Lifecycle, Phased {
	int DEFAULT_PHASE = Integer.MAX_VALUE;
	default boolean isAutoStartup() {
		return true;
	}
	default void stop(Runnable callback) {
		stop();
		callback.run();
	}
	
	@Override
	default int getPhase() {
		return DEFAULT_PHASE;
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

举例实现

@Component
@Slf4j
public class SecondLife implements SmartLifecycle {

    private volatile boolean running;

    /**
     * 作用:打印在log里
     * 默认生命周期处理器会检查实现方法isAutoStartUp返回的bool值
     * 如果为true,则start方法会被调用
     */
    @Override
    public void start() {
        log.info("初始化线程池、开启指定任务、开始异步任务、初始化中间件");
        running = true;
    }

    /**
     * Lifecycle接口中的方法,该方法执行的条件有两个,缺一不可
     * 1.当前这个Component是直接实现Lifecycle而不是SmartLifecycle接口
     * 2.isRunning方法返回true
     */
    @Override
    public void stop() {
        running = false;
    }

    /**
     * 应用启动或者退出都会执行该方法检测是否要执行start或者stop
     * @return
     */
    @Override
    public boolean isRunning() {
        return running;
    }

    /**
     * 如果context调用refresh方法或者容器刚好启动
     * 方法返回值为true时表示自动调用start方法
     * @return
     */
    @Override
    public boolean isAutoStartup() {
        return true;
    }

    /**
     * 如果isRunning返回true则会调用
     * DefaultLifecycleProcessor处理这个stop方法
     * @param callback
     */
    @Override
    public void stop(Runnable callback) {
        callback.run();
    }
    
    /**
     * 启动时返回值小,先执行start
     * 退出时返回值大,先执行stop
     * @return
     */
    @Override
    public int getPhase() {
        return 4;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66