LifecycleBean 接口，是绑定应用上下文（AppContext）的启动与停止的。

* 启动时，Bean 扫描已经结束，可以做一些初始化动作（@Init 函数，与此相当）
* 启动之后，一般开始网络监听与注册
* 停止之前，一般注销网络登记
* 停止时，可以做一些释放动作（@Destroy 函数，与此相当）

它，只对单例有效。非单例时，仅扫描时产生的第一实例会被纳管，其它实例的生命周期会失效（或者自己处理）。当有多个 LifecycleBean 相互依赖时，会自动排序。


| 接口                                  |     对应注解                 | 执行时机                     | 说明     |
| --------------------- | --------------- | ------------------ | ------ |
| `LifecycleBean::start`          |  `@Init`           | `AppContext::start()`          | 启动   |
| `LifecycleBean::postStart`    |                     | 同上     | 启动之后      |
| `LifecycleBean::preStop`      |                      | `AppContext::preStop()`     | 停止之前   |
| `LifecycleBean::stop`           |  `@Destroy`    | `AppContext::stop()`           | 停止      |



### 1、也可使用 `@Init`、`@Destroy` 替代

如果只需要 `LifecycleBean::start`，使用注解 `@Init` 更简洁。一般只做初始化处理。

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

@Component
public class Demo {
    @Init
    public void init(){ //一个无参的函数，名字随便取
    }
}
```

如果只需要 `LifecycleBean::stop`，使用注解 `@Destroy` 更简洁。一般只做注销处理。

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

@Component
public class Demo {
    @Destroy
    public void destroy(){ //一个无参的函数，名字随便取
    }
}
```


### 2、LifecycleBean 的自动排序（v2.2.8 后支持）

自动排序。当 Bean2 依赖 Bean1 注入时。Bean1::start() 会先执行，再执行 Bean2::start()。例：

```java 
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.bean.LifecycleBean;

@Component
public class Bean1 implements LifecycleBean {
    @Override
    public void start(){
        //db1 init ...
    }
    
    public void func1(){
        //db1 call
    }
}

@Component
public class Bean2 implements LifecycleBean {
    @Inject 
    Bean1 bean1;
    
    @Override
    public void start(){
        bean1.func1();
    }
}
```

有时候 Bean1 和 Bean2 可能并没有直接的依赖关系。也是可以通过注入，形成依赖关系，让执行自动排序（这个可称为"小技巧"）


### 3、LifecycleBean 自动排序引起的循环依赖问题

因为自动排序是基于注入的依赖关系来确定的。当相互依赖时就会傻掉（异常提示）。像这样：

```java 
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.bean.LifecycleBean;

@Component
public class Bean1 implements LifecycleBean{
    @Inject 
    Bean2 bean2;
    
    @Override
    public void start(){
    }
}

@Component
public class Bean2 implements LifecycleBean{
    @Inject 
    Bean1 bean1;
    
    @Override
    public void start(){
    }
}
```

要么取消相互依赖。要么手工指定顺序位：

```java 
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.bean.LifecycleBean;

@Component(index = 1)
public class Bean1 implements LifecycleBean{
    @Inject 
    Bean2 bean2;
    
    @Override
    public void start(){
    }
}

@Component(index = 2)
public class Bean2 implements LifecycleBean{
    @Inject 
    Bean1 bean1;
    
    @Override
    public void start(){
    }
}
```



### 附：AppLoadEndEvent （即，应用启动完成）

如果初始化时，有些依赖的 Bean 未准备就绪（比如，有些 bean 是在初始化时，才产生的）。可以使用 AppLoadEndEvent 事件：

```java
import org.noear.solon.annotation.Component;
import org.noear.solon.core.event.AppLoadEndEvent;
import org.noear.solon.core.event.EventListener;

//注解模式
@Component
public class AppLoadEndListener implements EventListener<AppLoadEndEvent>{
    @Override
    public void onEvent(AppLoadEndEvent event) throws Throwable {
        //db1 init ...
    }
}
```

