源码:j-spring TS的spring.
前言
启动器的设计为了协调后期各个模块间的异步启动顺序,目前以顺序启动主要为了方便调试,后期可以优化成分批并行启动。
自己先记录下,回头看一遍快速熟悉逻辑,方便优化。
实现
1.接口
springFactory.ts
首先在工厂实例化一个启动器存储集合
//实例化的启动的bean
export const starterBeanList = new Set<SpringStarter>();
export interface SpringStarter {
isSpringStater():boolean;
//启动
doStart():Promise<any>;
}
function isSpringStarter(bean:any):boolean {
const starter = bean as SpringStarter;
return isFunction(starter.doStart) && isFunction(starter.isSpringStater) && starter?.isSpringStater();
}
2.添加实例化的启动器
在工厂装配方法结束后,判断该实例是否满足SpringStarter接口要求。如果是放入启动器集合。
if(isSpringStarter(bean)){
starterBeanList.add(bean);
}
3.运行时顺序执行启动器
export async function invokeStarter():Promise<any>{
const starterBeanArray = Array.from(starterBeanList);
for (let index = 0; index < starterBeanArray.length; index++) {
const element = starterBeanArray[index];
await element.doStart()
}
}
export async function launchAsync(clazz:Clazz,args?:any[]):Promise<any> {
const bootApp = getBootAppBean(clazz);
await invokeStarter();
return bootApp.main.apply(bootApp,args||[])
}
export function launch(clazz:Clazz,args?:any[]){
const bootApp = getBootAppBean(clazz);
if(starterBeanList.size > 0){
throw Error(`found starter bean.please use asyncLaunch method!`)
}
return bootApp.main.apply(bootApp,args||[])
}
- 调用launch同步启动函数,如果检测到存在异步启动器则报错
- 调用launchAsync会先按照装载顺序执行异步启动器
测试用例
模拟持久层和web服务器启动
it('run starter applicaiton by spring and inject more starter ',()=>{
spring.clear();
@Component
class Db implements SpringStarter{
isConnect:string = 'db no';
isSpringStater(): boolean {
return true;
}
async doStart(): Promise<any> {
this.isConnect = 'db ok'
}
}
@Component
class Server implements SpringStarter{
isStart:string = 'server no';
isSpringStater(): boolean {
return true;
}
async doStart(): Promise<any> {
this.isStart = 'server ok'
}
}
@Component
class Application {
@Autowired({clazz:Db})
db:Db;
@Autowired({clazz:Server})
server:Server;
value = 1;
main(){
return `${this.db.isConnect} ${this.server.isStart}`
}
}
launchAsync(Application).then(v => expect(v).toBe(`db ok server ok`))
})