Solon v3.0.3

三、Bean 生命周期

</> markdown

被容器托管的 Bean,它的生命周期只限定在容器内部:

时机点说明补充
AppContext::new() 是在应用初始化时执行
::new()AppContext::beanScan() 时,符合条件的才构造此时,未登记到容器
@Inject开始执行注入之后,登记到容器。并“通知”订阅者
::登记到容器;并发布通知;订阅它的注入会被执行
start()
或 @Init
AppContext::start() 时执行。根据依赖关系自动排序
//需要实现 LifecycleBean 接口
自动排序,v2.2.8 后支持
postStart()同上v2.9 后支持
preStop()AppContext::preStop() 时执行
//需要实现 LifecycleBean 接口
v2.9 后支持
stop()
或 @Destroy
AppContext::stop() 时执行
//需要实现 LifecycleBean 接口
v2.2.0 后支持

1、时机点介绍

::new()

即构建函数。是在 Bean 被扫描时,且符合条件才会执行。此时,还未入到容器,且不能使用注入的字段(还未注入)

如果要初始化处理?可以改用构造参数注入,或者使用 @Init 函数(推荐)。

@Inject

开始执行注入。之后就会“登记”到容器,并“通知”订阅者。

start() 或 @Init //用来做初始化动作

AppContext::start() 时被执行。其中 start() 需要 实现 LifecycleBean 接口。此时 Bean 扫描已完成,一般的 Bean 都已进入容器。理论上:

  • 所有的 Bean 都已产生
  • 所有 Bean 的字段,都已完成注入

偶有些 Bean 是在 AppContext.start() 时才生产的,例外!

postStart() //开始之后

AppContext::start() 时被执行。属于开始的后半段,一般用于启动一些任务(不能再构造新的托管对象出来)。

preStop() //预停止

AppContext::preStop() 时被执行。一般用来做分布式服务注销之类。属于安全停止的前半段。

stop() 或 @Destroy //用来做释放动作

AppContext::stop() 时被执行。也就是容器停止时被执行。时机点,比插件的 stop() 要晚一点。

2、应用

a)一般的组件

@Component
public class DemoCom{

}

b)按需实现 LifecycleBean 接口的组件

这个接口,只对单例有效。非单例,仅扫描时产生的实例会被纳管。其它实例的生命周期要自己处理。

@Component
public class DemoCom implements LifecycleBean{
    @Override
    public void start(){
        //在 AppContext:start() 时被调用。此时所有bean扫描已完成,一般做些初始化工作
    }
    
    @Override
    public void postStart(){
        //在 AppContext:postStart() 时被调用。禁止再动态产生 bean,一般做些远程服务启动
    }
    
    @Override
    public void preStop(){
        //在 AppContext:preStop() 时被调用。一般做些远程注销
    }
    
    @Override
    public void stop(){
        //在 AppContext:stop() 时被调用。一般做些本地释放或停止类的工作
    }
}

如果只需要 start(),也可以使用注解 @Init

@Component
public class DemoCom {
    @Init
    public void start(){ //一个无参的函数,名字随便取
        //在 AppContext:start() 时被调用。此时所有bean扫描已完成,订阅注入已完成
    }
}