AppContext 是 Solon 框架的核心组件，是 Ioc/Aop 特性实现载体；是热插拨特性的实现基础。

### 1、主要用途

* 管理托管对象
* 提供注解处理的注册与应用

### 2、三种获取方式

方式一：获取全局的（直接拿：`Solon.context()`）

```java
import org.noear.solon.Solon;

public class DemoClass{
    UserService userService;
    
    public void demo(){
        Solon.context().getBeanAsync(UserService.class, bean->{
            userService = bean;
        });
    }
}
```


方式二：获取当前组件的（注入）

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

@Component
public class DemoComponent{
    @Inject
    AppContext context; 
}
```

方式三：获取当前插件的（生命周期开始处）

```java
import org.noear.solon.core.AppContext;
import org.noear.solon.core.Plugin;

public class DemoPlugin implements Plugin{
    @Override
    public void start(AppContext context) {
        //...
    }
}
```

### 3、相关接口

* 注解处理相关（用于自定义注解开发）

| 接口 | 相关说明 | 
| -------- | -------- | 
| -beanBuilderAdd(anno, builder)     | 添加构建“注解”处理     | 
| -beanBuilderAdd(anno, targetClz, builder)     | 添加构建“注解”处理（按类型选择处理）     | 
| -beanInjectorAdd(anno, injector)     | 添加注入“注解”处理     | 
| -beanInjectorAdd(anno, targetClz, injector)     | 添加注入“注解”处理（按类型选择处理）     | 
| -beanExtractorAdd(anno, extractor)     | 添加提取“注解”处理     | 
| -beanExtractorHas(anno)     | 检查提取“注解”处理，是否有？     | 
| -beanInterceptorAdd(anno, interceptor)     | 添加拦截“注解”处理     | 
| -beanInterceptorAdd(anno, interceptor, index)     | 添加拦截“注解”处理     | 
| -beanInterceptorGet(anno)     | 获取拦截“注解”处理     | 


* 自动装配相关

| 接口 | 相关说明 | 
| -------- | -------- | 
|  -beanScan(source)    |   扫描源下的所有 bean 及对应处理   | 
|  -beanScan(basePackage)    |  扫描包下的所有 bean 及对应处理    | 
|  -beanScan(classLoader, basePackage)    |  扫描包下的所有 bean 及对应处理    | 
|  -beanMake(clz)->BeanWrap    |   制造 bean 及对应处理   | 


* 手动注入相关


| 接口 | 相关说明 | 
| -------- | -------- | 
| -beanInject(bean)  |  为一个对象注入    | 
| -beanInject(varHolder, name)     | 尝试变量注入 字段或参数     | 
| -beanInject(varHolder, name, autoRefreshed)     | 尝试变量注入 字段或参数     | 


* 手动包装相关


| 接口 | 相关说明 | 
| -------- | -------- | 
| -wrap(type)->BeanWrap     | 包装 bean     | 
| -wrap(type, bean)->BeanWrap     | 包装 bean     | 
| -wrap(type, bean, typed)->BeanWrap     | 包装 bean     | 
| -wrap(name, bean)->BeanWrap     | 包装 bean     | 
| -wrap(name, bean, typed)->BeanWrap     | 包装 bean     | 
| -wrap(name, type)->BeanWrap     | 包装 bean。v3.0 后支持     | 
| -wrap(name, type, typed)->BeanWrap     | 包装 bean。v3.0 后支持     | 
| -wrapAndPut(type)->BeanWrap     | 包装 bean 并推入容器     | 
| -wrapAndPut(type, bean)->BeanWrap     | 包装 bean 并推入容器     | 
| -wrapAndPut(type, bean， typed)->BeanWrap     | 包装 bean 并推入容器     | 
| -wrapAndPut(name, bean)->BeanWrap     | 包装 bean 并推入容器。v3.0 后支持      | 
| -wrapAndPut(name, bean, typed)->BeanWrap     | 包装 bean 并推入容器。v3.0 后支持      | 
|      |      | 
| -putWrap(name, wrap)     | 推入到bean库（与 getWrap 相对应）     | 
| -putWrap(type, wrap)     | 推入到bean库（与 getWrap 相对应）     | 
|      |      | 
| -hasWrap(nameOrType)     | 是否有bean包装（与 getWrap 相对应）     | 
|      |      | 
| -beanRegister(wrap, name, typed)     | 注册 beanWrap（相当于 putWrap 的复杂版）     | 
| -beanDeliver(wrap)     | 交付 beanWrap（把特殊接口，转给相关管理器）     | 
| -beanPublish(wrap)     | 发布 beanWrap（可触发类型订阅，如：subWrapsOfType）     | 

* 获取与订阅相关


| 接口 | 相关说明 | 
| -------- | -------- | 
| -getWrap(nameOrType)->BeanWrap     | 获取bean包装     | 
| -getWrapsOfType(baseType)                  | 获取某类型的 Bean 包装      | 
| -getWrapAsync(nameOrType, callback)     | 异步获取bean包装（可实时接收）     | 
| -subWrapsOfType(baseType, callback)     | 订阅某类型的 Bean 包装（可实时接收）     | 
|      |      | 
| -getBean(name)->Object     | 获取 Bean     | 
| -getBean(type)->T     | 获取 Bean     | 
| -getBeansOfType(baseType)->List[T]     | 获取某类型的 Bean     | 
| -getBeansMapOfType(baseType)->Map[String,T]     | 获取某类型带名字的 Bean    | 
| -getBeanOrNew(type)     | 获取 Bean，或者新建     | 
| -getBeanAsync(name, callback)     | 异步获取 Bean（可实时接收）     | 
| -getBeanAsync(type, callback)     | 异步获取 Bean（可实时接收）      | 
| -subBeansOfType(baseType, callback)     | 订阅某类型的 Bean（可实时接收）      | 



* 遍历与查找相关（要注意时机点）

| 接口 | 相关说明 | 
| -------- | -------- | 
| -beanForeach((name, wrap)->{})     |  遍历bean包装库    | 
| -beanForeach((wrap)->{})     |  遍历bean包装库    | 
|      |      | 
| -beanFind((name, wrap)->bool)->List[BeanWrap]     |   查找bean包装库   | 
| -beanFind((wrap)->bool)->List[BeanWrap]     |   查找bean包装库   | 


* 绑定生命周期相关


| 接口 | 相关说明 | 
| -------- | -------- | 
|  -lifecycle(lifecycleBean)    |   添加生命周期bean（即获得容器的生命事件）   | 
|  -lifecycle(index, lifecycleBean)    |   添加生命周期bean（即获得容器的生命事件）   | 


### 4、带与不带 OfType 方法的区别（baseType 与 type 的区别）


| 带 OfType 的几方法                    |  对应的方法（不带 OfType 的）                 | 
| -------------------------- | ----------------- | 
| `getWrapsOfType(baseType)->List[T]`        | `getWrap(type)->T`     | 
| `subWrapsOfType(baseType, callback)`        | `getWrapAsync(type)`     | 
| `getBeansOfType(baseType)->List[T]`         | `getBean(type)->T`     | 
| `subBeansOfType(baseType, callback)`.       | `getBeanAsync(type)`     | 
| `getBeansMapOfType(baseType)`                | /                              | 


区别在于参数的不同（基于“克制”原则，按需选择）：

* baseType，表示基类。通过基类匹配获取 `一批`；对应的方法都带有 `s`，表过多个。
  * 可以获取多个，但性能会差些。
* type，表过本类。通过 hash_code 匹配获得 `单个`。
  * 可以速度更快，但只获取一个。


### 5、订阅接口的限制说明

* subBeansOfType、subWrapsOfType
 
```java
默认情况下，@Bean 或 @Component 产生的 Bean 会自动“发布”。否则需要手动调用发布方法（beanPublish）。
```


