项目链接:https://gitcode.com/Cangjie-SIG/fountain
本篇介绍使用fountain开发的应用项目如何启动和初始化。
fountain提供了一个子项目fboot,开发者可以借助fboot初始化应用项目。具体是以下两个命令:
1.fboot workspace [project_name]
- 在当前目录用project_name创建新的文件夹,并用它创建一个workspace项目。
- 如果没有指定project_name则在当前目录创建workspace项目
- 为新建项目添加fountain的git依赖、stdx二进制依赖、在[workspace]下面添加version="1.0.0"节点。
为新项目的compile-option、override-compile-option节点添加-O2 --dy-std的参数。
为[target]以及[target.x86-64-unknown-linux-gnu]等各操作系统和指令集的[target.*]节点下面的compile-option、override-compile-option添加-O2 --dy-std参数。
为[target.x86-64-unknown-linux-gnu]额外添加--lto=ful编译参数。
2.fboot module [module_name]
- 在当前目录用module_name创建新的文件夹,并用它创建一个动态链接库子项目作为workspace的模块。
- 在主项目[workspace]的members节点添加模块依赖。
为了使用以上命令,可以在fountain/fboot执行cjpm install --root /path/of/fountain/installed,并把/path/of/fountain/installed/bin添加到PATH环境变量,把/path/of/fountain/installed/libs/fboot添加到LD_LIBRARY_PATH。开发者可以参考fountain/cangjie.sh和fountain/fdemo/boot.sh开发符合项目需要的脚本。
如果项目依赖数据库建议创建一个模块,在模块内创建一个匿名的闭包,在闭包内初始化ORM。比如有以下初始化方式:
import opengauss.driver.*
import opengauss.slog
private let _ = {=>
try{
let logger = LoggerFactory.getLogger("opengauss")
slog.setDefault(logger)
let driver = DriverManager.getDriver("opengauss").getOrThrow()
ORM.register(driver)//ORM会从配置项获得数据库连接URL和其它配置项。
}catch(e: Exception){
e.printStackTrace()
throw e
}
}()
还有更简单的初始化:
import opengauss.driver.*//这个导入不能少,否则数据库驱动就不会初始化了
import opengauss.slog
private let _ = {=>
try{
let logger = LoggerFactory.getLogger("opengauss")
slog.setDefault(logger)
ORM.register('opengauss')//ORM会从配置项获得数据库连接URL和其它配置项。
}catch(e: Exception){
e.printStackTrace()
throw e
}
}()
在初始化脚本增加环境变量:
export orm_pooledDatasourceMaxSize=1
export orm_pooledDatasourceMaxIdleSize=1
export orm_pooledDatasourceIdleTimeout=86400
export orm_stdPoolMaxLifeTime=86400
export orm_pooledDatasourceConnectionTimeout=86400
export orm_pooledDatasourceKeepaliveTime=86400
# 以上是数据库连接池的初始化参数
# orm_transactionalFuncExecution 和@Transactional注解只要有一个生效就会将事务切面织入到函数
export orm_transactionalFuncExecution='*..*.delete*(**): *|*..*.remove*(**): *|*..*.save*(**): *|*..*.add*(**): *|*..*.new*(**): *|*..*.create*(**): *|*..*.insert*(**): *|*..*.update*(**): *|*..*.change*(**): *|*..*.register*(**): *'
export opengauss_orm_connectionUrl=$POSTGRES # 数据库驱动的初始化URL
if [[ "$path" == "" ]]; then
path='./fdemo'
fi
export LD_LIBRARY_PATH=$path/release/boot:$path/release/opengauss:$path/release/user:$LD_LIBRARY_PATH
# pattern可省略,有默认值
# %level 记录当前日志级别
# %name 记录当前日志名称
# %d 记录当前日志时间,花括号内是时间格式
# %m 记录当前日志消息文本
# 日志配置项的名字跟日志实例的名字不同,这些名字仅在用配置初始化时有用
export logger_appender_console=FDemoConsole # 为控制台日志配置项起个名字,可以用,指定多个控制台日志配置
export logger_appender_FDemoConsole_level=DEBUG # 为这个控制台配置指定日志级别
# 控制台日志的格式
export logger_appender_FDemoConsole_pattern='[%level-%name]%d{yyyy/MM/dd,HH:mm:ss.SSS}|%tid;%m'
export logger_appender_file=FDemoFile # 为文件日志的配置项起个名字。
export logger_appender_FDemoFile_level=INFO
export logger_appender_FDemoFile_pattern='[%level-%name]%d{yyyy/MM/dd,HH:mm:ss.SSS}|%tid;%m'
export logger_appender_FDemoFile_path=./log/fdemo.log # 日志文件的路径和文件名
export logger_appender_FDemoFile_rotateDuration=DAY # 日志文件的切分周期
# 以上是日志初始化参数
export mvc_port=8080 # 这一行可以没有,默认就是8080
export mvc_overallElapsedSwitch=true # 是否记录从路径查询handler开始到完全写出响应体的耗时
export mvc_internalServerErrorMessageKind=BEAN # 应用项目处理HTTP请求时如果发生异常,处理异常的类型,这个配置表示ErrorMessage是一个IOC bean name
export mvc_internalServerErrorMessage=NameOf500Handler
接下来可以按照业务划分不同的模块,模块内可以按照controller、service、service.impl、dao、util等创建包名,比如以下名为user的模块:

为了方便开发者编译和启动项目可以使用以下命令:
- fboot build——将当前工作目录作为待编译的项目目录。编译时会创建一个project_name_stAtIc__模块,读出[workspace]的version节点的值,并把project_name/banner.txt一起写入这个模块,把模块添加到members=[...]。编译结束,不论成功失败都会删除这个临时模块。
- fboot run --dylibPattern='(boot|user\.util\.auth|\.(controller|service\.impl))'——启动应用项目。递归遍历将当前目录内的全部动态链接库,--dylibPattern是应用启动时需要主动加载的动态链接库,启动时会使用PackageInfo.load(path)动态加载这些动态链接库。启动前需要把编译结果的动态链接库路径加入LD_LIBRARY_PATH。
- fboot cleanUpdate——执行cjpm clean清除当前目录的编译结果、删除当前目录下的cjpm.lock并重新执行cjpm update。
- fboot count——计数当前目录下的仓颉代码模块数、包数、文件数、行数。
能做到以上功能,是因为fboot是以下代码:
import fountain.App
main(args: Array<String>){
App(args).boot()
}
fboot的每个子命令都是fountain.App的一个函数:
public func boot(): Int64 {
match (args[0]) {
case 'run' => run()
case 'shutdown' => shutdown()
case 'restart' => restart()
case 'module' => initModule()
case 'workspace' => initWorkspace()
case 'cleanUpdate' => cleanUpdate()
case 'build' => build()
case 'test' => test()
case 'count' => count()
case 'version' => version()
case 'help' => help()
case _ => throw BootException(
'first command arg must be run|shutdow|restart|module|workspace|cleanUpdate|build|count|version, but current args are ${args}')
}
}

被折叠的 条评论
为什么被折叠?



