日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

在Spring中使用JDBCJobStore配置Quartz

發布時間:2023/12/3 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Spring中使用JDBCJobStore配置Quartz 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我將開始一些有關Quartz Scheduler內部,提示和技巧的系列文章,這是第0章-如何配置持久性作業存儲。 在Quartz中,您基本上可以在將作業和觸發器存儲在內存中以及在關系數據庫中進行選擇( Terracotta是最近添加的混合功能)。 我想說在90%的情況下,當您將Quartz與RAMJobStore一起使用時,您根本就不需要Quartz。 顯然,此存儲后端是瞬態的,并且所有重啟之間都將丟失所有待處理的作業和觸發器。 如果您對此感到滿意,則可以使用更簡單,更輕便的解決方案,包括JDK中內置的ScheduledExecutorService和Spring中的@Scheduled(cron =” * / 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.Driver@Configuration @EnableTransactionManagement class Persistence {@Beandef transactionManager() = new DataSourceTransactionManager(dataSource())@Bean@Primarydef 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_EXIT=FALSE;MVCC=TRUE")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 = null@Bean@DependsOn(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調度程序工廠上使用@DependsOn(Array(“ 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 = null@Beandef 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

總結

以上是生活随笔為你收集整理的在Spring中使用JDBCJobStore配置Quartz的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。