@fastcar/core 0.2.63 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +5 -2
  2. package/annotation.d.ts +3 -0
  3. package/index.d.ts +57 -50
  4. package/package.json +4 -4
  5. package/src/FastCarApplication.ts +184 -123
  6. package/src/annotation/Application.ts +3 -1
  7. package/src/annotation/bind/AddInjectionService.ts +17 -0
  8. package/src/annotation/bind/AddRequireModule.ts +1 -1
  9. package/src/annotation/bind/AliasInjection.ts +8 -15
  10. package/src/annotation/bind/Autowired.ts +1 -1
  11. package/src/annotation/bind/CallDependency.ts +7 -17
  12. package/src/annotation/bind/DemandInjection.ts +16 -0
  13. package/src/annotation/stereotype/Log.ts +13 -9
  14. package/src/annotation/stereotype/Value.ts +5 -0
  15. package/src/annotation.ts +2 -0
  16. package/src/constant/FastCarMetaData.ts +2 -0
  17. package/src/model/WinstonLogger.ts +1 -1
  18. package/src/type/ClassConstructor.ts +5 -0
  19. package/src/type/ComponentDesc.ts +13 -0
  20. package/src/type/FileHotterDesc.ts +6 -0
  21. package/src/utils/ClassLoader.ts +2 -1
  22. package/src/utils/ValidationUtil.ts +1 -1
  23. package/target/FastCarApplication.js +764 -708
  24. package/target/annotation/Application.js +46 -45
  25. package/target/annotation/ExceptionMonitor.js +16 -16
  26. package/target/annotation/bind/AddInjectionService.js +16 -0
  27. package/target/annotation/bind/AddRequireModule.js +21 -21
  28. package/target/annotation/bind/AliasInjection.js +19 -23
  29. package/target/annotation/bind/Autowired.js +13 -13
  30. package/target/annotation/bind/CallDependency.js +16 -23
  31. package/target/annotation/bind/DemandInjection.js +15 -0
  32. package/target/annotation/data/DBType.js +11 -11
  33. package/target/annotation/data/DS.js +54 -54
  34. package/target/annotation/data/DSIndex.js +9 -9
  35. package/target/annotation/data/Entity.js +10 -10
  36. package/target/annotation/data/Field.js +18 -18
  37. package/target/annotation/data/PrimaryKey.js +9 -9
  38. package/target/annotation/data/SqlSession.js +9 -9
  39. package/target/annotation/data/Table.js +35 -35
  40. package/target/annotation/data/Transactional.js +52 -52
  41. package/target/annotation/env/ApplicationSetting.js +25 -25
  42. package/target/annotation/env/BaseFilePath.js +14 -14
  43. package/target/annotation/env/BaseName.js +9 -9
  44. package/target/annotation/env/BasePath.js +14 -14
  45. package/target/annotation/env/ENV.js +10 -10
  46. package/target/annotation/env/ResourcePath.js +9 -9
  47. package/target/annotation/lifeCycle/AddLifeCycleItem.js +17 -18
  48. package/target/annotation/lifeCycle/ApplicationDestory.js +15 -15
  49. package/target/annotation/lifeCycle/ApplicationInit.js +15 -15
  50. package/target/annotation/lifeCycle/ApplicationRunner.js +7 -7
  51. package/target/annotation/lifeCycle/ApplicationStart.js +24 -24
  52. package/target/annotation/lifeCycle/ApplicationStop.js +20 -20
  53. package/target/annotation/property/Deprecate.js +19 -19
  54. package/target/annotation/property/NotImplemented.js +8 -8
  55. package/target/annotation/property/Override.js +7 -7
  56. package/target/annotation/property/Readonly.js +16 -16
  57. package/target/annotation/scan/ComponentInjection.js +21 -21
  58. package/target/annotation/scan/ComponentScan.js +9 -9
  59. package/target/annotation/scan/ComponentScanExclusion.js +25 -25
  60. package/target/annotation/scan/ComponentScanMust.js +25 -25
  61. package/target/annotation/scan/Hotter.js +8 -8
  62. package/target/annotation/stereotype/BeanName.js +11 -11
  63. package/target/annotation/stereotype/Component.js +8 -8
  64. package/target/annotation/stereotype/Configure.js +14 -14
  65. package/target/annotation/stereotype/Controller.js +9 -9
  66. package/target/annotation/stereotype/Injection.js +12 -12
  67. package/target/annotation/stereotype/Log.js +19 -17
  68. package/target/annotation/stereotype/Repository.js +9 -9
  69. package/target/annotation/stereotype/Service.js +9 -9
  70. package/target/annotation/stereotype/Value.js +5 -0
  71. package/target/annotation/valid/AddChildValid.js +56 -56
  72. package/target/annotation/valid/CustomType.js +11 -11
  73. package/target/annotation/valid/DefaultVal.js +10 -10
  74. package/target/annotation/valid/NotNull.js +8 -8
  75. package/target/annotation/valid/Rule.js +99 -100
  76. package/target/annotation/valid/Size.js +10 -10
  77. package/target/annotation/valid/Type.js +10 -10
  78. package/target/annotation/valid/ValidCustom.js +17 -17
  79. package/target/annotation/valid/ValidForm.js +133 -133
  80. package/target/annotation.js +110 -108
  81. package/target/config/ApplicationConfig.js +2 -2
  82. package/target/config/SysConfig.js +19 -19
  83. package/target/constant/AppStatusEnum.js +9 -9
  84. package/target/constant/BootPriority.js +11 -11
  85. package/target/constant/CommonConstant.js +18 -18
  86. package/target/constant/ComponentKind.js +11 -11
  87. package/target/constant/DataTypes.js +19 -19
  88. package/target/constant/FastCarMetaData.js +33 -31
  89. package/target/constant/LifeCycleModule.js +9 -9
  90. package/target/db.js +49 -49
  91. package/target/index.js +21 -21
  92. package/target/interface/ApplicationHook.js +2 -2
  93. package/target/interface/ApplicationInterface.js +2 -2
  94. package/target/interface/ApplicationRunnerService.js +2 -2
  95. package/target/interface/DataSourceManager.js +2 -2
  96. package/target/interface/Logger.js +5 -5
  97. package/target/model/BaseMapper.js +103 -98
  98. package/target/model/DataMap.js +87 -87
  99. package/target/model/FormRuleModel.js +2 -2
  100. package/target/model/ValidError.js +5 -5
  101. package/target/model/WinstonLogger.js +98 -96
  102. package/target/type/ClassConstructor.js +2 -0
  103. package/target/type/ComponentDesc.js +9 -2
  104. package/target/type/DesignMeta.js +15 -15
  105. package/target/type/FileHotterDesc.js +9 -2
  106. package/target/type/MapperType.js +2 -2
  107. package/target/type/ProcessType.js +2 -2
  108. package/target/type/SqlError.js +5 -5
  109. package/target/type/WinstonLoggerType.js +9 -9
  110. package/target/utils/ClassLoader.js +66 -65
  111. package/target/utils/ClassUtils.js +35 -35
  112. package/target/utils/CryptoUtil.js +86 -86
  113. package/target/utils/DataFormat.js +88 -88
  114. package/target/utils/DateUtil.js +71 -71
  115. package/target/utils/FileUtil.js +153 -153
  116. package/target/utils/FormatStr.js +14 -14
  117. package/target/utils/IPUtils.js +34 -34
  118. package/target/utils/Id.js +8 -9
  119. package/target/utils/Mix.js +62 -62
  120. package/target/utils/ReflectUtil.js +22 -22
  121. package/target/utils/TypeUtil.js +53 -53
  122. package/target/utils/ValidationUtil.js +123 -123
  123. package/target/utils.js +25 -25
  124. package/test/example/logs/fastcar-server.app.log +0 -0
  125. package/test/example/logs/fastcar-server.sys.log +10 -0
  126. package/test/example/logs/fastcar-server.sys1.log +8 -0
  127. package/test/example/logs/fastcar-server.sys2.log +11 -0
  128. package/test/example/logs/fastcar-server.sys3.log +0 -0
  129. package/test/example/logs/other-server.app.log +0 -0
  130. package/test/example/logs/other-server.sys.log +5 -0
  131. package/test/example/logs/sys.log +0 -0
  132. package/test/example/logs/sys1.log +0 -0
  133. package/test/example/resource/application.yml +2 -0
  134. package/test/example/resource/hello.yml +1 -1
  135. package/test/example/simple/app-test.ts +2 -1
  136. package/test/example/simple/app.ts +16 -16
  137. package/test/example/simple/service/CallService.ts +2 -0
  138. package/test/example/simple/service/HelloService.ts +2 -0
  139. package/test/unit/sys2.log +6 -0
  140. package/test/unit/sys3.log +6 -0
  141. package/test/unit/sys4.log +6 -0
  142. package/test/unit/sys5.log +6 -0
  143. package/test/unit/sys6.log +6 -0
