当前位置: 首页 > news >正文

学生个人网页制作免费wordpress文章优化

学生个人网页制作免费,wordpress文章优化,做收费网站,网站设计的难点一、背景 项目存在这样一个场景。程序启动过程中,在Spring的Bean组件注册完毕后,会初始化一些基础数据到数据库中,而项目中有部分定时任务需要依赖这些基础数据才能正常运行。如果直接使用Scheduled注解标注定时任务方法,会导致定…

一、背景

项目存在这样一个场景。程序启动过程中,在Spring的Bean组件注册完毕后,会初始化一些基础数据到数据库中,而项目中有部分定时任务需要依赖这些基础数据才能正常运行。如果直接使用@Scheduled注解标注定时任务方法,会导致定时任务提前执行且执行失败。
基于以上背景,需要将定时任务的注册执行放在数据初始化以后,那么这部分定时任务就需要手动注册且与基础数据初始化操作保持同步执行,保证定时任务的执行一定晚于数据初始化。

二、方案

自定义配置一个定时任务注册器和定时任务执行器,用于处理我们的需求场景。

三、编码实现

通过阅读Spring实现的定时任务源码(篇幅有限,不展开),得知其底层使用的执行器org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler,使用方法org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler#schedule(java.lang.Runnable, org.springframework.scheduling.Trigger)来配置启动定时任务。
因此,我们也使用这个类来启动需要控制执行时机的定时任务,实现代码如下:

package com.jacks.task;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;/*** 配置自定义定时任务执行器** @author Jacks丶* @since 2025-03-16*/
@Configuration
@Slf4j
public class ScheduledConfig implements SchedulingConfigurer {private TaskScheduler scheduler;/*** 配置定时任务注册器,注册器中自定义执行器用于手动执行定时任务** @param taskRegistrar the registrar to be configured*/@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {scheduler = buildScheduler();taskRegistrar.setScheduler(scheduler);}/*** 自定义定时任务执行器,用于执行定时任务** @return 定时任务执行器对象*/@Beanpublic TaskScheduler buildScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setThreadNamePrefix("thread-task-t-");scheduler.setPoolSize(2);return scheduler;}/*** 初始化定时任务,提供给其他Bean对象手动注册定时任务*/public void initScheduledTask() {scheduler.schedule(() -> System.out.println("定时任务执行了..."), new CronTrigger("*/2 * * * * *"));}
}

此时我们的初始化数据的逻辑如下:

