插件体外扩展机制，简称：E-Spi。用于解决 fatjar 模式部署时的扩展需求。比如：

* 把一些“业务模块”做成插件包放到体外
* 把数据源配置文件放到体外，方便后续修改


其中， .properties 或 .yml 文件都会做为扩展配置加载，.jar 文件会做为插件包加载。


### 1、特点说明

* 所有插件包 “共享” ClassLoader、AppContext、配置
* 可以打包成一个独立的插件包（放在体外加载），也可以与主程序一起打包。“分”或“合”自由！
* 更新体外插件包或配置文件后，需要重启主服务
* E-Spi 是由内核直接提供的支持，不需要其它依赖
* 一起打包的插件，区别不大。加载时机一样

### 2、关于 ClassLoader 共享

（E-Spi）是基于 `AppClassLoader:addJar(URL | File)` 实现。启动时，框架会自动加载配置的扩展目录下：

* 所有 `.jar` 和 `.zip` 包（有些应用会打包成 zip 文件）
* 及所有 `.properties` 和 `.yml` 配置文件。

也可以直接使用接口，自由加载包和属性文件，完成（E-Spi）：

```java
@SolonMain
public class Application {
    public static void main(String[] args) throws Exception {
        Solon.start(Application.class, args, app -> {
            //加载包文件
            app.classLoader().addJar(new File("/demo.jar")); 
            
            //加载属性文件
            app.cfg().loadAdd(new File("/demo.yml"));
        });
    }
}
```


### 3、操作说明

* 应用属性文件添加扩展目录配置

目录需要手动创建

```yml
#声明扩展目录为 demo_ext（没有时，不会异常）
solon.extend: "demo_ext"
```

也可以，目录自动创建。不同的场景可以不同选择
```yml
#声明扩展目录为 demo_ext（加!开头，表示自动创建）
solon.extend: "!demo_ext"
```


* 文件放置关系

将一个应用的数据源配置放在扩展目录，以便后续修改，部署效果：

```
demo.jar
demo_ext/_db.properties
```

再将一个用户频道或者领域模块做为插件包，部署效果：

```
demo.jar
demo_ext/_db.properties
demo_ext/demo_user.jar
demo_ext/demo_order.jar 
```

### 4、插件包注意事项

* 要么把插件包打成 fatjar（使用 [《maven-assembly-plugin 打胖包》](/article/306) ）
* 要么把插件包的依赖打进主应用里，特别的是公共的依赖（推荐）

最好，是把公共依赖放到主应用打包。在插件 pom.xml 里标为可选。

### 5、具体示例

[demo2002-external_ext](https://gitee.com/noear/solon-examples/tree/main/2.Solon_Advanced/demo2002-external_ext)