@@ -1,708 +1,764 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var FastCarApplication_1;
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- require("reflect-metadata");
14
- const fs = require("fs");
15
- const process = require("process");
16
- const Events = require("events");
17
- const path = require("path");
18
- const ClassLoader_1 = require("./utils/ClassLoader");
19
- const FileUtil_1 = require("./utils/FileUtil");
20
- const Mix_1 = require("./utils/Mix");
21
- const TypeUtil_1 = require("./utils/TypeUtil");
22
- const SysConfig_1 = require("./config/SysConfig");
23
- const FastCarMetaData_1 = require("./constant/FastCarMetaData");
24
- const CommonConstant_1 = require("./constant/CommonConstant");
25
- const LifeCycleModule_1 = require("./constant/LifeCycleModule");
26
- const AppStatusEnum_1 = require("./constant/AppStatusEnum");
27
- const ValidationUtil_1 = require("./utils/ValidationUtil");
28
- const Component_1 = require("./annotation/stereotype/Component");
29
- const WinstonLogger_1 = require("./model/WinstonLogger");
30
- const winston = require("winston");
31
- const DateUtil_1 = require("./utils/DateUtil");
32
- const Log_1 = require("./annotation/stereotype/Log");
33
- let FastCarApplication = FastCarApplication_1 = class FastCarApplication extends Events {
34
- constructor() {
35
- super();
36
- this.resourcePath = ""; //资源路径
37
- this.basename = CommonConstant_1.CommonConstant.Application;
38
- this.sysConfig = SysConfig_1.SYSDefaultConfig;
39
- this.componentMap = new Map();
40
- this.componentDeatils = new Map();
41
- this.applicationStatus = AppStatusEnum_1.AppStatusEnum.READY;
42
- this.liveTime = Date.now();
43
- this.watchFiles = new Map();
44
- this.delayHotIds = new Map();
45
- this.reloadTimerId = null;
46
- this.componentAliasMap = new Map();
47
- this.loadSelf();
48
- this.addHot();
49
- }
50
- /***
51
- * @version 1.0 根据原型加载注入的方法
52
- *
53
- */
54
- getInjectionUniqueKey(target) {
55
- let key = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionUniqueKey, target);
56
- return key;
57
- }
58
- loadSelf() {
59
- let key = this.getInjectionUniqueKey(FastCarApplication_1);
60
- this.componentMap.set(key, this);
61
- this.componentDeatils.set("FastCarApplication", {
62
- id: key,
63
- name: "FastCarApplication",
64
- path: __filename,
65
- });
66
- //暴露一个全局的app 以便调用
67
- Reflect.set(global, CommonConstant_1.CommonConstant.FastcarApp, this);
68
- }
69
- /***
70
- * @version 1.0 热更新组件
71
- * @version 1.1 热更新配置文件
72
- */
73
- addHot() {
74
- this.on("reload", (fp) => {
75
- if (this.applicationStatus != AppStatusEnum_1.AppStatusEnum.RUN) {
76
- return;
77
- }
78
- this.addDelayHot(fp, 1);
79
- });
80
- this.on("sysReload", (fp) => {
81
- if (fp.indexOf(this.basename) != -1) {
82
- this.addDelayHot(fp, 2);
83
- }
84
- });
85
- }
86
- addDelayHot(fp, loadType) {
87
- if (this.delayHotIds.has(fp)) {
88
- return;
89
- }
90
- this.delayHotIds.set(fp, {
91
- fp,
92
- loadType,
93
- });
94
- if (!this.reloadTimerId) {
95
- this.reloadTimerId = setTimeout(() => {
96
- this.reloadFiles();
97
- }, 1000);
98
- }
99
- }
100
- reloadFiles() {
101
- this.delayHotIds.forEach(({ fp, loadType }) => {
102
- switch (loadType) {
103
- case 1: {
104
- let moduleClass = ClassLoader_1.default.loadModule(fp, true);
105
- this.sysLogger.info("hot update---" + fp);
106
- if (moduleClass != null) {
107
- moduleClass.forEach((func) => {
108
- this.convertInstance(func, fp);
109
- });
110
- }
111
- break;
112
- }
113
- case 2: {
114
- this.sysLogger.info("sysConfig hot update----" + fp);
115
- this.loadSysConfig();
116
- break;
117
- }
118
- default: {
119
- }
120
- }
121
- });
122
- this.delayHotIds.clear();
123
- this.reloadTimerId = null;
124
- }
125
- /***
126
- * @version 1.0 获取资源路径
127
- */
128
- getResourcePath() {
129
- if (!!this.resourcePath) {
130
- return this.resourcePath;
131
- }
132
- let resourcePath = path.join(this.basePath, "../", CommonConstant_1.CommonConstant.Resource);
133
- this.resourcePath = resourcePath;
134
- return resourcePath;
135
- }
136
- /***
137
- * @version 1.0 获取项目的基本路径
138
- *
139
- */
140
- getBasePath() {
141
- return this.basePath;
142
- }
143
- /**
144
- * @version 1.0 获取项目读取的基本配置路径
145
- */
146
- getBaseName() {
147
- return this.basename;
148
- }
149
- /***
150
- * @version 1.0 加载系统配置 加载顺序为 default json < yaml < env
151
- *
152
- */
153
- loadSysConfig() {
154
- this.sysConfig = FileUtil_1.default.getApplicationConfig(this.getResourcePath(), this.basename, this.sysConfig);
155
- let env = (Reflect.get(this, CommonConstant_1.CommonConstant.ENV) || this.sysConfig.application.env || "devlopment");
156
- this.sysConfig = FileUtil_1.default.getApplicationConfig(this.getResourcePath(), `${this.basename}-${env}`, this.sysConfig);
157
- //自定义环境变量设置
158
- process.env.NODE_ENV = env;
159
- //判断程序内是否有配置
160
- let applicationSesstings = Reflect.getMetadata(CommonConstant_1.CommonConstant.FastcarSetting, this);
161
- if (applicationSesstings) {
162
- applicationSesstings.forEach((value, key) => {
163
- let afterConfig = value;
164
- let beforeConfig = this.sysConfig.settings.get(key);
165
- if (beforeConfig) {
166
- //对settings的属性进行覆盖
167
- if (typeof beforeConfig == "object") {
168
- afterConfig = Object.assign(beforeConfig, afterConfig);
169
- }
170
- }
171
- this.sysConfig.settings.set(key, afterConfig);
172
- });
173
- }
174
- //读取app的必要信息 name和版本号 根据 package.json
175
- let packagePath = path.join(this.basePath, "../", "package.json");
176
- if (fs.existsSync(packagePath)) {
177
- let packageInfo = require(packagePath);
178
- if (packageInfo.name) {
179
- this.sysConfig.application.name = packageInfo.name;
180
- }
181
- if (packageInfo.version) {
182
- this.sysConfig.application.version = packageInfo.version;
183
- }
184
- }
185
- }
186
- setSetting(key, value) {
187
- this.sysConfig.settings.set(key, value);
188
- }
189
- /***
190
- * @version 1.0 获取自定义设置 设置优先级 配置自定义>系统配置>初始化
191
- *
192
- */
193
- getSetting(key) {
194
- let res = this.sysConfig.settings.get(key);
195
- if (ValidationUtil_1.default.isNotNull(res)) {
196
- return res;
197
- }
198
- res = Reflect.get(this.sysConfig, key);
199
- if (ValidationUtil_1.default.isNotNull(res)) {
200
- res;
201
- }
202
- return Reflect.get(this, key);
203
- }
204
- /***
205
- * @version 1.0 获取应用配置
206
- */
207
- getapplicationConfig() {
208
- return this.sysConfig.application;
209
- }
210
- /***
211
- * @version 1.0 扫描组件
212
- * @version 1.1 新增手动注入组件
213
- * @version 1.2 改成统一入口
214
- */
215
- loadClass() {
216
- //加载文件扫描下的bean
217
- let tmpFilePath = Array.of();
218
- let includeList = Reflect.get(this, FastCarMetaData_1.FastCarMetaData.ComponentScan) || [];
219
- let mustIncludMustList = Reflect.get(this, FastCarMetaData_1.FastCarMetaData.ComponentScanMust) || [];
220
- //从配置文件内读
221
- if (Array.isArray(this.sysConfig.application?.scan?.include) && this.sysConfig.application?.scan?.include) {
222
- includeList = [...includeList, ...this.sysConfig.application.scan.include];
223
- }
224
- if (includeList.length > 0) {
225
- includeList.forEach((item) => {
226
- //获取路径
227
- let tmpList = FileUtil_1.default.getFilePathList(item);
228
- tmpFilePath = tmpFilePath.concat(tmpList);
229
- });
230
- }
231
- let includeFinalList = [];
232
- mustIncludMustList.forEach((item) => {
233
- let tmpList = FileUtil_1.default.getFilePathList(item);
234
- includeFinalList = includeFinalList.concat(tmpList);
235
- });
236
- let filePathList = FileUtil_1.default.getFilePathList(this.basePath);
237
- filePathList = tmpFilePath.concat(filePathList);
238
- filePathList = [...new Set(filePathList)];
239
- let excludeList = Reflect.get(this, FastCarMetaData_1.FastCarMetaData.ComponentScanExclusion) || [];
240
- if (Array.isArray(this.sysConfig.application?.scan?.exclude) && this.sysConfig.application?.scan?.exclude) {
241
- excludeList = [...excludeList, ...this.sysConfig.application.scan.exclude];
242
- }
243
- if (excludeList.length > 0) {
244
- let excludAllPath = [];
245
- excludeList.forEach((item) => {
246
- let exlist = FileUtil_1.default.getFilePathList(item);
247
- excludAllPath = [...excludAllPath, ...exlist];
248
- });
249
- filePathList = filePathList.filter((item) => {
250
- if (includeFinalList.includes(item)) {
251
- return true;
252
- }
253
- return !excludAllPath.includes(item);
254
- });
255
- }
256
- let resp = this.getResourcePath();
257
- for (let f of filePathList) {
258
- if (f == this.baseFileName) {
259
- continue;
260
- }
261
- //如果是资源路径下的则自动过滤掉
262
- if (f.startsWith(resp)) {
263
- continue;
264
- }
265
- let moduleClass = ClassLoader_1.default.loadModule(f);
266
- if (moduleClass != null) {
267
- moduleClass.forEach((func, name) => {
268
- if (this.componentMap.has(name)) {
269
- let repeatError = new Error(`Duplicate ${name} instance objects are not allowed `);
270
- this.sysLogger.error(repeatError.message);
271
- throw repeatError;
272
- }
273
- this.convertInstance(func, f);
274
- });
275
- }
276
- }
277
- }
278
- getInjectionUniqueKeyByFilePath(fp, name) {
279
- let list = this.watchFiles.get(fp);
280
- if (list) {
281
- for (let item of list) {
282
- if (item.name == name) {
283
- return item.key;
284
- }
285
- }
286
- }
287
- return null;
288
- }
289
- /***
290
- * @version 1.0 转成实例对象
291
- * @version 1.0.1 新增加载时识别载入配置选项
292
- *
293
- */
294
- convertInstance(classZ, fp) {
295
- //只有依赖注入的组件才能被实例化
296
- let Target = classZ;
297
- let instanceKey = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionUniqueKey, classZ);
298
- if (!instanceKey) {
299
- Target = Reflect.get(classZ, "__target__");
300
- if (!Target) {
301
- return;
302
- }
303
- instanceKey = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionUniqueKey, Target);
304
- }
305
- if (!!instanceKey) {
306
- let iname = classZ?.name || FileUtil_1.default.getFileName(fp);
307
- let beforeKey = this.getInjectionUniqueKeyByFilePath(fp, iname);
308
- if (beforeKey) {
309
- let beforeInstance = this.componentMap.get(beforeKey);
310
- if (!!beforeInstance) {
311
- Mix_1.default.assign(beforeInstance, classZ);
312
- return;
313
- }
314
- }
315
- //判断是否需要加载对应配置
316
- let cp = Reflect.getMetadata(LifeCycleModule_1.LifeCycleModule.LoadConfigure, Target);
317
- if (cp) {
318
- let rfp = path.join(this.getResourcePath(), cp);
319
- let tmpConfig = FileUtil_1.default.getResource(rfp);
320
- //进行实例化赋值
321
- if (tmpConfig) {
322
- //进行赋值不改变基础属性
323
- if (TypeUtil_1.default.isFunction(classZ)) {
324
- Mix_1.default.copPropertyValue(classZ.prototype, tmpConfig);
325
- }
326
- else {
327
- Mix_1.default.copPropertyValue(classZ, tmpConfig);
328
- }
329
- }
330
- }
331
- let instance = TypeUtil_1.default.isFunction(classZ) ? new classZ() : classZ;
332
- this.componentMap.set(instanceKey, instance);
333
- this.componentDeatils.set(instanceKey, {
334
- id: instanceKey,
335
- name: classZ?.name || FileUtil_1.default.getFileName(fp),
336
- path: fp,
337
- });
338
- //判断是否有别名
339
- let aliasName = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.Alias, instance);
340
- if (aliasName) {
341
- this.componentAliasMap.set(aliasName, instanceKey);
342
- // this.componentMap.set(aliasName, instance);
343
- // this.componentDeatils.set(aliasName, {
344
- // id: aliasName,
345
- // name: aliasName,
346
- // path: fp,
347
- // });
348
- }
349
- //判断是否需要热更加载
350
- if (this.isHotter() || Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.Hotter, instance)) {
351
- let fpObj = this.watchFiles.get(fp);
352
- let fpdesc = {
353
- key: instanceKey,
354
- name: iname,
355
- };
356
- if (!fpObj) {
357
- fpObj = [fpdesc];
358
- ClassLoader_1.default.watchServices(fp, this);
359
- this.watchFiles.set(fp, fpObj);
360
- }
361
- else {
362
- fpObj.push(fpdesc);
363
- }
364
- }
365
- }
366
- }
367
- /***
368
- * @version 1.0 装配模块
369
- * @version 1.0 装配日志模块
370
- * @version 1.1 移除装配日志模块 改为随用随取
371
- * @deprecated 弃用系统自动装配
372
- */
373
- // injectionModule(instance: any, instanceName: string | symbol): void {
374
- // let relyname = FastCarMetaData.IocModule;
375
- // let moduleList: Map<string, string> = Reflect.getMetadata(relyname, instance);
376
- // let detailInfo = this.componentDeatils.get(instanceName);
377
- // if (moduleList && moduleList.size > 0) {
378
- // moduleList.forEach((name: string, propertyKey: string) => {
379
- // let func = this.componentMap.get(name);
380
- // //如果等于自身则进行注入
381
- // if (name === FastCarApplication.name || name === FastCarMetaData.APP) {
382
- // func = this;
383
- // } else {
384
- // if (!this.componentMap.has(name)) {
385
- // //找不到依赖项
386
- // let injectionError = new Error(`Unsatisfied dependency expressed through [${propertyKey}] in ${detailInfo?.path} `);
387
- // this.sysLogger.error(injectionError.message);
388
- // throw injectionError;
389
- // }
390
- // }
391
- // Reflect.set(instance, propertyKey, func);
392
- // });
393
- // }
394
- // }
395
- /**
396
- * @version 1.0 加载需要注入的类
397
- * @deprecated
398
- */
399
- // loadInjectionModule() {
400
- // this.componentMap.forEach((instance, instanceName) => {
401
- // //补充实例找不到时 不能被注解
402
- // if (!instance) {
403
- // let insatnceError = new Error(`instance not found by ${instanceName.toString()}`);
404
- // this.sysLogger.error(insatnceError.message);
405
- // throw insatnceError;
406
- // }
407
- // this.injectionModule(instance, instanceName);
408
- // });
409
- // }
410
- /***
411
- * @version 1.0 根据类型获取组件
412
- */
413
- getComponentByType(name) {
414
- let instanceList = Array.of();
415
- this.componentMap.forEach((instance) => {
416
- let flag = Reflect.hasMetadata(name, instance);
417
- if (flag) {
418
- instanceList.push(instance);
419
- }
420
- });
421
- return instanceList;
422
- }
423
- /***
424
- * @version 1.0 获取全部的组件列表
425
- */
426
- getComponentList() {
427
- return [...this.componentMap.values()];
428
- }
429
- /***
430
- * @version 1.0 根据名称组件
431
- */
432
- getComponentByName(name) {
433
- if (this.componentMap.has(name)) {
434
- return this.componentMap.get(name);
435
- }
436
- let key = this.componentAliasMap.get(name);
437
- if (key) {
438
- return this.componentMap.get(key);
439
- }
440
- return null;
441
- }
442
- /***
443
- * @version 1.0 判断是否拥有组件名称
444
- */
445
- hasComponentByName(name) {
446
- return this.componentMap.has(name) || this.componentAliasMap.has(name);
447
- }
448
- /***
449
- * @version 1.0 根据原型获取实例
450
- */
451
- getComponentByTarget(target) {
452
- let key = this.getInjectionUniqueKey(target);
453
- return this.componentMap.get(key);
454
- }
455
- /**
456
- * @version 1.0 获取组件详情列表
457
- *
458
- */
459
- getComponentDetailsList() {
460
- return [...this.componentDeatils.values()];
461
- }
462
- /***
463
- * @version 1.0 根据名称获取组件的加载情况
464
- *
465
- */
466
- getComponentDetailByName(name) {
467
- if (this.componentDeatils.has(name)) {
468
- return this.componentDeatils.get(name);
469
- }
470
- let key = this.componentAliasMap.get(name);
471
- if (key) {
472
- return this.componentDeatils.get(key);
473
- }
474
- return undefined;
475
- }
476
- /***
477
- * @version 1.0 根据原型获取组件的加载信息
478
- *
479
- */
480
- getComponentDetailByTarget(target) {
481
- let key = this.getInjectionUniqueKey(target);
482
- return this.componentDeatils.get(key);
483
- }
484
- /**
485
- * @version 1.0 开启日志系统
486
- * @version 1.1 更改为采用winston日志
487
- */
488
- startLog() {
489
- let logConfig = this.getSetting("log");
490
- let defaultConfig = Object.assign({}, SysConfig_1.LogDefaultConfig, { rootPath: path.join(this.basePath, "../logs") });
491
- if (logConfig) {
492
- Object.assign(defaultConfig, logConfig);
493
- }
494
- this.loggerFactory = new WinstonLogger_1.default(defaultConfig);
495
- //添加系统日志
496
- // this.sysLogger = this.loggerFactory.addLogger(CommonConstant.SYSLOGGER);
497
- }
498
- /***
499
- * @version 1.0 初始化应用
500
- */
501
- init() {
502
- //加载配置
503
- this.basePath = (Reflect.get(this, CommonConstant_1.CommonConstant.BasePath) || require.main?.path || module.path || process.cwd());
504
- this.baseFileName = (Reflect.get(this, CommonConstant_1.CommonConstant.BaseFileName) || require.main?.filename || module.filename);
505
- this.beforeStartServer();
506
- this.startServer();
507
- this.addExitEvent();
508
- this.addExecptionEvent();
509
- }
510
- async exitEvent(msg) {
511
- //防止多次停止 原则上不会发生
512
- if (this.applicationStatus == AppStatusEnum_1.AppStatusEnum.RUN) {
513
- this.applicationStatus = AppStatusEnum_1.AppStatusEnum.STOP;
514
- this.sysLogger.info("exit reason", msg);
515
- await this.beforeStopServer();
516
- process.exit();
517
- }
518
- }
519
- addExitEvent() {
520
- process.on("beforeExit", () => {
521
- this.exitEvent("beforeExit exit");
522
- });
523
- process.on("SIGINT", () => {
524
- this.exitEvent("sigint exit");
525
- });
526
- process.on("message", async (msg) => {
527
- if (msg == "shutdown") {
528
- this.exitEvent("shutdown");
529
- }
530
- });
531
- process.on("exit", () => {
532
- this.stopServer();
533
- });
534
- }
535
- addExecptionEvent() {
536
- process.on("uncaughtException", (err, origin) => {
537
- this.sysLogger.error(`Caught exception: ${err.message}`);
538
- this.sysLogger.error(`Exception origin: ${origin}`);
539
- this.sysLogger.error(`stack: ${err.stack}`);
540
- });
541
- process.on("unhandledRejection", (reason, promise) => {
542
- this.sysLogger.error("Unhandled Rejection at:", promise);
543
- this.sysLogger.error("reason:", reason);
544
- });
545
- }
546
- /***
547
- * @version 1.0 自动调用方法
548
- */
549
- async automaticRun(name) {
550
- let list = [];
551
- this.componentMap.forEach((item) => {
552
- let runInfo = Reflect.hasMetadata(name, item);
553
- if (runInfo) {
554
- let childList = Reflect.getMetadata(name, item);
555
- childList.forEach((citem) => {
556
- list.push({
557
- order: citem.order,
558
- exec: citem.exec,
559
- item,
560
- });
561
- });
562
- }
563
- });
564
- list.sort((a, b) => {
565
- return a.order - b.order;
566
- });
567
- for (let { exec, item } of list) {
568
- let fn = item[exec];
569
- if (TypeUtil_1.default.isPromise(fn)) {
570
- await Promise.resolve(Reflect.apply(fn, item, []));
571
- }
572
- else {
573
- Reflect.apply(fn, item, []);
574
- }
575
- }
576
- }
577
- /**
578
- * @version 1.0 开启应用前执行的操作 加载配置,扫描组件,注入依赖组件
579
- */
580
- beforeStartServer() {
581
- //加载日志
582
- this.loadSysConfig();
583
- //监听系统配置
584
- if (this.isHotterSysConfig()) {
585
- ClassLoader_1.default.watchServices(this.getResourcePath(), this, "sysReload");
586
- }
587
- //开启日志
588
- this.startLog();
589
- this.sysLogger.info("Start scanning component");
590
- this.loadClass();
591
- this.sysLogger.info("Complete component scan");
592
- // this.sysLogger.info("Start component injection");
593
- // this.loadInjectionModule();
594
- // this.sysLogger.info("Complete component injection");
595
- }
596
- /***
597
- * @version 1.0 启动服务
598
- */
599
- async startServer() {
600
- this.sysLogger.info("Call application initialization method");
601
- await this.automaticRun(LifeCycleModule_1.LifeCycleModule.ApplicationStart);
602
- this.sysLogger.info(`start server ${this.sysConfig.application.name} is run`);
603
- this.sysLogger.info(`version ${this.sysConfig.application.version}`);
604
- this.applicationStatus = AppStatusEnum_1.AppStatusEnum.RUN;
605
- if (process.send && TypeUtil_1.default.isFunction(process.send)) {
606
- process.send("ready");
607
- }
608
- }
609
- /***
610
- * @version 1.0 停止服务前自动调用服务
611
- */
612
- async beforeStopServer() {
613
- this.sysLogger.info("Call the method before the application stops");
614
- await this.automaticRun(LifeCycleModule_1.LifeCycleModule.ApplicationStop);
615
- }
616
- /***
617
- * @version 1.0 停止服务
618
- */
619
- stopServer() {
620
- this.sysLogger.info("application stop");
621
- }
622
- /**
623
- * @version 1.0 获取app名称
624
- */
625
- getApplicationName() {
626
- return this.sysConfig.application.name;
627
- }
628
- /***
629
- * @version 1.0 获取系统日志
630
- *
631
- */
632
- getSysLogger() {
633
- return this.sysLogger;
634
- }
635
- /***
636
- * @version 1.0 获取文件内容
637
- */
638
- getFileContent(fp) {
639
- if (!fs.existsSync(fp)) {
640
- fp = path.join(this.getResourcePath(), fp);
641
- if (!fs.existsSync(fp)) {
642
- return "";
643
- }
644
- }
645
- let currStats = fs.statSync(fp);
646
- if (!currStats.isFile()) {
647
- return "";
648
- }
649
- return fs.readFileSync(fp).toString();
650
- }
651
- /***
652
- * @version 1.0 是否支持热更
653
- *
654
- */
655
- isHotter() {
656
- return !!this.getSetting("hotter");
657
- }
658
- /***
659
- * @version 1.0 是否支持资源文件热更
660
- */
661
- isHotterSysConfig() {
662
- return !!this.getSetting(FastCarMetaData_1.FastCarMetaData.HotterSysConfig);
663
- }
664
- /***
665
- * @version 1.0 指定热更新文件
666
- *
667
- */
668
- specifyHotUpdate(fp) {
669
- if (fs.existsSync(fp)) {
670
- this.emit("reload", fp);
671
- }
672
- }
673
- /***
674
- * @version 1.0 获取进程的信息
675
- *
676
- */
677
- getMemoryUsage() {
678
- let { rss, heapTotal, heapUsed, arrayBuffers, external } = process.memoryUsage();
679
- return {
680
- pid: process.pid,
681
- name: this.sysConfig.application.name,
682
- env: this.sysConfig.application.env,
683
- version: this.sysConfig.application.version,
684
- rss: FileUtil_1.default.formatBytes(rss),
685
- heapTotal: FileUtil_1.default.formatBytes(heapTotal),
686
- heapUsed: FileUtil_1.default.formatBytes(heapUsed),
687
- arrayBuffers: FileUtil_1.default.formatBytes(arrayBuffers),
688
- external: FileUtil_1.default.formatBytes(external),
689
- uptime: DateUtil_1.default.getTimeStr(Date.now() - this.liveTime), //运行时间
690
- };
691
- }
692
- getLogger(category = CommonConstant_1.CommonConstant.SYSLOGGER) {
693
- let logger = this.loggerFactory.getLogger(category);
694
- if (!logger) {
695
- return this.loggerFactory.addLogger(category);
696
- }
697
- return logger;
698
- }
699
- };
700
- __decorate([
701
- (0, Log_1.default)("sys"),
702
- __metadata("design:type", winston.Logger)
703
- ], FastCarApplication.prototype, "sysLogger", void 0);
704
- FastCarApplication = FastCarApplication_1 = __decorate([
705
- Component_1.default,
706
- __metadata("design:paramtypes", [])
707
- ], FastCarApplication);
708
- exports.default = FastCarApplication;
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var FastCarApplication_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ require("reflect-metadata");
14
+ const fs = require("fs");
15
+ const process = require("process");
16
+ const Events = require("events");
17
+ const path = require("path");
18
+ const ClassLoader_1 = require("./utils/ClassLoader");
19
+ const FileUtil_1 = require("./utils/FileUtil");
20
+ const Mix_1 = require("./utils/Mix");
21
+ const TypeUtil_1 = require("./utils/TypeUtil");
22
+ const SysConfig_1 = require("./config/SysConfig");
23
+ const FastCarMetaData_1 = require("./constant/FastCarMetaData");
24
+ const CommonConstant_1 = require("./constant/CommonConstant");
25
+ const LifeCycleModule_1 = require("./constant/LifeCycleModule");
26
+ const AppStatusEnum_1 = require("./constant/AppStatusEnum");
27
+ const ValidationUtil_1 = require("./utils/ValidationUtil");
28
+ const Component_1 = require("./annotation/stereotype/Component");
29
+ const WinstonLogger_1 = require("./model/WinstonLogger");
30
+ const Logger_1 = require("./interface/Logger");
31
+ const DateUtil_1 = require("./utils/DateUtil");
32
+ const FileHotterDesc_1 = require("./type/FileHotterDesc");
33
+ const ReflectUtil_1 = require("./utils/ReflectUtil");
34
+ const annotation_1 = require("./annotation");
35
+ let FastCarApplication = FastCarApplication_1 = class FastCarApplication extends Events {
36
+ componentMap; //组件键值对
37
+ sysConfig; //系统配置
38
+ basePath; //入口文件夹路径
39
+ baseFileName; //入口文件路径
40
+ loggerFactory;
41
+ applicationStatus;
42
+ sysLogger;
43
+ componentDeatils; //读取路径 名称
44
+ liveTime;
45
+ watchFiles;
46
+ resourcePath = ""; //资源路径
47
+ delayHotIds;
48
+ reloadTimerId;
49
+ basename = CommonConstant_1.CommonConstant.Application;
50
+ componentAliasMap;
51
+ hotConfigure;
52
+ constructor() {
53
+ super();
54
+ this.sysConfig = SysConfig_1.SYSDefaultConfig;
55
+ this.componentMap = new Map();
56
+ this.componentDeatils = new Map();
57
+ this.applicationStatus = AppStatusEnum_1.AppStatusEnum.READY;
58
+ this.liveTime = Date.now();
59
+ this.watchFiles = new Map();
60
+ this.delayHotIds = new Map();
61
+ this.reloadTimerId = null;
62
+ this.componentAliasMap = new Map();
63
+ this.hotConfigure = new Map();
64
+ this.loadSelf();
65
+ this.addHot();
66
+ }
67
+ /***
68
+ * @version 1.0 根据原型加载注入的方法
69
+ *
70
+ */
71
+ getInjectionUniqueKey(target) {
72
+ let key = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionUniqueKey, target);
73
+ return key;
74
+ }
75
+ loadSelf() {
76
+ let key = this.getInjectionUniqueKey(FastCarApplication_1);
77
+ this.componentMap.set(key, this);
78
+ this.componentDeatils.set("FastCarApplication", {
79
+ id: key,
80
+ name: "FastCarApplication",
81
+ path: __filename,
82
+ classZ: this,
83
+ });
84
+ //暴露一个全局的app 以便调用
85
+ Reflect.set(global, CommonConstant_1.CommonConstant.FastcarApp, this);
86
+ }
87
+ /***
88
+ * @version 1.0 热更新组件
89
+ * @version 1.1 热更新配置文件
90
+ */
91
+ addHot() {
92
+ this.on(FileHotterDesc_1.HotReloadEnum.reload, (fp) => {
93
+ if (this.applicationStatus != AppStatusEnum_1.AppStatusEnum.RUN) {
94
+ return;
95
+ }
96
+ this.addDelayHot(fp, FileHotterDesc_1.HotReloadEnum.reload);
97
+ });
98
+ this.on(FileHotterDesc_1.HotReloadEnum.sysReload, (fp) => {
99
+ if (fp.indexOf(this.basename) != -1) {
100
+ this.addDelayHot(fp, FileHotterDesc_1.HotReloadEnum.sysReload);
101
+ }
102
+ });
103
+ this.on(FileHotterDesc_1.HotReloadEnum.configReload, (fp) => {
104
+ this.addDelayHot(fp, FileHotterDesc_1.HotReloadEnum.configReload);
105
+ });
106
+ }
107
+ addDelayHot(fp, loadType) {
108
+ if (this.delayHotIds.has(fp)) {
109
+ return;
110
+ }
111
+ this.delayHotIds.set(fp, {
112
+ fp,
113
+ loadType,
114
+ });
115
+ if (!this.reloadTimerId) {
116
+ this.reloadTimerId = setTimeout(() => {
117
+ this.reloadFiles();
118
+ }, 1000);
119
+ }
120
+ }
121
+ reloadFiles() {
122
+ this.delayHotIds.forEach(({ fp, loadType }) => {
123
+ switch (loadType) {
124
+ case FileHotterDesc_1.HotReloadEnum.reload: {
125
+ let moduleClass = ClassLoader_1.default.loadModule(fp, true);
126
+ this.sysLogger.info("hot update---" + fp);
127
+ if (moduleClass != null) {
128
+ moduleClass.forEach((func) => {
129
+ this.convertInstance(func, fp);
130
+ });
131
+ }
132
+ break;
133
+ }
134
+ case FileHotterDesc_1.HotReloadEnum.sysReload: {
135
+ this.sysLogger.info("sysConfig hot update----" + fp);
136
+ this.loadSysConfig();
137
+ break;
138
+ }
139
+ case FileHotterDesc_1.HotReloadEnum.configReload: {
140
+ let ids = this.hotConfigure.get(fp);
141
+ if (ids) {
142
+ ids.forEach((item) => {
143
+ let instance = this.getComponentByName(item);
144
+ if (instance) {
145
+ this.updateConfig(instance, fp);
146
+ }
147
+ });
148
+ }
149
+ break;
150
+ }
151
+ default: {
152
+ this.sysLogger.warn(`not found ${loadType} by ${fp}`);
153
+ break;
154
+ }
155
+ }
156
+ });
157
+ this.delayHotIds.clear();
158
+ this.reloadTimerId = null;
159
+ }
160
+ /***
161
+ * @version 1.0 获取资源路径
162
+ */
163
+ getResourcePath() {
164
+ if (!!this.resourcePath) {
165
+ return this.resourcePath;
166
+ }
167
+ let resourcePath = path.join(this.basePath, "../", CommonConstant_1.CommonConstant.Resource);
168
+ this.resourcePath = resourcePath;
169
+ return resourcePath;
170
+ }
171
+ /***
172
+ * @version 1.0 获取项目的基本路径
173
+ *
174
+ */
175
+ getBasePath() {
176
+ return this.basePath;
177
+ }
178
+ /**
179
+ * @version 1.0 获取项目读取的基本配置路径
180
+ */
181
+ getBaseName() {
182
+ return this.basename;
183
+ }
184
+ /***
185
+ * @version 1.0 加载系统配置 加载顺序为 default json < yaml < env
186
+ *
187
+ */
188
+ loadSysConfig() {
189
+ this.sysConfig = FileUtil_1.default.getApplicationConfig(this.getResourcePath(), this.basename, this.sysConfig);
190
+ let env = (Reflect.get(this, CommonConstant_1.CommonConstant.ENV) || this.sysConfig.application.env || "devlopment");
191
+ this.sysConfig = FileUtil_1.default.getApplicationConfig(this.getResourcePath(), `${this.basename}-${env}`, this.sysConfig);
192
+ //自定义环境变量设置
193
+ process.env.NODE_ENV = env;
194
+ //判断程序内是否有配置
195
+ let applicationSesstings = Reflect.getMetadata(CommonConstant_1.CommonConstant.FastcarSetting, this);
196
+ if (applicationSesstings) {
197
+ applicationSesstings.forEach((value, key) => {
198
+ let afterConfig = value;
199
+ let beforeConfig = this.sysConfig.settings.get(key);
200
+ if (beforeConfig) {
201
+ //对settings的属性进行覆盖
202
+ if (typeof beforeConfig == "object") {
203
+ afterConfig = Object.assign(beforeConfig, afterConfig);
204
+ }
205
+ }
206
+ this.sysConfig.settings.set(key, afterConfig);
207
+ });
208
+ }
209
+ //读取app的必要信息 name和版本号 根据 package.json
210
+ let packagePath = path.join(this.basePath, "../", "package.json");
211
+ if (fs.existsSync(packagePath)) {
212
+ let packageInfo = require(packagePath);
213
+ if (packageInfo.name) {
214
+ this.sysConfig.application.name = packageInfo.name;
215
+ }
216
+ if (packageInfo.version) {
217
+ this.sysConfig.application.version = packageInfo.version;
218
+ }
219
+ }
220
+ }
221
+ setSetting(key, value) {
222
+ this.sysConfig.settings.set(key, value);
223
+ }
224
+ /***
225
+ * @version 1.0 获取自定义设置 设置优先级 配置自定义>系统配置>初始化
226
+ *
227
+ */
228
+ getSetting(key) {
229
+ let res = this.sysConfig.settings.get(key);
230
+ if (ValidationUtil_1.default.isNotNull(res)) {
231
+ return res;
232
+ }
233
+ res = Reflect.get(this.sysConfig, key);
234
+ if (ValidationUtil_1.default.isNotNull(res)) {
235
+ return res;
236
+ }
237
+ return Reflect.get(this, key);
238
+ }
239
+ /***
240
+ * @version 1.0 获取应用配置
241
+ */
242
+ getapplicationConfig() {
243
+ return this.sysConfig.application;
244
+ }
245
+ /***
246
+ * @version 1.0 扫描组件
247
+ * @version 1.1 新增手动注入组件
248
+ * @version 1.2 改成统一入口
249
+ */
250
+ loadClass() {
251
+ //加载文件扫描下的bean
252
+ let tmpFilePath = Array.of();
253
+ let includeList = Reflect.get(this, FastCarMetaData_1.FastCarMetaData.ComponentScan) || [];
254
+ let mustIncludMustList = Reflect.get(this, FastCarMetaData_1.FastCarMetaData.ComponentScanMust) || [];
255
+ //从配置文件内读
256
+ if (Array.isArray(this.sysConfig.application?.scan?.include) && this.sysConfig.application?.scan?.include) {
257
+ includeList = [...includeList, ...this.sysConfig.application.scan.include];
258
+ }
259
+ if (includeList.length > 0) {
260
+ includeList.forEach((item) => {
261
+ //获取路径
262
+ let tmpList = FileUtil_1.default.getFilePathList(item);
263
+ tmpFilePath = tmpFilePath.concat(tmpList);
264
+ });
265
+ }
266
+ let includeFinalList = [];
267
+ mustIncludMustList.forEach((item) => {
268
+ let tmpList = FileUtil_1.default.getFilePathList(item);
269
+ includeFinalList = includeFinalList.concat(tmpList);
270
+ });
271
+ let filePathList = FileUtil_1.default.getFilePathList(this.basePath);
272
+ filePathList = tmpFilePath.concat(filePathList);
273
+ filePathList = [...new Set(filePathList)];
274
+ let excludeList = Reflect.get(this, FastCarMetaData_1.FastCarMetaData.ComponentScanExclusion) || [];
275
+ if (Array.isArray(this.sysConfig.application?.scan?.exclude) && this.sysConfig.application?.scan?.exclude) {
276
+ excludeList = [...excludeList, ...this.sysConfig.application.scan.exclude];
277
+ }
278
+ if (excludeList.length > 0) {
279
+ let excludAllPath = [];
280
+ excludeList.forEach((item) => {
281
+ let exlist = FileUtil_1.default.getFilePathList(item);
282
+ excludAllPath = [...excludAllPath, ...exlist];
283
+ });
284
+ filePathList = filePathList.filter((item) => {
285
+ if (includeFinalList.includes(item)) {
286
+ return true;
287
+ }
288
+ return !excludAllPath.includes(item);
289
+ });
290
+ }
291
+ let resp = this.getResourcePath();
292
+ for (let f of filePathList) {
293
+ if (f == this.baseFileName) {
294
+ continue;
295
+ }
296
+ //如果是资源路径下的则自动过滤掉
297
+ if (f.startsWith(resp)) {
298
+ continue;
299
+ }
300
+ let moduleClass = ClassLoader_1.default.loadModule(f);
301
+ if (moduleClass != null) {
302
+ moduleClass.forEach((func, name) => {
303
+ if (this.componentMap.has(name)) {
304
+ let repeatError = new Error(`Duplicate ${name} instance objects are not allowed `);
305
+ this.sysLogger.error(repeatError.message);
306
+ throw repeatError;
307
+ }
308
+ this.convertInstance(func, f);
309
+ });
310
+ }
311
+ }
312
+ }
313
+ getInjectionUniqueKeyByFilePath(fp, name) {
314
+ let list = this.watchFiles.get(fp);
315
+ if (list) {
316
+ for (let item of list) {
317
+ if (item.name == name) {
318
+ return item.key;
319
+ }
320
+ }
321
+ }
322
+ return null;
323
+ }
324
+ /***
325
+ * @version 1.0 转成实例对象
326
+ * @version 1.0.1 新增加载时识别载入配置选项
327
+ *
328
+ */
329
+ convertInstance(classZ, fp) {
330
+ //只有依赖注入的组件才能被实例化
331
+ let Target = classZ;
332
+ let instanceKey = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionUniqueKey, classZ);
333
+ if (!instanceKey) {
334
+ Target = Reflect.get(classZ, "__target__");
335
+ if (!Target) {
336
+ return;
337
+ }
338
+ instanceKey = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionUniqueKey, Target);
339
+ }
340
+ if (!!instanceKey) {
341
+ let iname = classZ?.name || FileUtil_1.default.getFileName(fp);
342
+ let beforeKey = this.getInjectionUniqueKeyByFilePath(fp, iname);
343
+ if (beforeKey) {
344
+ let beforeInstance = this.getBean(beforeKey);
345
+ if (!!beforeInstance) {
346
+ Mix_1.default.assign(beforeInstance, classZ);
347
+ return;
348
+ }
349
+ }
350
+ //这边只放元数据
351
+ this.componentDeatils.set(instanceKey, {
352
+ id: instanceKey,
353
+ name: classZ?.name || FileUtil_1.default.getFileName(fp),
354
+ path: fp,
355
+ classZ,
356
+ });
357
+ //加载Bean
358
+ this.getBean(instanceKey);
359
+ }
360
+ }
361
+ /***
362
+ * @version 1.0 根据类型获取组件
363
+ */
364
+ getComponentByType(name) {
365
+ let instanceList = Array.of();
366
+ this.componentMap.forEach((instance) => {
367
+ let flag = Reflect.hasMetadata(name, instance);
368
+ if (flag) {
369
+ instanceList.push(instance);
370
+ }
371
+ });
372
+ return instanceList;
373
+ }
374
+ /***
375
+ * @version 1.0 获取全部的组件列表
376
+ */
377
+ getComponentList() {
378
+ return [...this.componentMap.values()];
379
+ }
380
+ /***
381
+ * @version 1.0 根据名称组件
382
+ */
383
+ getComponentByName(name) {
384
+ if (this.componentMap.has(name)) {
385
+ return this.getBean(name);
386
+ }
387
+ let key = this.componentAliasMap.get(name);
388
+ if (key) {
389
+ return this.getBean(key);
390
+ }
391
+ return null;
392
+ }
393
+ /**
394
+ * @version 1.0 组件改成按需加载的模式
395
+ */
396
+ getBean(key) {
397
+ let instance = this.componentMap.get(key) || null;
398
+ if (!instance) {
399
+ //初始化
400
+ let item = this.componentDeatils.get(key);
401
+ if (!item) {
402
+ return null;
403
+ }
404
+ //判断是否有别名
405
+ let instanceKey = item.id;
406
+ let classZ = item.classZ;
407
+ let instance = TypeUtil_1.default.isFunction(classZ) ? new classZ() : classZ;
408
+ let hotter = this.isHotter();
409
+ if (!hotter) {
410
+ if (classZ?.prototype && Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.Hotter, classZ.prototype)) {
411
+ hotter = true;
412
+ }
413
+ }
414
+ //加载配置
415
+ let cp = Reflect.getMetadata(LifeCycleModule_1.LifeCycleModule.LoadConfigure, classZ);
416
+ if (cp) {
417
+ let rfp = path.join(this.getResourcePath(), cp);
418
+ this.updateConfig(instance, rfp);
419
+ if (hotter) {
420
+ //监听资源文件
421
+ this.setHotConfigures(rfp, instanceKey);
422
+ ClassLoader_1.default.watchServices(rfp, this, FileHotterDesc_1.HotReloadEnum.configReload);
423
+ }
424
+ }
425
+ this.loadInjectionService(instance);
426
+ this.loadLoggerIOC(instance);
427
+ let aliasName = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.Alias, instance);
428
+ if (aliasName) {
429
+ this.componentAliasMap.set(aliasName, instanceKey);
430
+ }
431
+ let fp = item.path;
432
+ let iname = classZ?.name || FileUtil_1.default.getFileName(fp);
433
+ //判断是否需要热更加载
434
+ if (hotter) {
435
+ let fpObj = this.watchFiles.get(fp);
436
+ let fpdesc = {
437
+ key: instanceKey,
438
+ name: iname,
439
+ };
440
+ if (!fpObj) {
441
+ fpObj = [fpdesc];
442
+ ClassLoader_1.default.watchServices(fp, this);
443
+ this.watchFiles.set(fp, fpObj);
444
+ }
445
+ else {
446
+ fpObj.push(fpdesc);
447
+ }
448
+ }
449
+ this.componentMap.set(key, instance);
450
+ }
451
+ return instance;
452
+ }
453
+ loadInjectionService(instance) {
454
+ let injectionIds = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionSingleInstance, instance);
455
+ if (injectionIds && injectionIds.length > 0) {
456
+ injectionIds.forEach((item) => {
457
+ Reflect.defineProperty(instance, item.key, {
458
+ get: () => {
459
+ let key = ReflectUtil_1.default.getNameByPropertyKey(instance, item.alias || item.key);
460
+ if (!this.hasComponentByName(key)) {
461
+ //找不到依赖组件异常
462
+ let injectionError = new Error(`Unsatisfied dependency expressed through [${item.key}] `);
463
+ throw injectionError;
464
+ }
465
+ return this.getComponentByName(key);
466
+ },
467
+ });
468
+ });
469
+ }
470
+ }
471
+ loadLoggerIOC(instance) {
472
+ let logIds = Reflect.getMetadata(FastCarMetaData_1.FastCarMetaData.InjectionLog, instance);
473
+ if (logIds && logIds.length > 0) {
474
+ logIds.forEach((item) => {
475
+ Reflect.defineProperty(instance, item.propertyKey, {
476
+ get: () => {
477
+ let appid = this.getSetting(CommonConstant_1.CommonConstant.APPId) || ""; //进行差异化区分
478
+ return this.getLogger(appid ? `${appid}.${item.name}` : item.name);
479
+ },
480
+ });
481
+ });
482
+ }
483
+ }
484
+ updateConfig(instance, fp) {
485
+ let tmpConfig = FileUtil_1.default.getResource(fp);
486
+ //进行实例化赋值
487
+ if (tmpConfig) {
488
+ Mix_1.default.copPropertyValue(instance, tmpConfig);
489
+ }
490
+ }
491
+ setHotConfigures(fid, servicePath) {
492
+ let list = this.hotConfigure.get(fid);
493
+ if (!list) {
494
+ list = [];
495
+ this.hotConfigure.set(fid, list);
496
+ }
497
+ if (!list.includes(servicePath)) {
498
+ list.push(servicePath);
499
+ }
500
+ }
501
+ /***
502
+ * @version 1.0 判断是否拥有组件名称
503
+ */
504
+ hasComponentByName(name) {
505
+ return this.componentMap.has(name) || this.componentAliasMap.has(name);
506
+ }
507
+ /***
508
+ * @version 1.0 根据原型获取实例
509
+ */
510
+ getComponentByTarget(target) {
511
+ let key = this.getInjectionUniqueKey(target);
512
+ let bean = this.getBean(key);
513
+ return bean != null ? bean : null;
514
+ }
515
+ /**
516
+ * @version 1.0 获取组件详情列表
517
+ *
518
+ */
519
+ getComponentDetailsList() {
520
+ return [...this.componentDeatils.values()];
521
+ }
522
+ /***
523
+ * @version 1.0 根据名称获取组件的加载情况
524
+ *
525
+ */
526
+ getComponentDetailByName(name) {
527
+ if (this.componentDeatils.has(name)) {
528
+ return this.componentDeatils.get(name);
529
+ }
530
+ let key = this.componentAliasMap.get(name);
531
+ if (key) {
532
+ return this.componentDeatils.get(key);
533
+ }
534
+ return undefined;
535
+ }
536
+ /***
537
+ * @version 1.0 根据原型获取组件的加载信息
538
+ *
539
+ */
540
+ getComponentDetailByTarget(target) {
541
+ let key = this.getInjectionUniqueKey(target);
542
+ return this.componentDeatils.get(key);
543
+ }
544
+ /**
545
+ * @version 1.0 开启日志系统
546
+ * @version 1.1 更改为采用winston日志
547
+ */
548
+ startLog() {
549
+ let logConfig = this.getSetting("log");
550
+ let defaultConfig = Object.assign({}, SysConfig_1.LogDefaultConfig, { rootPath: path.join(this.basePath, "../logs") });
551
+ if (logConfig) {
552
+ Object.assign(defaultConfig, logConfig);
553
+ }
554
+ this.loggerFactory = new WinstonLogger_1.default(defaultConfig);
555
+ }
556
+ /***
557
+ * @version 1.0 初始化应用
558
+ */
559
+ init() {
560
+ //加载配置
561
+ this.basePath = (Reflect.get(this, CommonConstant_1.CommonConstant.BasePath) || require.main?.path || module.path || process.cwd());
562
+ this.baseFileName = (Reflect.get(this, CommonConstant_1.CommonConstant.BaseFileName) || require.main?.filename || module.filename);
563
+ this.beforeStartServer();
564
+ this.startServer();
565
+ this.addExitEvent();
566
+ this.addExecptionEvent();
567
+ }
568
+ async exitEvent(msg) {
569
+ //防止多次停止 原则上不会发生
570
+ if (this.applicationStatus == AppStatusEnum_1.AppStatusEnum.RUN) {
571
+ this.applicationStatus = AppStatusEnum_1.AppStatusEnum.STOP;
572
+ this.sysLogger.info("exit reason", msg);
573
+ await this.beforeStopServer();
574
+ process.exit();
575
+ }
576
+ }
577
+ addExitEvent() {
578
+ process.on("beforeExit", () => {
579
+ this.exitEvent("beforeExit exit");
580
+ });
581
+ process.on("SIGINT", () => {
582
+ this.exitEvent("sigint exit");
583
+ });
584
+ process.on("message", async (msg) => {
585
+ if (msg == "shutdown") {
586
+ this.exitEvent("shutdown");
587
+ }
588
+ });
589
+ process.on("exit", () => {
590
+ this.stopServer();
591
+ });
592
+ }
593
+ addExecptionEvent() {
594
+ process.on("uncaughtException", (err, origin) => {
595
+ this.sysLogger.error(`Caught exception: ${err.message}`);
596
+ this.sysLogger.error(`Exception origin: ${origin}`);
597
+ this.sysLogger.error(`stack: ${err.stack}`);
598
+ });
599
+ process.on("unhandledRejection", (reason, promise) => {
600
+ this.sysLogger.error("Unhandled Rejection at:", promise);
601
+ this.sysLogger.error("reason:", reason);
602
+ });
603
+ }
604
+ /***
605
+ * @version 1.0 自动调用方法
606
+ */
607
+ async automaticRun(name) {
608
+ let list = [];
609
+ this.componentMap.forEach((item) => {
610
+ let runInfo = Reflect.hasMetadata(name, item);
611
+ if (runInfo) {
612
+ let childList = Reflect.getMetadata(name, item);
613
+ childList.forEach((citem) => {
614
+ list.push({
615
+ order: citem.order,
616
+ exec: citem.exec,
617
+ item,
618
+ });
619
+ });
620
+ }
621
+ });
622
+ list.sort((a, b) => {
623
+ return a.order - b.order;
624
+ });
625
+ for (let { exec, item } of list) {
626
+ let fn = item[exec];
627
+ if (TypeUtil_1.default.isPromise(fn)) {
628
+ await Promise.resolve(Reflect.apply(fn, item, []));
629
+ }
630
+ else {
631
+ Reflect.apply(fn, item, []);
632
+ }
633
+ }
634
+ }
635
+ /**
636
+ * @version 1.0 开启应用前执行的操作 加载配置,扫描组件,注入依赖组件
637
+ */
638
+ beforeStartServer() {
639
+ //加载日志
640
+ this.loadSysConfig();
641
+ //监听系统配置
642
+ if (this.isHotterSysConfig()) {
643
+ ClassLoader_1.default.watchServices(this.getResourcePath(), this, FileHotterDesc_1.HotReloadEnum.sysReload);
644
+ }
645
+ //开启日志
646
+ this.startLog();
647
+ this.loadLoggerIOC(this);
648
+ this.sysLogger.info("Start scanning component");
649
+ this.loadClass();
650
+ this.sysLogger.info("Complete component scan");
651
+ }
652
+ /***
653
+ * @version 1.0 启动服务
654
+ */
655
+ async startServer() {
656
+ this.sysLogger.info("Call application initialization method");
657
+ await this.automaticRun(LifeCycleModule_1.LifeCycleModule.ApplicationStart);
658
+ this.sysLogger.info(`start server ${this.sysConfig.application.name} is run`);
659
+ this.sysLogger.info(`version ${this.sysConfig.application.version}`);
660
+ this.applicationStatus = AppStatusEnum_1.AppStatusEnum.RUN;
661
+ if (process.send && TypeUtil_1.default.isFunction(process.send)) {
662
+ process.send("ready");
663
+ }
664
+ }
665
+ /***
666
+ * @version 1.0 停止服务前自动调用服务
667
+ */
668
+ async beforeStopServer() {
669
+ this.sysLogger.info("Call the method before the application stops");
670
+ await this.automaticRun(LifeCycleModule_1.LifeCycleModule.ApplicationStop);
671
+ }
672
+ /***
673
+ * @version 1.0 停止服务
674
+ */
675
+ stopServer() {
676
+ this.sysLogger.info("application stop");
677
+ }
678
+ /**
679
+ * @version 1.0 获取app名称
680
+ */
681
+ getApplicationName() {
682
+ return this.sysConfig.application.name;
683
+ }
684
+ /***
685
+ * @version 1.0 获取系统日志
686
+ *
687
+ */
688
+ getSysLogger() {
689
+ return this.sysLogger;
690
+ }
691
+ /***
692
+ * @version 1.0 获取文件内容
693
+ */
694
+ getFileContent(fp) {
695
+ if (!fs.existsSync(fp)) {
696
+ fp = path.join(this.getResourcePath(), fp);
697
+ if (!fs.existsSync(fp)) {
698
+ return "";
699
+ }
700
+ }
701
+ let currStats = fs.statSync(fp);
702
+ if (!currStats.isFile()) {
703
+ return "";
704
+ }
705
+ return fs.readFileSync(fp).toString();
706
+ }
707
+ /***
708
+ * @version 1.0 是否支持热更
709
+ *
710
+ */
711
+ isHotter() {
712
+ return !!this.getSetting("hotter");
713
+ }
714
+ /***
715
+ * @version 1.0 是否支持资源文件热更
716
+ */
717
+ isHotterSysConfig() {
718
+ return !!this.getSetting(FastCarMetaData_1.FastCarMetaData.HotterSysConfig);
719
+ }
720
+ /***
721
+ * @version 1.0 指定热更新文件
722
+ *
723
+ */
724
+ specifyHotUpdate(fp) {
725
+ if (fs.existsSync(fp)) {
726
+ this.emit("reload", fp);
727
+ }
728
+ }
729
+ /***
730
+ * @version 1.0 获取进程的信息
731
+ *
732
+ */
733
+ getMemoryUsage() {
734
+ let { rss, heapTotal, heapUsed, arrayBuffers, external } = process.memoryUsage();
735
+ return {
736
+ pid: process.pid, //进程id
737
+ name: this.sysConfig.application.name,
738
+ env: this.sysConfig.application.env,
739
+ version: this.sysConfig.application.version,
740
+ rss: FileUtil_1.default.formatBytes(rss), //常住集大小
741
+ heapTotal: FileUtil_1.default.formatBytes(heapTotal), //V8 的内存使用量
742
+ heapUsed: FileUtil_1.default.formatBytes(heapUsed),
743
+ arrayBuffers: FileUtil_1.default.formatBytes(arrayBuffers), //包含所有的Buffer
744
+ external: FileUtil_1.default.formatBytes(external), //绑定到 V8 管理的 JavaScript 对象的 C++ 对象的内存使用量
745
+ uptime: DateUtil_1.default.getTimeStr(Date.now() - this.liveTime), //运行时间
746
+ };
747
+ }
748
+ getLogger(category = CommonConstant_1.CommonConstant.SYSLOGGER) {
749
+ let logger = this.loggerFactory.getLogger(category);
750
+ if (!logger) {
751
+ return this.loggerFactory.addLogger(category);
752
+ }
753
+ return logger;
754
+ }
755
+ };
756
+ __decorate([
757
+ (0, annotation_1.Log)("sys"),
758
+ __metadata("design:type", Logger_1.default)
759
+ ], FastCarApplication.prototype, "sysLogger", void 0);
760
+ FastCarApplication = FastCarApplication_1 = __decorate([
761
+ Component_1.default,
762
+ __metadata("design:paramtypes", [])
763
+ ], FastCarApplication);
764
+ exports.default = FastCarApplication;