package com.jacks.task;import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;import java.time.Duration;/*** SpringBoot启动阶段执行** @author Jacks丶* @since 2025-03-16*/
@Slf4j
public class SpringTask implements SpringApplicationRunListener {public SpringTask(SpringApplication application, String[] args) {log.info("hello init SpringTask.");}/*** Springboot应用已就绪,可在此初始化基础数据** @param context   上下文对象,包含Bean对象,可用于获取定时任务配置Bean,然后调用init方法* @param timeTaken 应用准备所花费时间,可用于了解性能*/@Overridepublic void ready(ConfigurableApplicationContext context, Duration timeTaken) {log.info("开始初始化 ....");try {// 模拟数据初始化耗时Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("结束初始化 ...");// 获取定时任务配置类bean对象执行初始化方法启动定时任务context.getBean(ScheduledConfig.class).initScheduledTask();}
}

启动类如下:

package com.jacks;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;/*** 启动入口类** @author Jacks丶* @since 2025-03-16*/
@EnableScheduling
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

此时可见控制台输出:

2025-03-16 18:43:10.489  INFO 17176 --- [           main] com.jacks.DemoApplication                : Started DemoApplication in 0.88 seconds (JVM running for 1.185)
2025-03-16 18:43:10.490  INFO 17176 --- [           main] com.jacks.task.SpringTask                : 开始初始化 ....
2025-03-16 18:43:12.503  INFO 17176 --- [           main] com.jacks.task.SpringTask                : 结束初始化 ...
2025-03-16 18:43:14.006  INFO 17176 --- [thread-task-t-1] com.jacks.task.ScheduledConfig           : 定时任务执行了...
2025-03-16 18:43:16.001  INFO 17176 --- [thread-task-t-1] com.jacks.task.ScheduledConfig           : 定时任务执行了...
2025-03-16 18:43:18.014  INFO 17176 --- [thread-task-t-1] com.jacks.task.ScheduledConfig           : 定时任务执行了...

四、代码优化

如何优雅的将以上逻辑写入到项目中呢?那就需要引入依赖倒置、单一职责等思想。以上代码中,定时任务是直接定义在initScheduledTask方法中的,当我们需要添加定时任务时,那么就会侵入式的修改com.jacks.task.ScheduledConfig#initScheduledTask
基于单一职责思想,定时任务配置类就只负责初始化注册器、执行器和启动定时任务就好,定时任务的定义逻辑就需要提取出去。
基于依赖倒置的思想,我们需要将注册时依赖的具体实现类优化成接口,所以需要抽取接口,让注册依赖接口,而不是具体实现,我们在新增定时任务时,只需要继承接口编写定时任务逻辑即可,无需侵入式的修改原逻辑。

1、定义接口获取定时任务

package com.jacks.service;import org.springframework.scheduling.config.CronTask;import java.util.List;/*** 定时任务接口,用于提供可执行的定时任务对象** @author Jacks丶* @since 2025-03-16*/
public interface IScheduled {/*** 提供定时任务执行对象** @return 定时任务执行对象列表*/List<CronTask> getScheduledTasks();
}

2、在实现类定义定时任务逻辑

package com.jacks.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.config.CronTask;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;/*** 定时任务方法** @author Jacks丶* @since 2025-03-16*/
@Slf4j
@Service
public class MyService implements IScheduled {/*** 定时任务逻辑*/public void task() {log.info("task1 exec..");}/*** 提供定时任务执行对象,用于初始化注册** @return 定时任务列表*/@Overridepublic List<CronTask> getScheduledTasks() {List<CronTask> cronTasks = new ArrayList<>();cronTasks.add(new CronTask(this::task, "*/2 * * * * *"));return cronTasks;}
}

3、单一职责,定时任务抽取为方法入参

package com.jacks.task;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;import java.util.List;/*** 配置自定义定时任务执行器** @author Jacks丶* @since 2025-03-16*/
@Configuration
@Slf4j
public class ScheduledConfig implements SchedulingConfigurer {private TaskScheduler scheduler;/*** 配置定时任务注册器,注册器中自定义执行器用于手动执行定时任务** @param taskRegistrar the registrar to be configured*/@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {scheduler = buildScheduler();taskRegistrar.setScheduler(scheduler);}/*** 自定义定时任务执行器,用于执行定时任务** @return 定时任务执行器对象*/@Beanpublic TaskScheduler buildScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setThreadNamePrefix("thread-task-t-");scheduler.setPoolSize(2);return scheduler;}/*** 初始化定时任务,提供给其他Bean对象手动注册定时任务** @param cronTasks 待执行的定时任务列表*/public void initScheduledTask(List<CronTask> cronTasks) {cronTasks.forEach(task -> scheduler.schedule(task.getRunnable(), task.getTrigger()));}
}

4、依赖倒置,注册时依赖接口,而不是具体实现

注册定时任务时获取所有com.jacks.service.IScheduled的实现类,并调用getScheduledTasks方法获取定时任务。

package com.jacks.task;import com.jacks.service.IScheduled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.config.CronTask;import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;/*** SpringBoot启动阶段执行** @author Jacks丶* @since 2025-03-16*/
@Slf4j
public class SpringTask implements SpringApplicationRunListener {public SpringTask(SpringApplication application, String[] args) {log.info("hello init SpringTask.");}/*** Springboot应用已就绪,可在此初始化基础数据** @param context   上下文对象,包含Bean对象,可用于获取定时任务配置Bean,然后调用init方法* @param timeTaken 应用准备所花费时间,可用于了解性能*/@Overridepublic void ready(ConfigurableApplicationContext context, Duration timeTaken) {log.info("开始初始化 ....");try {// 模拟数据初始化耗时Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("结束初始化 ...");// 获取定时任务配置类bean对象执行初始化方法启动定时任务Collection<IScheduled> scheduledServiceList = context.getBeansOfType(IScheduled.class).values();List<CronTask> cronTasks = scheduledServiceList.stream().flatMap(service -> service.getScheduledTasks().stream()).collect(Collectors.toList());context.getBean(ScheduledConfig.class).initScheduledTask(cronTasks);}
}

五、结语

以上就是手动控制注册定时任务时机的一种实现方案,并且这种方案不会影响@Scheduled注解注册的定时任务。
希望本篇博客对你有所帮助。

http://www.dtcms.com/a/502440.html

相关文章:

  • 宜昌网站seo收费网络推广策略
  • 国家重大项目建设库网站打不开wordpress个人淘宝
  • 汽配网站建设企业网站建设报价清单
  • 旅游网站开发说明邹城网站网站建设
  • 做个网站做什么呢android sdk官网
  • 重庆专业网站开发服务新闻热点大事件
  • 直播间挂人气自助网站帮客户做网站平台犯法吗
  • 米特号类似网站全国公示信用信息系统
  • 郑州做企业网站的seo百度贴吧
  • 广州骏域网站建设专家手机电脑版健身网站的建设方案
  • 国家建设免费论文网站free wordpress themes
  • 中国建设劳动协会网站wordpress博客点赞
  • 连云港做网站公司哪家好wordpress打赏作者插件
  • wordpress可以建站吗外贸电商平台哪个网站最好
  • 江西恒通建设工程有限公司网站网站建设数据收集方法
  • 建筑企业登录哪个网站成都seo技术经理
  • 培训网站方案wordpress资源管理
  • 建设网站需要多大域名空间烟台网站建设询问臻动传媒
  • 网站建设属于经营什么范围培训课程设计
  • 免费域名网站的wordpress收集客户插件
  • app推广的网站全球域名
  • 蔬莱网站建设中小网站公司做的推广怎么样
  • 成都网站建设常见问题前端低代码开发平台
  • 手机网站布局营销推广工作内容
  • 外贸免费建设网站安徽地图
  • 扁平化网站源码网站建设公司浙江华企
  • 门户网站做的比较好的公司政务公开既网站信息化建设会议
  • 手机端网站变成wap玖玖玖人力资源有限公司
  • 论文中引用网站怎么写江苏景禾瑜博建设工程有限公司网站
  • 自己免费做网站有什么用网站改版前端流程经验