栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

与Quartz完全实现Spring集成,以实现实时通知电子邮件

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

与Quartz完全实现Spring集成,以实现实时通知电子邮件

您可以使用调度库(例如quartz)来提供与Spring框架的轻松集成。

将约会保存在数据库中后,将在所需的时间(例如,开始日期前一小时)安排“发送电子邮件”作业。

“发送电子邮件”作业必须实现

org.quartz.Job
,更具体地讲
execute
,您可以在其中使用
Autowired

SendEmailService
实现的方法。

您可以在下面找到(几乎)完整的示例,以了解如何在代码中实现这种要求。

更新-计划作业的代码

首先,我们定义一个

SchedulingService
接口。

public interface SchedulingService {    startScheduler() throws SchedulerException;    void standbyScheduler() throws SchedulerException;    void shutdownScheduler() throws SchedulerException;    void scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException;}

和相关的执行。

@Servicepublic class SchedulingServiceImpl implements SchedulingService {    @Autowired    private Scheduler scheduler;    @Override    public void startScheduler() throws SchedulerException {        if (!scheduler.isStarted()) { scheduler.start();        }    }    @Override    public void standbyScheduler() throws SchedulerException {        if (!scheduler.isInStandbyMode()) { scheduler.standby();        }    }    @Override    public void shutdownScheduler() throws SchedulerException {        if (!scheduler.isShutdown()) { scheduler.shutdown();        }    }    @Override    public void scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException {        scheduler.scheduleJob(jobDetail, trigger);    }}

然后,

AppointmentServiceImpl
我们有一个
createAppointment()
调用的方法
scheduleSendEmailJob()

@Servicepublic class AppointmentServiceImpl implements AppointmentService {    @Autowired    private SchedulingService schedulingService;    public void createAppointment(Appointment appointment) throws SchedulerException {        // Save appointment to database        // ...        // Schedule send email job if appointment has been successfully saved        scheduleSendEmailJob(appointment);        return;    }    private void scheduleSendEmailJob(Appointment appointment) throws SchedulerException {        JobDetail jobDetail = JobBuilder.newJob().ofType(SendEmailJob.class) .storeDurably() .withIdentity(UuidUtils.generateId(), "APPOINTMENT_NOTIFICATIONS") .withDescription("Send email notification for appointment") .build();        jobDetail.getJobDataMap().put("appointmentId", appointment.getId());        Date scheduleDate = appointment.computeDesiredScheduleDate();        String cronexpression = convertDateToCronexpression(scheduleDate);        CronTrigger trigger = TriggerBuilder.newTrigger().forJob(jobDetail) .withIdentity(UuidUtils.generateId(), "APPOINTMENT_NOTIFICATIONS") .withDescription("Trigger description") .withSchedule(CronScheduleBuilder.cronSchedule(cronexpression)) .build();        schedulingService.scheduleJob(jobDetail, trigger);    }    private String convertDateToCronexpression(Date date) {        Calendar calendar = new GregorianCalendar();        if (date == null) return null;        calendar.setTime(date);        int year = calendar.get(java.util.Calendar.YEAR);        int month = calendar.get(java.util.Calendar.MONTH) + 1;        int day = calendar.get(java.util.Calendar.DAY_OF_MONTH);        int hour = calendar.get(java.util.Calendar.HOUR_OF_DAY);        int minute = calendar.get(java.util.Calendar.MINUTE);        return String.format("0 %d %d %d %d ? %d", minute, hour, day, month, year);    }}

SendEmailJob
Job
接口的实现,负责使用相关服务发送电子邮件。

更新-将参数从调度方法传递到实际作业执行的代码

为了传递参数,正在使用jobDataMap。例如:

public class SendEmailJob implements Job {    @Autowired    private AppointmentService appointmentService;    @Autowired    private SendEmailService sendEmailService;    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();        // Retrieving passed parameters        Long appointmentId = (Long) jobDataMap.get("appointmentId");        Appointment appointment = appointmentService.findById(appointmentId);        // Send email        sendEmailService.sendEmail(appointment);    }}

注意: 约会对象也可以从调度方法传递到实际的作业执行,您可以传递:

jobDetail.getJobDataMap().put("appointment", appointment);

得到:

// Retrieving passed parametersAppointment appointment = (Appointment) jobDataMap.get("appointment");

更新-配置代码

Bean

scheduler
是在
@Configuration
负责Quartz初始化的类中定义的。

SchedulingConfiguration
类定义为:

@Configurationpublic class SchedulingConfiguration {    @Autowired    private ApplicationContext applicationContext;    @Bean    public Scheduler scheduler() throws SchedulerException, IOException {        StdSchedulerFactory factory = new StdSchedulerFactory();        factory.initialize(new ClassPathResource("properties/quartz.properties").getInputStream());        Scheduler scheduler = factory.getScheduler();        scheduler.setJobFactory(springBeanJobFactory());        return scheduler;    }    @Bean    public SpringBeanJobFactory springBeanJobFactory() {        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();        jobFactory.setApplicationContext(applicationContext);        return jobFactory;    }}

我们的

quartz.properties
文件位于
resources/properties
文件夹中。请注意,作业持久性数据库是Oracle实例。

# Configure Main Scheduler Propertiesorg.quartz.scheduler.instanceName = AppSchedulerorg.quartz.scheduler.instanceId = AUTO# Configure ThreadPoolorg.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPoolorg.quartz.threadPool.threadCount = 10org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true# Configure JobStoreorg.quartz.jobStore.misfireThreshold = 60000org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTXorg.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegateorg.quartz.jobStore.tablePrefix = APP.QRTZ_org.quartz.jobStore.useProperties = falseorg.quartz.jobStore.dataSource = appDsorg.quartz.jobStore.isClustered = trueorg.quartz.jobStore.clusterCheckinInterval = 20000# Configure Datasourcesorg.quartz.dataSource.appDs.driver = oracle.jdbc.driver.OracleDriverorg.quartz.dataSource.appDs.URL = jdbc:oracle:thin:@dbsrv:1521:appdborg.quartz.dataSource.appDs.user = db_userorg.quartz.dataSource.appDs.password = db_pwdorg.quartz.dataSource.appDs.maxConnections = 5org.quartz.dataSource.appDs.validationQuery = select 0 from dual

最后一步是在应用程序上下文初始化中调用调度程序方法,如下所示(请注意在中添加的方法

SchedulingService
):

public class SchedulingContextListener implements ServletContextListener {    private static final Logger logger = LogManager.getLogger(SchedulingContextListener.class);    private SchedulingService schedulingService(ServletContextEvent sce) {        WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());        return springContext.getBean(SchedulingService.class);    }    @Override    public void contextInitialized(ServletContextEvent sce) {        try { this.schedulingService(sce).startScheduler();        } catch (SchedulerException e) { logger.error("Error while Scheduler is being started", e);        }    }    @Override    public void contextDestroyed(ServletContextEvent sce) {        try { this.schedulingService(sce).shutdownScheduler();        } catch (SchedulerException e) { logger.error("Error while Scheduler is being shutdown", e);        }    }}

注意:

SchedulingContextListener
应该
servletContext
在应用程序初始化中注册,这取决于使用Spring
Boot或传统的Spring MVC Configuration定义Spring配置的方式。

希望能有所帮助。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/468812.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号