插件扩展机制，是基于 “插件” + “配置声明” 实现的解耦的扩展机制（**类似 Spring Factories、Java Spi**）：简单、弹性、自由。它的核心作用，是为模块获得了应用启动入口，并参与了应用生命周期。简称为 Solon Spi。

我们将一些可复用的能力，独立为一个“插件”。比如像 `@Transaction`、`@Cache` 之类的注解能力，肯定是希望在所有项目中复用，它们的能力实现就会被封装成一个插件。


### 1、插件扩展机制的实现介绍

建议把插件的实现类，放到 `integration` 包下面，且以 `SolonPlugin` （或者 `Plugin`）结尾。


* 第一步：定制“插件实现类”（即实现插件生命周期的内部处理），实现类不能有注入。


```java
package demo.integration;

public class DemoSolonPlugin implements Plugin{
    @Override
    public void start(AppContext context) {
        //插件启动时...
    }
    
    @Override
    public void prestop() throws Throwable {
        //插件预停止时（启用安全停止时：预停止后隔几秒才会进行停止）
    }
    
    @Override
    public void stop(){
        //插件停止时
    }
}
```


* 第二步：通过“插件配置文件”声明自己，<mark>文件名须全局唯一存在</mark>

约定插件配置文件：

```
#建议使用包做为文件名，便于识别，且可避免冲突
META-INF/solon/{packname}.properties
```

约定插件配置内容：
```properties
#插件实现类配置
solon.plugin={PluginImpl}  
#插件优化级配置。越大越优先，默认为0
solon.plugin.priority=1
```
  

* 第三步：扫描并发现插件

程序启动时，扫描`META-INF/solon/`目录下所有的`.properties`文件，找到所有的插件并排序。

### 2、插件的排除

如果引入很多 maven 插件包，但想排除某个插件。可使用:

* 配置方式

```yaml
solon.plugin.exclude:
  - "{PluginImpl}"
```

* 编码方式

```java
public class App {
    public static void main(String[] args){
        Solon.start(App.class, args, app -> {
            app.pluginExclude(PluginImpl.class);
        });
    }
}
```

### 3、插件包的命名规范

| 插件命名规则                             | 说明          |
|--------------------------------|-------------|
| `solon-*（由 solon.* 调整而来）`      | 表示内部架构插件    |
| `*-solon-plugin（保持不变）`         | 表示外部适配插件    |
| `*-solon-ai-plugin（保持不变）`   | 表过智能体（AI）接口外部适配插件 |
| `*-solon-cloud-plugin（保持不变）`   | 表过分布式（Cloud）接口外部适配插件 |


插件实现类命名建议：XxxSolonPlugin（例，GritSolonPlugin）


### 4、示例参考，插件：solon-data （只是示例！！！）

这个插件提供了 `@Transaction` 注解的能力实现，进而实现事务的管理能力。

* 插件实现类：`src/main/java/org.noear.solon.data.integration.DataSolonPlugin.java`

```java
public class DataSolonPlugin implements Plugin {
    @Override
    public void start(AppContext context) {
        if (Solon.app().enableTransaction()) {
            context.beanInterceptorAdd(Tran.class, new TranInterceptor(), 120);
        }
    }
}

```

* 插件配置文件：`src/main/resources/META-INF/solon/solon.data.properties`

```properties
solon.plugin=org.noear.solon.data.integration.DataSolonPlugin
solon.plugin.priority=3
```


* 插件应用示例

```java
//
// 引入 org.noear:solon.data 插件之后
//
@Component
public class AppService {
    @Inject
    AppMapper appMapper;

    @Transaction
    public void addApp(App app){
        appMapper.add(app);
    }
}
```






