本篇文章我们将关注jfinal中的核心组件之
Plugin
。
1. 概述
相比较于其他核心组件,jfinal对Plugin的处理可谓是相当简洁了。这一点从Plugin组件的核心接口IPlugin
的定义中可见一斑。
2. 定义
/**
* IPlugin
*/
public interface IPlugin {
boolean start();
boolean stop();
}
- 对于Plugin,jfinal给予了足够的地位——顶级package
com.jfinal.plugin
。 - 需要注意到的一点就是plugin机制中,jfinal在其中只负责plugin的启动和停止,具体的实现逻辑,以及plugin的应用则是完全交由外界来自主决定。
- 另外观察
com.jfinal.plugin
包结构也能察觉出jfinal对plugin的组织方式以及设计思路。而且从这个package结构也可以看出,一般的项目基本上也就这么几个需求。(其中auth中还没有完成,看思路应该是自定义Session的构建)。
3. 继承链
看完了定义,接下来我们按照之前的习惯来看看Plugin的继承链体系。
3.1 ActiveRecordPlugin
作为 JFinal 最核心的组成部分之一的ActiveRecord 正是由这个Plugin启动的,重要性就不言而喻了。
public boolean start() {
if (isStarted) {
return true;
}
// 配置数据源
if (config.dataSource == null && dataSourceProvider != null) {
config.dataSource = dataSourceProvider.getDataSource();
}
if (config.dataSource == null) {
throw new RuntimeException("ActiveRecord start error: ActiveRecordPlugin need DataSource or DataSourceProvider");
}
// 解析jfinal 3.0起加入的sql 管理模块
config.sqlKit.parseSqlTemplate();
// build the mapping of model between class and table
new TableBuilder().build(tableList, config);
DbKit.addConfig(config);
isStarted = true;
// 返回true, 告知jfinal本Plugin启动成功
return true;
}
3.2 C3p0Plugin / DruidPlugin / HikariCpPlugin
把这三个Plugin都是数据库连接池工具。核心逻辑就是DataSource实例的构建。
3.3 EhCachePlugin/ RedisPlugin
缓存实现。
3.3 Cron4jPlugin
定时任务实现。本类上的官方文档上有详细的使用说明,使用者都不用百度了。
4. 生命周期
最后让我们看看plugin是如何融入jfinal的生命周期中的。
4.1 启动
JFinalFilter.init
>> JFinal.init
>> Config.configJFinal(jfinalConfig)
>> Config.configPluginWithOrder(1, jfinalConfig);
>> Config.startPlugins(); 【jfinal会依据用户配置(constants.setConfigPluginOrder()),在不同的 JFinalConfig.configXxxx之前启动Plugin。】
4.2 停止
JFinalFilter.destroy
>> jfinal.stopPlugins()
5. 总结
jfinal在框架层面对于Plugin的处理,只负责回调plugin的启动和停止;具体的实现逻辑,以及plugin的应用则是完全交由外界来完成。
极少的强制契约,使得Plugin拥有非常强大的灵活性来满足各种项目上的自定义需求。