From 4673ca356ce23629fd9bceb2d2facb31b4d53324 Mon Sep 17 00:00:00 2001 From: Odboy Date: Sun, 27 Jul 2025 13:35:21 +0800 Subject: [PATCH] =?UTF-8?q?refactor(framework):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E6=A0=B8=E5=BF=83=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 SpringBeanHolder 类名,统一命名风格 - 更新相关类的包结构,提高代码可维护性 - 优化部分代码实现,提升性能和可读性 --- .gitignore | 1 + .../docs/.vuepress/public/logo/logo.png | Bin 0 -> 38666 bytes ...istener.java => BeanLoadFinishListener.java} | 2 +- ...ootApplication.java => BootApplication.java} | 6 +++--- ...{RequestHolder.java => CsRequestHolder.java} | 2 +- ...gBeanHolder.java => CsSpringBeanHolder.java} | 16 ++++++++-------- ...ntroller.java => HealthCheckController.java} | 2 +- .../framework/quartz/core/QuartzRunnable.java | 4 ++-- .../src/main/java/cn/odboy/util/IpUtil.java | 4 ++-- .../pipeline/core/PipelineJobBean.java | 16 ++++++++-------- .../pipeline/core/PipelineNodeJobBean.java | 6 +++--- .../controller/SystemQuartzJobController.java | 4 ++-- .../permission/core/CsSecurityHelper.java | 4 ++-- .../framework/quartz/ExecutionJobBean.java | 12 ++++++------ .../src/main/java/cn/odboy/AppRun.java | 4 ++-- 15 files changed, 42 insertions(+), 41 deletions(-) create mode 100644 cutejava-doc/docs/.vuepress/public/logo/logo.png rename cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/{CsBeanLoadFinishListener.java => BeanLoadFinishListener.java} (91%) rename cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/{CsBootApplication.java => BootApplication.java} (94%) rename cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/{RequestHolder.java => CsRequestHolder.java} (94%) rename cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/{SpringBeanHolder.java => CsSpringBeanHolder.java} (89%) rename cutejava/cutejava-framework/src/main/java/cn/odboy/framework/monitor/controller/{CsHealthCheckController.java => HealthCheckController.java} (97%) diff --git a/.gitignore b/.gitignore index cd8c847e..574b56e5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ yarn-error.log* tests/**/coverage/ tests/e2e/reports selenium-debug.log +cutejava-doc # Editor directories and files .idea diff --git a/cutejava-doc/docs/.vuepress/public/logo/logo.png b/cutejava-doc/docs/.vuepress/public/logo/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7cbbd8d2ec066f908547c12bb7abe1b2a3ce6537 GIT binary patch literal 38666 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�2bWFZcVhuUwnOWK|V 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 { +public class BeanLoadFinishListener implements ApplicationListener { @Override public void onApplicationEvent(ContextRefreshedEvent event) { log.info("所有的Bean都加载完毕了"); diff --git a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsBootApplication.java b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/BootApplication.java similarity index 94% rename from cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsBootApplication.java rename to cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/BootApplication.java index 3c99d002..b9628177 100644 --- a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsBootApplication.java +++ b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/BootApplication.java @@ -31,10 +31,10 @@ import java.net.UnknownHostException; * @date 2024-04-20 */ @Slf4j -public class CsBootApplication { +public class BootApplication { @Bean - public SpringBeanHolder springBeanHolder() { - return new SpringBeanHolder(); + public CsSpringBeanHolder springBeanHolder() { + return new CsSpringBeanHolder(); } protected static void inited(ConfigurableApplicationContext application) throws UnknownHostException { diff --git a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/RequestHolder.java b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsRequestHolder.java similarity index 94% rename from cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/RequestHolder.java rename to cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsRequestHolder.java index 94c27068..e54c18b8 100644 --- a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/RequestHolder.java +++ b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsRequestHolder.java @@ -9,7 +9,7 @@ import java.util.Objects; /** * 获取 HttpServletRequest */ -public class RequestHolder { +public class CsRequestHolder { public static HttpServletRequest getHttpServletRequest() { return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); diff --git a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/SpringBeanHolder.java b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsSpringBeanHolder.java similarity index 89% rename from cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/SpringBeanHolder.java rename to cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsSpringBeanHolder.java index b4ce0928..0b9853b9 100644 --- a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/SpringBeanHolder.java +++ b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/context/CsSpringBeanHolder.java @@ -15,7 +15,7 @@ import java.util.List; @Slf4j @SuppressWarnings({"unchecked", "all"}) -public class SpringBeanHolder implements ApplicationContextAware, DisposableBean { +public class CsSpringBeanHolder implements ApplicationContextAware, DisposableBean { private static ApplicationContext applicationContext = null; private static final List CALL_BACKS = new ArrayList<>(); @@ -29,7 +29,7 @@ public class SpringBeanHolder implements ApplicationContextAware, DisposableBean */ public synchronized static void addCallBacks(CallBack callBack) { if (addCallback) { - SpringBeanHolder.CALL_BACKS.add(callBack); + CsSpringBeanHolder.CALL_BACKS.add(callBack); } else { log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName()); callBack.executor(); @@ -109,22 +109,22 @@ public class SpringBeanHolder implements ApplicationContextAware, DisposableBean @Override public void destroy() { - SpringBeanHolder.clearHolder(); + CsSpringBeanHolder.clearHolder(); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - if (SpringBeanHolder.applicationContext != null) { - log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringBeanHolder.applicationContext); + if (CsSpringBeanHolder.applicationContext != null) { + log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + CsSpringBeanHolder.applicationContext); } - SpringBeanHolder.applicationContext = applicationContext; + CsSpringBeanHolder.applicationContext = applicationContext; if (addCallback) { - for (CallBack callBack : SpringBeanHolder.CALL_BACKS) { + for (CallBack callBack : CsSpringBeanHolder.CALL_BACKS) { callBack.executor(); } CALL_BACKS.clear(); } - SpringBeanHolder.addCallback = false; + CsSpringBeanHolder.addCallback = false; } /** diff --git a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/monitor/controller/CsHealthCheckController.java b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/monitor/controller/HealthCheckController.java similarity index 97% rename from cutejava/cutejava-framework/src/main/java/cn/odboy/framework/monitor/controller/CsHealthCheckController.java rename to cutejava/cutejava-framework/src/main/java/cn/odboy/framework/monitor/controller/HealthCheckController.java index d021326a..a5c077ca 100644 --- a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/monitor/controller/CsHealthCheckController.java +++ b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/monitor/controller/HealthCheckController.java @@ -31,7 +31,7 @@ import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor @RequestMapping("/healthCheck") @Api(tags = "系统:健康检查接口") -public class CsHealthCheckController { +public class HealthCheckController { @Autowired private CsHealthCheckPointService healthCheckPointService; diff --git a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/quartz/core/QuartzRunnable.java b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/quartz/core/QuartzRunnable.java index c36488f4..8b027b03 100644 --- a/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/quartz/core/QuartzRunnable.java +++ b/cutejava/cutejava-framework/src/main/java/cn/odboy/framework/quartz/core/QuartzRunnable.java @@ -1,6 +1,6 @@ package cn.odboy.framework.quartz.core; -import cn.odboy.framework.context.SpringBeanHolder; +import cn.odboy.framework.context.CsSpringBeanHolder; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.util.ReflectionUtils; @@ -18,7 +18,7 @@ public class QuartzRunnable implements Callable { private final String params; public QuartzRunnable(String beanName, String methodName, String params) throws NoSuchMethodException, SecurityException { - this.target = SpringBeanHolder.getBean(beanName); + this.target = CsSpringBeanHolder.getBean(beanName); this.params = params; if (StringUtils.isNotBlank(params)) { this.method = target.getClass().getDeclaredMethod(methodName, String.class); diff --git a/cutejava/cutejava-framework/src/main/java/cn/odboy/util/IpUtil.java b/cutejava/cutejava-framework/src/main/java/cn/odboy/util/IpUtil.java index 35749f6b..d323c24b 100644 --- a/cutejava/cutejava-framework/src/main/java/cn/odboy/util/IpUtil.java +++ b/cutejava/cutejava-framework/src/main/java/cn/odboy/util/IpUtil.java @@ -1,6 +1,6 @@ package cn.odboy.util; -import cn.odboy.framework.context.SpringBeanHolder; +import cn.odboy.framework.context.CsSpringBeanHolder; import lombok.experimental.UtilityClass; import net.dreamlu.mica.ip2region.core.Ip2regionSearcher; import net.dreamlu.mica.ip2region.core.IpInfo; @@ -17,7 +17,7 @@ public final class IpUtil { /** * 注入bean */ - private final static Ip2regionSearcher IP_SEARCHER = SpringBeanHolder.getBean(Ip2regionSearcher.class); + private final static Ip2regionSearcher IP_SEARCHER = CsSpringBeanHolder.getBean(Ip2regionSearcher.class); /** * 根据ip获取详细地址 diff --git a/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineJobBean.java b/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineJobBean.java index 0d34edd1..a8e6a4e7 100644 --- a/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineJobBean.java +++ b/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineJobBean.java @@ -10,7 +10,7 @@ import cn.odboy.devops.dal.mysql.PipelineInstanceMapper; import cn.odboy.devops.dal.redis.PipelineInstanceDAO; import cn.odboy.devops.framework.pipeline.model.PipelineNodeTemplateVo; import cn.odboy.devops.service.core.PipelineInstanceNodeService; -import cn.odboy.framework.context.SpringBeanHolder; +import cn.odboy.framework.context.CsSpringBeanHolder; import cn.odboy.framework.exception.BadRequestException; import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; @@ -33,11 +33,11 @@ public class PipelineJobBean implements InterruptableJob { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 获取服务 - PipelineInstanceMapper pipelineInstanceMapper = SpringBeanHolder.getBean(PipelineInstanceMapper.class); - PipelineInstanceNodeService pipelineInstanceNodeService = SpringBeanHolder.getBean(PipelineInstanceNodeService.class); - PipelineInstanceDAO pipelineInstanceDAO = SpringBeanHolder.getBean(PipelineInstanceDAO.class); - PipelineJobManage pipelineJobManage = SpringBeanHolder.getBean(PipelineJobManage.class); - PipelineNodeJobManage pipelineNodeJobManage = SpringBeanHolder.getBean(PipelineNodeJobManage.class); + PipelineInstanceMapper pipelineInstanceMapper = CsSpringBeanHolder.getBean(PipelineInstanceMapper.class); + PipelineInstanceNodeService pipelineInstanceNodeService = CsSpringBeanHolder.getBean(PipelineInstanceNodeService.class); + PipelineInstanceDAO pipelineInstanceDAO = CsSpringBeanHolder.getBean(PipelineInstanceDAO.class); + PipelineJobManage pipelineJobManage = CsSpringBeanHolder.getBean(PipelineJobManage.class); + PipelineNodeJobManage pipelineNodeJobManage = CsSpringBeanHolder.getBean(PipelineNodeJobManage.class); // 参数解析 JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap(); @@ -160,8 +160,8 @@ public class PipelineJobBean implements InterruptableJob { public void interrupt() throws UnableToInterruptJobException { this.interrupted = true; if (this.currentInstanceId != null && StrUtil.isNotBlank(this.currentNodeCode)) { - PipelineInstanceMapper pipelineInstanceMapper = SpringBeanHolder.getBean(PipelineInstanceMapper.class); - PipelineInstanceDAO pipelineInstanceDAO = SpringBeanHolder.getBean(PipelineInstanceDAO.class); + PipelineInstanceMapper pipelineInstanceMapper = CsSpringBeanHolder.getBean(PipelineInstanceMapper.class); + PipelineInstanceDAO pipelineInstanceDAO = CsSpringBeanHolder.getBean(PipelineInstanceDAO.class); int seconds = 30_000; log.info("中断信号已发出,等待最多 {} 秒,若未自行结束则强制终止线程", seconds); diff --git a/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineNodeJobBean.java b/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineNodeJobBean.java index 5559ccaf..677a9c19 100644 --- a/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineNodeJobBean.java +++ b/cutejava/cutejava-module-devops/src/main/java/cn/odboy/devops/framework/pipeline/core/PipelineNodeJobBean.java @@ -5,7 +5,7 @@ import cn.odboy.devops.constant.pipeline.PipelineStatusEnum; import cn.odboy.devops.framework.pipeline.model.PipelineNodeJobExecuteResult; import cn.odboy.devops.framework.pipeline.model.PipelineNodeTemplateVo; import cn.odboy.devops.service.core.PipelineInstanceNodeService; -import cn.odboy.framework.context.SpringBeanHolder; +import cn.odboy.framework.context.CsSpringBeanHolder; import cn.odboy.framework.exception.BadRequestException; import lombok.extern.slf4j.Slf4j; import org.quartz.Job; @@ -25,7 +25,7 @@ import java.util.Date; public class PipelineNodeJobBean implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { - PipelineInstanceNodeService pipelineInstanceNodeService = SpringBeanHolder.getBean(PipelineInstanceNodeService.class); + PipelineInstanceNodeService pipelineInstanceNodeService = CsSpringBeanHolder.getBean(PipelineInstanceNodeService.class); JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap(); long instanceId = jobDataMap.getLong(PipelineConst.INSTANCE_ID); @@ -34,7 +34,7 @@ public class PipelineNodeJobBean implements Job { try { String serviceName = PipelineConst.EXECUTOR_PREFIX + nodeCode; - PipelineNodeJobExecutor pipelineNodeJobExecutor = SpringBeanHolder.getBean(serviceName); + PipelineNodeJobExecutor pipelineNodeJobExecutor = CsSpringBeanHolder.getBean(serviceName); pipelineInstanceNodeService.updatePipelineInstanceNodeByArgs(instanceId, nodeCode, PipelineStatusEnum.RUNNING, PipelineStatusEnum.RUNNING.getDesc()); PipelineNodeJobExecuteResult executeResult = pipelineNodeJobExecutor.execute(jobDataMap); jobExecutionContext.getMergedJobDataMap().put(PipelineConst.LAST_NODE_RESULT, executeResult); diff --git a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemQuartzJobController.java b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemQuartzJobController.java index 7776d5a4..55f6c52e 100644 --- a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemQuartzJobController.java +++ b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/controller/SystemQuartzJobController.java @@ -2,7 +2,7 @@ package cn.odboy.system.controller; import cn.odboy.base.CsPageArgs; import cn.odboy.base.CsResultVo; -import cn.odboy.framework.context.SpringBeanHolder; +import cn.odboy.framework.context.CsSpringBeanHolder; import cn.odboy.framework.exception.BadRequestException; import cn.odboy.system.dal.dataobject.SystemQuartzJobTb; import cn.odboy.system.dal.dataobject.SystemQuartzLogTb; @@ -120,7 +120,7 @@ public class SystemQuartzJobController { private void checkBean(String beanName) { // 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类 // 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。 - if (!SpringBeanHolder.getAllServiceBeanName().contains(beanName)) { + if (!CsSpringBeanHolder.getAllServiceBeanName().contains(beanName)) { throw new BadRequestException("非法的 Bean,请重新输入!"); } } diff --git a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/permission/core/CsSecurityHelper.java b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/permission/core/CsSecurityHelper.java index c63e05b6..20a3e65f 100644 --- a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/permission/core/CsSecurityHelper.java +++ b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/permission/core/CsSecurityHelper.java @@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.jwt.JWT; import cn.hutool.jwt.JWTUtil; import cn.odboy.constant.SystemConst; -import cn.odboy.framework.context.SpringBeanHolder; +import cn.odboy.framework.context.CsSpringBeanHolder; import cn.odboy.system.constant.SystemDataScopeEnum; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; @@ -32,7 +32,7 @@ public class CsSecurityHelper { * @return UserDetails */ public static UserDetails getCurrentUser() { - UserDetailsService userDetailsService = SpringBeanHolder.getBean(UserDetailsService.class); + UserDetailsService userDetailsService = CsSpringBeanHolder.getBean(UserDetailsService.class); return userDetailsService.loadUserByUsername(getCurrentUsername()); } diff --git a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/quartz/ExecutionJobBean.java b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/quartz/ExecutionJobBean.java index 4ce55323..b6c2fdcd 100644 --- a/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/quartz/ExecutionJobBean.java +++ b/cutejava/cutejava-module-system/src/main/java/cn/odboy/system/framework/quartz/ExecutionJobBean.java @@ -5,7 +5,7 @@ import cn.hutool.extra.template.Template; import cn.hutool.extra.template.TemplateConfig; import cn.hutool.extra.template.TemplateEngine; import cn.hutool.extra.template.TemplateUtil; -import cn.odboy.framework.context.SpringBeanHolder; +import cn.odboy.framework.context.CsSpringBeanHolder; import cn.odboy.framework.quartz.core.QuartzRunnable; import cn.odboy.framework.redis.RedisHelper; import cn.odboy.system.dal.dataobject.SystemQuartzJobTb; @@ -31,16 +31,16 @@ public class ExecutionJobBean extends QuartzJobBean { /** * 此处仅供参考,可根据任务执行情况自定义线程池参数 */ - private final ThreadPoolTaskExecutor executor = SpringBeanHolder.getBean("taskAsync"); + private final ThreadPoolTaskExecutor executor = CsSpringBeanHolder.getBean("taskAsync"); @Override public void executeInternal(JobExecutionContext context) { // 获取任务 SystemQuartzJobTb quartzJob = (SystemQuartzJobTb) context.getMergedJobDataMap().get(SystemQuartzJobTb.JOB_KEY); // 获取spring bean - SystemQuartzLogMapper quartzLogMapper = SpringBeanHolder.getBean(SystemQuartzLogMapper.class); - SystemQuartzJobService systemQuartzJobService = SpringBeanHolder.getBean(SystemQuartzJobService.class); - RedisHelper redisHelper = SpringBeanHolder.getBean(RedisHelper.class); + SystemQuartzLogMapper quartzLogMapper = CsSpringBeanHolder.getBean(SystemQuartzLogMapper.class); + SystemQuartzJobService systemQuartzJobService = CsSpringBeanHolder.getBean(SystemQuartzJobService.class); + RedisHelper redisHelper = CsSpringBeanHolder.getBean(RedisHelper.class); String uuid = quartzJob.getUuid(); @@ -88,7 +88,7 @@ public class ExecutionJobBean extends QuartzJobBean { systemQuartzJobService.switchQuartzJobStatus(quartzJob); } if (quartzJob.getEmail() != null) { - SystemEmailService emailService = SpringBeanHolder.getBean(SystemEmailService.class); + SystemEmailService emailService = CsSpringBeanHolder.getBean(SystemEmailService.class); // 邮箱报警 if (StringUtil.isNoneBlank(quartzJob.getEmail())) { SystemSendEmailArgs sendEmailRequest = taskAlarm(quartzJob, ExceptionUtil.stacktraceToString(e)); diff --git a/cutejava/cutejava-starter/src/main/java/cn/odboy/AppRun.java b/cutejava/cutejava-starter/src/main/java/cn/odboy/AppRun.java index b7e68222..0e988bf6 100644 --- a/cutejava/cutejava-starter/src/main/java/cn/odboy/AppRun.java +++ b/cutejava/cutejava-starter/src/main/java/cn/odboy/AppRun.java @@ -1,6 +1,6 @@ package cn.odboy; -import cn.odboy.framework.context.CsBootApplication; +import cn.odboy.framework.context.BootApplication; import com.anwen.mongo.config.MongoPlusAutoConfiguration; import com.anwen.mongo.config.OverrideMongoConfiguration; import io.swagger.annotations.Api; @@ -13,7 +13,7 @@ import java.net.UnknownHostException; @Api(hidden = true) @SpringBootApplication(exclude = OverrideMongoConfiguration.class) @Import(MongoPlusAutoConfiguration.class) -public class AppRun extends CsBootApplication { +public class AppRun extends BootApplication { public static void main(String[] args) throws UnknownHostException { SpringApplication springApplication = new SpringApplication(AppRun.class);