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

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


<img src="/img/d3d8145f830244359f252c2cca9673af.png" width="600" />



### 1、时机点介绍

#### ::new()

即构建函数。是在 Bean 被扫描时，且符合条件才会执行。此时，还未入到容器，<mark>且不能使用注入的字段（还未注入）</mark>。

如果要初始化处理？可以改用构造参数注入，或者使用 `@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）一般的组件

```java
import org.noear.solon.annotation.Component;

@Component
public class DemoCom{

}
```


#### b）按需实现 LifecycleBean 接口的组件

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

```java
import org.noear.solon.annotation.Component;
import org.noear.solon.core.bean.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`：

```java
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Init;

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




