@@ -1,11 +1,13 @@ | |||
package cc.smtweb.system.bpm.spring; | |||
package cc.smtweb.system.bpm.web; | |||
import cc.smtweb.framework.core.annotation.SwService; | |||
import cc.smtweb.framework.core.annotation.SwStartListener; | |||
import cc.smtweb.framework.core.cache.CacheManager; | |||
import cc.smtweb.framework.core.common.SwConsts; | |||
import cc.smtweb.framework.core.db.cache.ModelTableCache; | |||
import cc.smtweb.framework.core.db.impl.DatabaseUtil; | |||
import cc.smtweb.framework.core.db.vo.ModelCatalog; | |||
import cc.smtweb.framework.core.mvc.controller.IStartListener; | |||
import cc.smtweb.framework.core.mvc.service.TreeHelper; | |||
import cc.smtweb.framework.core.systask.TaskStartEvent; | |||
import cc.smtweb.framework.core.systask.WebStartedEvent; | |||
@@ -19,12 +21,14 @@ import org.springframework.stereotype.Component; | |||
/** | |||
* Created by Akmm at 2022/7/8 19:57 | |||
*/ | |||
@Component | |||
@Order(SwConsts.DEFAULT_ORDER + 1) | |||
public class BpmStartedListener implements ApplicationListener<ApplicationStartedEvent> { | |||
@SwStartListener() | |||
public class BpmStartedListener implements IStartListener { | |||
public int order() { | |||
return SwConsts.DEFAULT_ORDER + 1; | |||
} | |||
@Override | |||
public void onApplicationEvent(ApplicationStartedEvent event) { | |||
public void run() { | |||
//初始化数据库 | |||
new DatabaseUtil(true, false).checkDb(); | |||
//初始化缓存 |
@@ -497,6 +497,13 @@ public class ModelFormHelper { | |||
} else { | |||
field.put("maxlength", 0); | |||
} | |||
Map lookup = (Map)field.get("lookup"); | |||
if (lookup!=null){ | |||
long widgetId = MapUtil.readLong(lookup, "widgetId",-1L); | |||
if(widgetId>0){ | |||
setWidget.add(widgetId); | |||
} | |||
} | |||
} | |||
} | |||
@@ -520,7 +527,7 @@ public class ModelFormHelper { | |||
col.put("editor", dtb != null ? dtb.editor: SwEnum.EditorType.INPUT.value); | |||
if (field.getLink() == 0L) return; | |||
Set<ModelForm> set = ModelFormCache.getInstance().getListByTable(field.getLink(), SwEnum.FormType.WIDGET.value); | |||
if (set == null || set.isEmpty()) return; | |||
ModelForm form = set.iterator().next(); | |||
@@ -166,7 +166,7 @@ public class FlowInstance { | |||
getProcInstDao().updateEntity(procInst); | |||
buildBillLog(FlowConst.Button.HANDLE.value, actInst, null); | |||
// comp.transCallback(FlowConst.FlowOptType.RETAKE.value, act_inst, null); | |||
listener.handle(actInst); | |||
} | |||
//从页面参数加载流程实例 | |||
@@ -509,6 +509,7 @@ public class FlowInstance { | |||
getProcInstDao().updateEntity(procInst); | |||
buildBillLog(FlowConst.Button.SUBMIT.value, actInst, listInsertTask); | |||
listener.submit(actInst, listInsertTask); | |||
} | |||
@@ -569,7 +570,7 @@ public class FlowInstance { | |||
getProcInstDao().updateEntity(procInst); | |||
buildBillLog(FlowConst.Button.SUBMIT.value, actInst, listInsertTask); | |||
// comp.transCallback(FlowConst.Button.SUBMIT.value, actInst, listInsertTask); | |||
listener.submit(actInst, listInsertTask); | |||
} | |||
@@ -613,7 +614,7 @@ public class FlowInstance { | |||
getProcInstDao().updateEntity(procInst); | |||
buildBillLog(FlowConst.Button.DISUSE.value, actInst, null); | |||
// comp.transCallback(FlowConst.FlowOptType.DISUSE.value, actInst, null); | |||
listener.disuse(actInst); | |||
} | |||
/** | |||
@@ -714,6 +715,7 @@ public class FlowInstance { | |||
new_acts.clear(); | |||
new_acts.add(old_act); | |||
buildBillLog(FlowConst.Button.RETAKE.value, actInst, new_acts); | |||
listener.retake(actInst, new_acts); | |||
// comp.transCallback(FlowConst.Button.RETAKE.value, actInst, new_acts); | |||
} else { | |||
List<Task> new_acts = provider.findAfterTasks(actInst.getId()); | |||
@@ -739,7 +741,7 @@ public class FlowInstance { | |||
getProcInstDao().updateEntity(procInst); | |||
buildBillLog(FlowConst.Button.RETAKE.value, actInst, new_acts); | |||
// comp.transCallback(FlowConst.FlowOptType.RETAKE.value, actInst, new_acts); | |||
listener.retake(actInst, new_acts); | |||
} | |||
} | |||
@@ -788,6 +790,7 @@ public class FlowInstance { | |||
getProcInstDao().updateEntity(procInst); | |||
buildBillLog(FlowConst.Button.REJECT.value, actInst, new_acts); | |||
listener.reject(actInst, new_acts); | |||
// comp.transCallback(FlowConst.FlowOptType.REJECT.value, actInst, new_acts); | |||
} | |||
@@ -831,44 +834,10 @@ public class FlowInstance { | |||
make_acts.add(make_act); | |||
buildBillLog(FlowConst.Button.REJECT.value, actInst, make_acts); | |||
// comp.transCallback(FlowConst.FlowOptType.REJECT.value, actInst, make_acts); | |||
listener.reject(actInst, make_acts); | |||
} | |||
/** | |||
* 办理 | |||
* | |||
* @throws Exception | |||
*/ | |||
/* | |||
public void handler(AbsBillWfComponent comp) { | |||
String user_id = context.getLoginInfo().getUserId(); | |||
//校验权限,当前人员有权限干不,没权限直接抛异常 | |||
checkPermission(); | |||
if (actInst.getStatu() != FlowConst.ActivityStatu.WAIT.value) { | |||
throw new BizException("当前任务非待办状态,不能办理失败!"); | |||
} | |||
ActinstDao actDao = new ActinstDao(); | |||
actInst.setHandler(user_id); | |||
actInst.setStartTime(DateUtil.nowDateTimeLong()); | |||
actInst.setStatu(FlowConst.ActivityStatu.HANDLE.value); | |||
procInst.setTaskId(actInst.getEntityId()); | |||
procInst.setTaskName(ActivityEntityBuffer.getInstance().getNameById(actInst.getActId())); | |||
procInst.setStatu(FlowConst.InstanceStatu.RUNING.value); | |||
actDao.update(actInst); | |||
new ProcinstDao().update(procInst); | |||
buildBillLog(FlowConst.FlowOptType.HANDLER.value, actInst, null); | |||
// comp.transCallback(FlowConst.FlowOptType.RETAKE.value, act_inst, null); | |||
} | |||
*/ | |||
/** | |||
* 状态变更,构建日志 | |||
*/ | |||
protected void buildBillLog(final String flow_opt, Task srcTask, List<Task> dstTasks) { | |||
@@ -1,6 +1,9 @@ | |||
package cc.smtweb.system.bpm.web.engine.flow; | |||
import cc.smtweb.framework.core.common.SwMap; | |||
import cc.smtweb.system.bpm.web.engine.flow.entity.Task; | |||
import java.util.List; | |||
/** | |||
* Created by Akmm at 2022-08-20 16:12 | |||
@@ -9,4 +12,16 @@ import cc.smtweb.framework.core.common.SwMap; | |||
public class FlowListener { | |||
//设置条件计算参数 | |||
public void setExprParam(SwMap param){} | |||
//提交 | |||
public void submit(Task srcTask, List<Task> dstTasks) {} | |||
//取回 | |||
public void retake(Task srcTask, List<Task> dstTasks) {} | |||
//驳回 | |||
public void reject(Task srcTask, List<Task> dstTasks) {} | |||
//办理,签收 | |||
public void handle(Task srcTask) {} | |||
//作废 | |||
public void disuse(Task srcTask) {} | |||
} |
@@ -18,10 +18,9 @@ | |||
<#list fields as filter> | |||
{ | |||
"id": "id${newId()}", | |||
"type": "fx-${filter.editor}", | |||
"type": "${filter.editor}", | |||
"props": { | |||
"label": "${filter.label}", | |||
"type": "text", | |||
<#if filter.maxlength gt 0> | |||
"maxlength": ${filter.maxlength}, | |||
</#if> | |||
@@ -31,6 +30,13 @@ | |||
"affixError": false, | |||
"dataset": "${filter.dataset}", | |||
"field": "${filter.id}", | |||
<#if filter.lookup??> | |||
"lookup": { | |||
<#list filter.lookup as k, v> | |||
"${k}": "${v}" <#if k_has_next>,</#if> | |||
</#list> | |||
}, | |||
</#if> | |||
"name": "${filter.name}" | |||
}, | |||
"events": {} | |||
@@ -39,10 +39,9 @@ | |||
<#list fields as filter > | |||
{ | |||
"id": "id${newId()}", | |||
"type": "fx-${filter.editor}", | |||
"type": "${filter.editor}", | |||
"props": { | |||
"label": "${filter.label}", | |||
"type": "text", | |||
<#if filter.maxlength gt 0 > | |||
"maxlength": ${filter.maxlength}, | |||
</#if> | |||
@@ -50,6 +49,13 @@ | |||
"labelWidth": 100, | |||
"dataset": "${filter.dataset}", | |||
"field": "${filter.id}", | |||
<#if filter.lookup??> | |||
"lookup": { | |||
<#list filter.lookup as k, v> | |||
"${k}": "${v}" <#if k_has_next>,</#if> | |||
</#list> | |||
}, | |||
</#if> | |||
"name": "${filter.name}" | |||
}, | |||
"events": {} | |||
@@ -156,15 +156,22 @@ | |||
"id": "id${newId()}", | |||
<#if (dfield.readonly = true)> | |||
"type": "fx-text", | |||
"disabled": true, | |||
<#else> | |||
"type": "fx-${dfield.editor}", | |||
"type": "${dfield.editor}", | |||
</#if> | |||
"props": { | |||
"label": "${dfield.label}", | |||
"type": "text", | |||
"dataset": "${dfield.dataset}", | |||
"field": "${dfield.id}", | |||
"required": "${field.required}", | |||
"required": "${dfield.required}", | |||
<#if dfield.lookup??> | |||
"lookup": { | |||
<#list dfield.lookup as k, v> | |||
"${k}": "${v}" <#if k_has_next>,</#if> | |||
</#list> | |||
}, | |||
</#if> | |||
<#if dfield.maxlength gt 0> | |||
"maxlength": ${dfield.maxlength}, | |||
</#if> | |||
@@ -3,7 +3,9 @@ package cc.smtweb.framework.core; | |||
import cc.smtweb.framework.core.cache.CacheManager; | |||
import cc.smtweb.framework.core.common.SwConsts; | |||
import cc.smtweb.framework.core.db.impl.DatabaseUtil; | |||
import cc.smtweb.framework.core.mvc.controller.IStartListener; | |||
import cc.smtweb.framework.core.mvc.controller.scan.ApplicationScanner; | |||
import cc.smtweb.framework.core.mvc.controller.scan.BeanManager; | |||
import cc.smtweb.framework.core.systask.TaskStartEvent; | |||
import cc.smtweb.framework.core.systask.WebStartedEvent; | |||
import lombok.SneakyThrows; | |||
@@ -13,24 +15,32 @@ import org.springframework.context.ConfigurableApplicationContext; | |||
import org.springframework.core.annotation.Order; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Comparator; | |||
import java.util.List; | |||
/** | |||
* 执行接口扫描任务 | |||
*/ | |||
@Component | |||
@Order(SwConsts.DEFAULT_ORDER) | |||
public class CoreApplicationStartedListener implements ApplicationListener<ApplicationStartedEvent> { | |||
@SneakyThrows | |||
@Override | |||
public void onApplicationEvent(ApplicationStartedEvent event) { | |||
System.out.println("onApplicationEvent============="); | |||
ConfigurableApplicationContext applicationContext = event.getApplicationContext(); | |||
applicationContext.publishEvent(new TaskStartEvent()); | |||
//包扫描 | |||
ApplicationScanner.scan(applicationContext); | |||
@SneakyThrows | |||
@Override | |||
public void onApplicationEvent(ApplicationStartedEvent event) { | |||
System.out.println("onApplicationEvent============="); | |||
ConfigurableApplicationContext applicationContext = event.getApplicationContext(); | |||
// 通知 controller 正式使用 | |||
applicationContext.publishEvent(new WebStartedEvent()); | |||
System.out.println("start end============="); | |||
} | |||
applicationContext.publishEvent(new TaskStartEvent()); | |||
//包扫描 | |||
ApplicationScanner.scan(applicationContext); | |||
List<IStartListener> list = BeanManager.getInstance().getStartListeners(); | |||
list.sort(Comparator.comparingInt(IStartListener::order)); | |||
for (IStartListener sl : list) { | |||
sl.run(); | |||
} | |||
// 通知 controller 正式使用 | |||
applicationContext.publishEvent(new WebStartedEvent()); | |||
SwConsts.SysParam.SYS_STARTED = true; | |||
System.out.println("start end============="); | |||
} | |||
} |
@@ -7,6 +7,9 @@ import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.ComponentScan; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.scheduling.annotation.EnableScheduling; | |||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | |||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; | |||
/** | |||
* @author kevin | |||
@@ -14,7 +17,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; | |||
@Configuration | |||
@ComponentScan | |||
@EnableScheduling | |||
public class CoreAutoConfiguration { | |||
public class CoreAutoConfiguration implements WebMvcConfigurer { | |||
/** | |||
* ID生成器的分步式机器码(1-1023) | |||
*/ | |||
@@ -30,4 +33,9 @@ public class CoreAutoConfiguration { | |||
public ControllerConfig coreControllerConfig() { | |||
return new ControllerConfig("core", "cc.smtweb.framework.core"); | |||
} | |||
@Override | |||
public void addInterceptors(InterceptorRegistry registry) { | |||
registry.addInterceptor(new CoreInterceptor()); | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
package cc.smtweb.framework.core; | |||
import cc.smtweb.framework.core.common.SwConsts; | |||
import cc.smtweb.framework.core.exception.BizException; | |||
import org.springframework.web.servlet.HandlerInterceptor; | |||
import org.springframework.web.servlet.ModelAndView; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
/** | |||
* Created by Akmm at 2022-08-24 10:53 | |||
*/ | |||
public class CoreInterceptor implements HandlerInterceptor { | |||
@Override | |||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |||
if (!SwConsts.SysParam.SYS_STARTED) throw new BizException("系统启动中,请稍候..."); | |||
return HandlerInterceptor.super.preHandle(request, response, handler); | |||
} | |||
@Override | |||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { | |||
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); | |||
} | |||
@Override | |||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { | |||
HandlerInterceptor.super.afterCompletion(request, response, handler, ex); | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
package cc.smtweb.framework.core.annotation; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
/** | |||
* 启动监听,order为执行顺序,请按SWConsts.DEFAULT_ORDER + XXX | |||
* @author zhenggm | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target({ElementType.TYPE}) | |||
public @interface SwStartListener { | |||
// int order() default 0; | |||
} |
@@ -4,8 +4,14 @@ package cc.smtweb.framework.core.common; | |||
* Created by Akmm at 2022/3/23 9:46 | |||
*/ | |||
public interface SwConsts { | |||
class SysParam { | |||
//系统启动完成 | |||
public static boolean SYS_STARTED = false; | |||
} | |||
//开发调试模式 | |||
boolean SYS_DEBUG = true; | |||
int DEFAULT_ORDER = 1; | |||
//缓存中:树节点按parent的key | |||
String KEY_PARENT_ID = "pr"; | |||
@@ -0,0 +1,11 @@ | |||
package cc.smtweb.framework.core.mvc.controller; | |||
/** | |||
* Created by Akmm at 2022-08-24 09:26 | |||
* 启动监听 | |||
*/ | |||
public interface IStartListener { | |||
//启动执行顺序 | |||
int order(); | |||
void run(); | |||
} |
@@ -20,38 +20,39 @@ import java.util.Map; | |||
/** | |||
* 服务方法调用管理,通过url进行API调用 | |||
* | |||
* @author xkliu | |||
*/ | |||
@Slf4j | |||
public class MethodAccessManager { | |||
private Map<String, IMethodAccess> controllers; | |||
private IBeanContext beanContext; | |||
private PermInterceptor permInterceptor; | |||
private SchedulerTaskManager schedulerTaskManager; | |||
private MethodAccess[] destroyMethods; | |||
@Getter | |||
private CacheManager cacheManager; | |||
public MethodAccessManager(RedisManager redisManager, CacheManager cacheManager) { | |||
permInterceptor = new PermInterceptor(redisManager); | |||
this.cacheManager = cacheManager; | |||
} | |||
// 执行控制器方法 | |||
Object invoke(String url, Map<String, Object> params, String body, HttpServletRequest request, HttpServletResponse response) throws Exception { | |||
// 调用普通方法 | |||
private Map<String, IMethodAccess> controllers; | |||
private IBeanContext beanContext; | |||
private PermInterceptor permInterceptor; | |||
private SchedulerTaskManager schedulerTaskManager; | |||
private MethodAccess[] destroyMethods; | |||
@Getter | |||
private CacheManager cacheManager; | |||
public MethodAccessManager(RedisManager redisManager, CacheManager cacheManager) { | |||
permInterceptor = new PermInterceptor(redisManager); | |||
this.cacheManager = cacheManager; | |||
} | |||
// 执行控制器方法 | |||
Object invoke(String url, Map<String, Object> params, String body, HttpServletRequest request, HttpServletResponse response) throws Exception { | |||
// 调用普通方法 | |||
// String url = module + "/" + service + "/" + method; | |||
IMethodAccess methodAccess = controllers.get(url); | |||
IMethodAccess methodAccess = controllers.get(url); | |||
if (methodAccess != null) { | |||
permInterceptor.preHandle(request, methodAccess.getPerm()); | |||
if (methodAccess != null) { | |||
permInterceptor.preHandle(request, methodAccess.getPerm()); | |||
return methodAccess.invoke(beanContext, params, body, request); | |||
} | |||
return methodAccess.invoke(beanContext, params, body, request); | |||
} | |||
// TODO 调用默认方法 | |||
// TODO 调用默认方法 | |||
// url = module + "/" + service + "/"; | |||
// | |||
// methodAccess = controllers.get(url); | |||
@@ -63,43 +64,43 @@ public class MethodAccessManager { | |||
// return methodAccess.invoke(beanContext, params, body, request, response); | |||
// } | |||
return R.error(404, "not find api:" + url); | |||
} | |||
public void init(BeanManager beanManager, ISwCache<Long, PermChecker> cache) { | |||
this.beanContext = beanManager.getBeanContext(); | |||
this.controllers = beanManager.getControllers(); | |||
this.destroyMethods = beanManager.loadDestroyMethods(); | |||
this.permInterceptor.setCache(cache); | |||
// 启动定时任务 | |||
this.schedulerTaskManager = SchedulerTaskManager.build(beanContext, beanManager.getTasks()); | |||
if (this.schedulerTaskManager != null) { | |||
// 设置用于外部服务调用 | |||
SchedulerManager schedulerManager = this.beanContext.getBean(SchedulerManager.class); | |||
if (schedulerManager != null) { | |||
schedulerManager.install(this.schedulerTaskManager); | |||
} else { | |||
log.error("not find spring bean schedulerManager"); | |||
} | |||
return R.error(404, "not find api:" + url); | |||
} | |||
} | |||
void showdown() { | |||
// 强行关闭定时任务 | |||
if (this.schedulerTaskManager != null) { | |||
this.schedulerTaskManager.shutdown(); | |||
public void init(BeanManager beanManager, ISwCache<Long, PermChecker> cache) { | |||
this.beanContext = beanManager.getBeanContext(); | |||
this.controllers = beanManager.getControllers(); | |||
this.destroyMethods = beanManager.loadDestroyMethods(); | |||
this.permInterceptor.setCache(cache); | |||
// 启动定时任务 | |||
this.schedulerTaskManager = SchedulerTaskManager.build(beanContext, beanManager.getTasks()); | |||
if (this.schedulerTaskManager != null) { | |||
// 设置用于外部服务调用 | |||
SchedulerManager schedulerManager = this.beanContext.getBean(SchedulerManager.class); | |||
if (schedulerManager != null) { | |||
schedulerManager.install(this.schedulerTaskManager); | |||
} else { | |||
log.error("not find spring bean schedulerManager"); | |||
} | |||
} | |||
} | |||
if (destroyMethods != null) { | |||
for (MethodAccess methodAccess : destroyMethods) { | |||
try { | |||
methodAccess.invoke(beanContext); | |||
} catch (Exception e) { | |||
log.error(methodAccess.fullName(), e); | |||
void showdown() { | |||
// 强行关闭定时任务 | |||
if (this.schedulerTaskManager != null) { | |||
this.schedulerTaskManager.shutdown(); | |||
} | |||
if (destroyMethods != null) { | |||
for (MethodAccess methodAccess : destroyMethods) { | |||
try { | |||
methodAccess.invoke(beanContext); | |||
} catch (Exception e) { | |||
log.error(methodAccess.fullName(), e); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -1,6 +1,8 @@ | |||
package cc.smtweb.framework.core.mvc.controller.scan; | |||
import cc.smtweb.framework.core.exception.SwException; | |||
import cc.smtweb.framework.core.mvc.controller.IActionManager; | |||
import cc.smtweb.framework.core.mvc.controller.IStartListener; | |||
import cc.smtweb.framework.core.mvc.controller.access.ControllerAccess; | |||
import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess; | |||
import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; | |||
@@ -17,145 +19,163 @@ import java.util.Map; | |||
@Slf4j | |||
public class BeanManager implements IActionManager { | |||
private ApplicationContext applicationContext; | |||
private List<ControllerAccess> beans = new ArrayList<>(); | |||
private Map<Class<?>, Object> beanMap = new HashMap<>(); | |||
private List<ControllerAccess> singletonServices = new ArrayList<>(); | |||
@Getter | |||
private Map<String, IMethodAccess> controllers = new HashMap<>(); | |||
@Getter | |||
private BeanContext beanContext; | |||
@Getter | |||
private List<SchedulerMethodAccess> tasks = new ArrayList<>(); | |||
private List<OrderMethodAccess> constructMethods = new ArrayList<>(); | |||
private List<OrderMethodAccess> destroyMethods = new ArrayList<>(); | |||
private List<IMethodAccess> beanMethods = new ArrayList<>(); | |||
private Map<String, Class<?>> mapTableClass = new HashMap<>(); | |||
private static BeanManager instance = null; | |||
static { | |||
instance = new BeanManager(); | |||
} | |||
public static BeanManager getInstance() { | |||
return instance; | |||
} | |||
private BeanManager() { | |||
} | |||
public void install(ApplicationContext applicationContext) { | |||
this.applicationContext = applicationContext; | |||
beanContext = new BeanContext(beanMap, applicationContext); | |||
} | |||
private ApplicationContext applicationContext; | |||
private List<ControllerAccess> beans = new ArrayList<>(); | |||
private Map<Class<?>, Object> beanMap = new HashMap<>(); | |||
private List<ControllerAccess> singletonServices = new ArrayList<>(); | |||
@Getter | |||
private Map<String, IMethodAccess> controllers = new HashMap<>(); | |||
@Getter | |||
private BeanContext beanContext; | |||
@Getter | |||
private List<SchedulerMethodAccess> tasks = new ArrayList<>(); | |||
private List<OrderMethodAccess> constructMethods = new ArrayList<>(); | |||
private List<OrderMethodAccess> destroyMethods = new ArrayList<>(); | |||
private List<IMethodAccess> beanMethods = new ArrayList<>(); | |||
private Map<String, Class<?>> mapTableClass = new HashMap<>(); | |||
private List<IStartListener> listStartListener = new ArrayList<>(); | |||
private static BeanManager instance = null; | |||
static { | |||
instance = new BeanManager(); | |||
} | |||
public void init() throws Exception { | |||
// 读取DbEngine,用以初始化 EntityDao | |||
beanContext.init(); | |||
public static BeanManager getInstance() { | |||
return instance; | |||
} | |||
// 自动设置@SwBean注解对象的@SwParam注解属性 | |||
for (ControllerAccess controllerAccess: beans) { | |||
Object bean = controllerAccess.getSingletonInstance(); | |||
addBeanMap(controllerAccess.getBeanType(), bean); | |||
private BeanManager() { | |||
} | |||
// 映射单例Bean字段值 | |||
for (ControllerAccess controllerAccess: beans) { | |||
controllerAccess.initSingletonFields(beanContext, null); | |||
public void install(ApplicationContext applicationContext) { | |||
this.applicationContext = applicationContext; | |||
beanContext = new BeanContext(beanMap, applicationContext); | |||
} | |||
for (IMethodAccess methodAccess: beanMethods) { | |||
Object bean = methodAccess.invoke(beanContext); | |||
addBeanMap(methodAccess.getReturnType(), bean); | |||
log.debug("[smt]init bean:" + methodAccess.getReturnType() + " by " + methodAccess.fullName()); | |||
public void init() throws Exception { | |||
// 读取DbEngine,用以初始化 EntityDao | |||
beanContext.init(); | |||
// 自动设置@SwBean注解对象的@SwParam注解属性 | |||
for (ControllerAccess controllerAccess : beans) { | |||
Object bean = controllerAccess.getSingletonInstance(); | |||
addBeanMap(controllerAccess.getBeanType(), bean); | |||
} | |||
// 映射单例Bean字段值 | |||
for (ControllerAccess controllerAccess : beans) { | |||
controllerAccess.initSingletonFields(beanContext, null); | |||
} | |||
for (IMethodAccess methodAccess : beanMethods) { | |||
Object bean = methodAccess.invoke(beanContext); | |||
addBeanMap(methodAccess.getReturnType(), bean); | |||
log.debug("[smt]init bean:" + methodAccess.getReturnType() + " by " + methodAccess.fullName()); | |||
} | |||
// 映射单例控制器字段值 | |||
for (ControllerAccess controllerAccess : singletonServices) { | |||
controllerAccess.initSingletonFields(beanContext, null); | |||
} | |||
// 执行初始化方法 | |||
constructMethods.sort((a, b) -> a.order - b.order); | |||
for (OrderMethodAccess orderMethodAccess : constructMethods) { | |||
IMethodAccess methodAccess = orderMethodAccess.methodAccess; | |||
methodAccess.invoke(beanContext); | |||
} | |||
} | |||
// 映射单例控制器字段值 | |||
for (ControllerAccess controllerAccess: singletonServices) { | |||
controllerAccess.initSingletonFields(beanContext, null); | |||
private void addBeanMap(Class<?> beanType, Object bean) { | |||
if (bean != null) { | |||
beanMap.put(beanType, bean); | |||
} | |||
} | |||
// 执行初始化方法 | |||
constructMethods.sort((a, b) -> a.order - b.order); | |||
IMethodAccess putIfAbsent(String url, IMethodAccess methodAccess) { | |||
return controllers.putIfAbsent(url, methodAccess); | |||
} | |||
for (OrderMethodAccess orderMethodAccess: constructMethods) { | |||
IMethodAccess methodAccess = orderMethodAccess.methodAccess; | |||
methodAccess.invoke(beanContext); | |||
void addBean(ControllerAccess controllerAccess) { | |||
this.beans.add(controllerAccess); | |||
} | |||
} | |||
private void addBeanMap(Class<?> beanType, Object bean) { | |||
if (bean != null) { | |||
beanMap.put(beanType, bean); | |||
void addSingletonController(ControllerAccess controllerAccess) { | |||
this.singletonServices.add(controllerAccess); | |||
} | |||
} | |||
IMethodAccess putIfAbsent(String url, IMethodAccess methodAccess) { | |||
return controllers.putIfAbsent(url, methodAccess); | |||
} | |||
void addTask(SchedulerMethodAccess schedulerMethodAccess) { | |||
this.tasks.add(schedulerMethodAccess); | |||
} | |||
void addBean(ControllerAccess controllerAccess) { | |||
this.beans.add(controllerAccess); | |||
} | |||
void addConstruct(int order, MethodAccess methodAccess) { | |||
constructMethods.add(new OrderMethodAccess(order, methodAccess)); | |||
} | |||
void addSingletonController(ControllerAccess controllerAccess) { | |||
this.singletonServices.add(controllerAccess); | |||
} | |||
void addDestroy(int order, MethodAccess methodAccess) { | |||
destroyMethods.add(new OrderMethodAccess(order, methodAccess)); | |||
} | |||
void addTask(SchedulerMethodAccess schedulerMethodAccess) { | |||
this.tasks.add(schedulerMethodAccess); | |||
} | |||
public MethodAccess[] loadDestroyMethods() { | |||
if (destroyMethods.isEmpty()) { | |||
return null; | |||
} | |||
void addConstruct(int order, MethodAccess methodAccess) { | |||
constructMethods.add(new OrderMethodAccess(order, methodAccess)); | |||
} | |||
destroyMethods.sort((a, b) -> b.order - a.order); | |||
void addDestroy(int order, MethodAccess methodAccess) { | |||
destroyMethods.add(new OrderMethodAccess(order, methodAccess)); | |||
} | |||
int size = destroyMethods.size(); | |||
MethodAccess[] result = new MethodAccess[size]; | |||
for (int i = 0; i < size; i++) { | |||
result[i] = destroyMethods.get(i).methodAccess; | |||
} | |||
public MethodAccess[] loadDestroyMethods() { | |||
if (destroyMethods.isEmpty()) { | |||
return null; | |||
return result; | |||
} | |||
destroyMethods.sort((a, b) -> b.order - a.order); | |||
int size = destroyMethods.size(); | |||
MethodAccess[] result = new MethodAccess[size]; | |||
for (int i = 0; i < size; i++) { | |||
result[i] = destroyMethods.get(i).methodAccess; | |||
void addBeanMethod(IMethodAccess methodAccess) { | |||
this.beanMethods.add(methodAccess); | |||
} | |||
return result; | |||
} | |||
void addStartListener(Class<?> clazz) { | |||
if (!IStartListener.class.isAssignableFrom(clazz)) { | |||
throw new SwException("启动监听类必须实现IStartListener接口!"); | |||
} | |||
try { | |||
IStartListener startListener = (IStartListener) clazz.newInstance(); | |||
listStartListener.add(startListener); | |||
} catch (Exception e) { | |||
throw new SwException(e); | |||
} | |||
} | |||
void addBeanMethod(IMethodAccess methodAccess) { | |||
this.beanMethods.add(methodAccess); | |||
} | |||
public List<IStartListener> getStartListeners() { | |||
return listStartListener; | |||
} | |||
@Override | |||
public boolean api(String url, IMethodAccess methodAccess) { | |||
return this.putIfAbsent(url, methodAccess) == null; | |||
} | |||
@Override | |||
public boolean api(String url, IMethodAccess methodAccess) { | |||
return this.putIfAbsent(url, methodAccess) == null; | |||
} | |||
public void addTableClass(String tableName, Class<?> clzz) { | |||
mapTableClass.put(tableName, clzz); | |||
} | |||
public void addTableClass(String tableName, Class<?> clzz) { | |||
mapTableClass.put(tableName, clzz); | |||
} | |||
public Class<?> getTableClass(String tableName) { | |||
return mapTableClass.get(tableName); | |||
} | |||
public Class<?> getTableClass(String tableName) { | |||
return mapTableClass.get(tableName); | |||
} | |||
private static class OrderMethodAccess { | |||
private final int order; | |||
private final MethodAccess methodAccess; | |||
private static class OrderMethodAccess { | |||
private final int order; | |||
private final MethodAccess methodAccess; | |||
OrderMethodAccess(int order, MethodAccess methodAccess) { | |||
this.order = order; | |||
this.methodAccess = methodAccess; | |||
OrderMethodAccess(int order, MethodAccess methodAccess) { | |||
this.order = order; | |||
this.methodAccess = methodAccess; | |||
} | |||
} | |||
} | |||
} |
@@ -99,6 +99,11 @@ public class ClassParser { | |||
if (swTable != null) { | |||
beanManager.addTableClass(swTable.value(), clazz); | |||
} | |||
SwStartListener startListener = clazz.getAnnotation(SwStartListener.class); | |||
if (startListener != null) { | |||
beanManager.addStartListener(clazz); | |||
} | |||
} | |||
private ControllerAccess buildControllerAccess(Class<?> clazz, boolean alwaysCreate) { | |||