泉州网站制作套餐,seo教学网seo,wordpress 宝塔加速,长沙官网seo诊断我将开始一些有关Quartz Scheduler内部#xff0c;提示和技巧的系列文章#xff0c;这是第0章-如何配置持久性作业存储。 在Quartz中#xff0c;您基本上可以在将作业和触发器存储在内存中以及在关系数据库中进行选择#xff08; Terracotta是最近添加的混合功能#xff0… 我将开始一些有关Quartz Scheduler内部提示和技巧的系列文章这是第0章-如何配置持久性作业存储。 在Quartz中您基本上可以在将作业和触发器存储在内存中以及在关系数据库中进行选择 Terracotta是最近添加的混合功能。 我想说在90的情况下当您将Quartz与RAMJobStore一起使用时您根本就不需要Quartz。 显然此存储后端是瞬态的并且所有重启之间都将丢失所有待处理的作业和触发器。 如果您对此感到满意则可以使用更简单更轻便的解决方案包括JDK中内置的ScheduledExecutorService和Spring中的Scheduledcron ” * / 5 * * * * MON-FRI”。 您能证明在这种情况下使用额外的0.5MiB JAR是合理的吗 当您需要群集故障转移负载平衡和其他一些时髦的词时情况将发生巨大变化。 有几个用例 单个服务器无法处理所需数量的并发且长时间运行的作业并且执行需要分成几台机器-但是每个任务必须完全执行 我们负担不起为时过晚的工作-如果一台服务器宕机另一台服务器应按时运行 …或更严格地说–作业最终需要运行–即使只有一台服务器因维护而停机延迟的作业也需要在重新启动后尽快运行 在上述所有情况下我们都需要某种非瞬态全局存储来跟踪执行了哪些作业以便它们由一台机器精确地运行。 关系数据库作为共享内存在这种情况下效果很好。 因此如果您认为需要安排工作并满足上述一些要求请继续阅读。 我将向您展示如何使用Spring配置Quartz并将其完全集成。 首先我们需要一个数据源 import org.apache.commons.dbcp.BasicDataSource
import com.googlecode.flyway.core.Flyway
import org.jdbcdslog.DataSourceProxy
import org.springframework.jdbc.datasource.{DataSourceTransactionManager, LazyConnectionDataSourceProxy}
import org.h2.DriverConfiguration
EnableTransactionManagement
class Persistence {Beandef transactionManager() new DataSourceTransactionManager(dataSource())BeanPrimarydef dataSource() {val proxy new DataSourceProxy()proxy.setTargetDSDirect(dbcpDataSource())new LazyConnectionDataSourceProxy(proxy)}Bean(destroyMethod close)def dbcpDataSource() {val dataSource new BasicDataSourcedataSource.setDriverClassName(classOf[Driver].getName)dataSource.setUrl(jdbc:h2:mem:quartz-demo;DB_CLOSE_DELAY-1;DB_CLOSE_ON_EXITFALSE;MVCCTRUE)dataSource.setUsername(sa)dataSource.setPassword()dataSource.setMaxActive(20)dataSource.setMaxIdle(20)dataSource.setMaxWait(10000)dataSource.setInitialSize(5)dataSource.setValidationQuery(SELECT 1)dataSource}} 您可能已经猜到了Quartz需要一些数据库表才能使用。 它不会自动创建它们但是提供了几个数据库的SQL脚本包括H2您可以看到我正在使用它。 我认为Flyway是启动时运行数据库脚本的最简单方法 Bean(initMethod migrate)
def flyway() {val fly new Flyway()fly.setDataSource(dataSource())fly
} 顺便说一句如果您没有注意到否我们的示例应用程序中没有XML是的我们正在使用Spring。 让我们继续到Quartz Configuration
class Scheduling {Resourceval persistence: Persistence nullBeanDependsOn(Array(flyway))def schedulerFactory() {val schedulerFactoryBean new SchedulerFactoryBean()schedulerFactoryBean.setDataSource(persistence.dataSource())schedulerFactoryBean.setTransactionManager(persistence.transactionManager())schedulerFactoryBean.setConfigLocation(new ClassPathResource(quartz.properties))schedulerFactoryBean.setJobFactory(jobFactory())schedulerFactoryBean.setApplicationContextSchedulerContextKey(applicationContext)schedulerFactoryBean.setSchedulerContextAsMap(Map().asJava)schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true)schedulerFactoryBean}Beandef jobFactory() new SpringBeanJobFactory} 很高兴知道您可以将Configuration注释类的实例注入到另一个此类中以方便使用。 除此之外–没有幻想。 请注意我们需要在Quartz调度程序工厂上使用DependsOnArray“ flyway”–否则调度程序可能会在Flyway用Quartz数据库表触发迁移脚本之前启动从而导致启动时出现令人不愉快的错误。 基本位是SpringBeanJobFactory和schedulerContextAsMap。 特殊工厂使Spring负责创建Job实例。 不幸的是这个工厂非常有限我们将在下面的示例中很快看到。 首先我们需要一个Spring bean和一个Quartz作业 Service
class Printer extends Logging {def print(msg: String) {logger.info(msg)}}class PrintMessageJob extends Job with Logging {BeanPropertyvar printer: Printer _BeanPropertyvar msg def execute(context: JobExecutionContext) {printer print msg}
} 第一个意外输入是BeanProperty而不是Autowired或Resource。 事实证明即使Job创建了一个实例Job也不是真正的Spring bean。 相反Spring使用可用的setter查找所需的依赖项。 那么味精字符串从何而来 继续 val trigger newTrigger().withIdentity(Every-few-seconds, Demo).withSchedule(simpleSchedule().withIntervalInSeconds(4).repeatForever()).build()val job newJob(classOf[PrintMessageJob]).withIdentity(Print-message, Demo).usingJobData(msg, Hello, world!).build()scheduler.scheduleJob(job, trigger) Quartz 2.0附带了一个不错的内部DSL用于以可读的方式创建作业和触发器。 如您所见我正在传递一个额外的“你好世界” 工作参数。 该参数存储在每个作业或每个触发器的数据库中所谓的JobData中。 执行时将提供给作业。 这样您就可以参数化您的工作。 但是执行时我们的作业将引发NullPointerException…显然没有设置打印机引用并且忽略了该引用。 事实证明Spring不会简单地浏览ApplicationContext中所有可用的bean。 SpringBeanJobFactory仅查看Jobs和Triggers的JobData以及所谓的调度程序上下文已经提到。 如果要将任何Spring bean注入Job则必须在schedulerContext中显式放置对该bean的引用 Configuration
class Scheduling {Resourceval printer: Printer nullBeandef schedulerFactory() {val schedulerFactoryBean new SchedulerFactoryBean()//...schedulerFactoryBean.setSchedulerContextAsMap(schedulerContextMap().asJava)//...schedulerFactoryBean}def schedulerContextMap() Map(printer - printer)} 不幸的是要注入作业的每个Spring bean必须在schedulerContextMap中明确引用。 更糟糕的是如果您忘记了它Quartz将在运行时以静默方式记录NPE。 将来我们将编写更强大的作业工厂。 但是对于初学者来说我们已经准备好运行的Spring Quartz应用程序可以进行进一步的实验这些资源始终可以在我的GitHub帐户下获得。 您可能会问自己我们不能简单地使用MethodInvokingJobDetailFactoryBean吗 好吧首先是因为它不适用于持久性作业存储。 其次-由于无法将JobData传递给Job-因此我们无法再区分不同的作业运行。 例如我们的作业打印消息将必须始终打印在该类中硬编码的相同消息。 顺便说一句如果有人问您Java企业开发人员需要多少个类才能打印“ Hello world”。 您可以自豪地回答4个类30个JAR占用20 MiB的空间以及一个带有10多个表的关系数据库。 认真的说这是本文的输出…… 参考 Java和社区博客上的JCG合作伙伴 Tomasz Nurkiewicz从Spring在JDBCJobStore中配置Quartz 。 翻译自: https://www.javacodegeeks.com/2012/04/configuring-quartz-with-jdbcjobstore-in.html