Enter a bean link in a quartz job in Spring?

I was able to set up and schedule a Quartz job using SpringStore JobStoreTX persistent storage. I do not use Spring Quartz jobs because I need to schedule them dynamically at runtime, and all the examples of Spring integration with quartz that I discovered were hard-coding shcedules in Spring configuration files. Anyway, this is how I plan the work:

JobDetail emailJob = JobBuilder.newJob(EMailJob.class) .withIdentity("someJobKey", "immediateEmailsGroup") .storeDurably() .build(); SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() .withIdentity("someTriggerKey", "immediateEmailsGroup") .startAt(fireTime) .build(); // pass initialization parameters into the job emailJob.getJobDataMap().put(NotificationConstants.MESSAGE_PARAMETERS_KEY, messageParameters); emailJob.getJobDataMap().put(NotificationConstants.RECIPIENT_KEY, recipient); if (!scheduler.checkExists(jobKey) && scheduler.getTrigger(triggerKey) != null) { // schedule the job to run Date scheduleTime1 = scheduler.scheduleJob(emailJob, trigger); } 

EMailJob is a simple task that sends emails using the Spring JavaMailSenderImpl class.

 public class EMailJob implements Job { @Autowired private JavaMailSenderImpl mailSenderImpl; public EMailJob() { } public void execute(JobExecutionContext context) throws JobExecutionException { .... try { mailSenderImpl.send(mimeMessage); } catch (MessagingException e) { .... throw new JobExecutionException("EMailJob failed: " + jobKey.getName(), e); } logger.info("EMailJob finished OK"); } 

The problem is that I need to get a reference to an instance of this class (JavaMailSenderImpl) in my EMailJob class. When I try to enter it like this:

 @Autowired private JavaMailSenderImpl mailSenderImpl; 

it is not entered - the link is NULL. I assume this happens because it is not Spring that creates an instance of the EMailJob class, but Quartz and Quartz do not know anything about dependency injection ...

So, is there a way to make this injection happen?

thank!

Update 1: @ Aaron: here is the important part of the stacktrace from launch, which shows that EMailJob was created twice:

 2011-08-15 14:16:38,687 [main] INFO org.springframework.context.support.GenericApplicationContext - Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler#0' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2011-08-15 14:16:38,734 [main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1328c7a: defining beans [...]; root of factory hierarchy 2011-08-15 14:16:39,734 [main] INFO com.cambridgedata.notifications.EMailJob - EMailJob() - initializing ... 2011-08-15 14:16:39,937 [main] INFO org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor - Validated configuration attributes 2011-08-15 14:16:40,078 [main] INFO org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Validated configuration attributes 2011-08-15 14:16:40,296 [main] INFO org.springframework.jdbc.datasource.init.ResourceDatabasePopulator - Executing SQL script from class path resource ... 2011-08-15 14:17:14,031 [main] INFO com.mchange.v2.log.MLog - MLog clients using log4j logging. 2011-08-15 14:17:14,109 [main] INFO com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace: 10] 2011-08-15 14:17:14,171 [main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl 2011-08-15 14:17:14,171 [main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.0.1 created. 2011-08-15 14:17:14,187 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Using thread monitor-based data access locking (synchronization). 2011-08-15 14:17:14,187 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - JobStoreTX initialized. 2011-08-15 14:17:14,187 [main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.0.1) 'NotificationsScheduler' with instanceId 'NON_CLUSTERED' Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads. Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreTX' - which supports persistence. and is not clustered. 2011-08-15 14:17:14,187 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'NotificationsScheduler' initialized from the specified file : 'spring/quartz.properties' from the class resource path. 2011-08-15 14:17:14,187 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.0.1 2011-08-15 14:17:14,234 [main] INFO com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 2sajb28h1lcabf28k3nr1|13af084, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 2sajb28h1lcabf28k3nr1|13af084, idleConnectionTestPeriod -> 50, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/2010rewrite2, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 5, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> select 0 from dual, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> true, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ] 2011-08-15 14:17:14,312 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Freed 0 triggers from 'acquired' / 'blocked' state. 2011-08-15 14:17:14,328 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Recovering 0 jobs that were in-progress at the time of the last shut-down. 2011-08-15 14:17:14,328 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Recovery complete. 2011-08-15 14:17:14,328 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 'complete' triggers. 2011-08-15 14:17:14,328 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 stale fired job entries. 2011-08-15 14:17:14,328 [main] INFO org.quartz.core.QuartzScheduler - Scheduler NotificationsScheduler_$_NON_CLUSTERED started. 2011-08-15 14:17:14,515 [NotificationsScheduler_QuartzSchedulerThread] INFO com.cambridgedata.notifications.EMailJob - EMailJob() - initializing ... 

thank!

Update # 2: @Ryan:

I tried using SpringBeanJobFactory as follows:

  <bean id="jobFactoryBean" class="org.springframework.scheduling.quartz.SpringBeanJobFactory"> </bean> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="configLocation" value="classpath:spring/quartz.properties"/> <property name="jobFactory" ref="jobFactoryBean"/> </bean> 

And I changed my main class to get a Scheduler from this factory instead of Quartz ':

  @PostConstruct public void initNotificationScheduler() { try { //sf = new StdSchedulerFactory("spring/quartz.properties"); //scheduler = sf.getScheduler(); scheduler = schedulerFactoryBean.getScheduler(); scheduler.start(); .... 

But when I launch the application, I get errors, see below. Here is a stack from Spring startup. It looks like the Scheduler itself was created perfectly, but the error occurs when trying to create an instance of my EMailJob:

 2011-08-15 21:49:42,968 [main] INFO org.springframework.scheduling.quartz.SchedulerFactoryBean - Loading Quartz config from [class path resource [spring/quartz.properties]] 2011-08-15 21:49:43,031 [main] INFO com.mchange.v2.log.MLog - MLog clients using log4j logging. 2011-08-15 21:49:43,109 [main] INFO com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace: 10] 2011-08-15 21:49:43,187 [main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl 2011-08-15 21:49:43,187 [main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.0.1 created. 2011-08-15 21:49:43,187 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Using thread monitor-based data access locking (synchronization). 2011-08-15 21:49:43,187 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - JobStoreTX initialized. 2011-08-15 21:49:43,187 [main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.0.1) 'schedulerFactoryBean' with instanceId 'NON_CLUSTERED' Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads. Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreTX' - which supports persistence. and is not clustered. 2011-08-15 21:49:43,187 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'schedulerFactoryBean' initialized from an externally provided properties instance. 2011-08-15 21:49:43,187 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.0.1 2011-08-15 21:49:43,187 [main] INFO org.quartz.core.QuartzScheduler - JobFactory set to: org.springframework.scheduling.quartz.SpringBeanJobFactory@566633 2011-08-15 21:49:43,265 [main] INFO com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge13f8h1lsg7py1rg0iu0|1956391, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge13f8h1lsg7py1rg0iu0|1956391, idleConnectionTestPeriod -> 50, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/2010rewrite2, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 5, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> select 0 from dual, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> true, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ] 2011-08-15 21:49:43,343 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Freed 0 triggers from 'acquired' / 'blocked' state. 2011-08-15 21:49:43,359 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Recovering 0 jobs that were in-progress at the time of the last shut-down. 2011-08-15 21:49:43,359 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Recovery complete. 2011-08-15 21:49:43,359 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 'complete' triggers. 2011-08-15 21:49:43,359 [main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 stale fired job entries. 2011-08-15 21:49:43,359 [main] INFO org.quartz.core.QuartzScheduler - Scheduler schedulerFactoryBean_$_NON_CLUSTERED started. 2011-08-15 21:49:43,562 [schedulerFactoryBean_QuartzSchedulerThread] ERROR org.quartz.core.ErrorLogger - An error occured instantiating job to be executed. job= 'immediateEmailsGroup.DEFAULT.jobFor_1000new1' org.quartz.SchedulerException: Problem instantiating class 'com.cambridgedata.notifications.EMailJob' - [See nested exception: java.lang.AbstractMethodError: org.springframework.scheduling.quartz.SpringBeanJobFactory.newJob(Lorg/quartz/spi/TriggerFiredBundle;Lorg/quartz/Scheduler;)Lorg/quartz/Job;] at org.quartz.core.JobRunShell.initialize(JobRunShell.java:141) at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:381) Caused by: java.lang.AbstractMethodError: org.springframework.scheduling.quartz.SpringBeanJobFactory.newJob(Lorg/quartz/spi/TriggerFiredBundle;Lorg/quartz/Scheduler;)Lorg/quartz/Job; at org.quartz.core.JobRunShell.initialize(JobRunShell.java:134) 

thank!

+87
spring quartz-scheduler inject
Aug 09 '11 at 2:21
source share
21 answers

Just complete the solution provided by jelies, as well as a couple of other things, to make Spring + Quartz integration easier: http://codrspace.com/Khovansa/spring-quartz-with-a-database/

+5
29 Oct '15 at 17:13
source share

You can use this SpringBeanJobFactory to automatically auto-arrange quartz objects using spring:

 import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.scheduling.quartz.SpringBeanJobFactory; public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; @Override public void setApplicationContext(final ApplicationContext context) { beanFactory = context.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; } } 

Then attach it to your SchedulerBean (in this case, with Java-config):

 @Bean public SchedulerFactoryBean quartzScheduler() { SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean(); ... AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); quartzScheduler.setJobFactory(jobFactory); ... return quartzScheduler; } 

Work with me using spring -3.2.1 and quartz-2.1.6.

See the full gist here .

I found a solution in this blog post

+120
Mar 04 '13 at 21:00
source share

I just put SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); to the first line of my Job.execute(JobExecutionContext context) method Job.execute(JobExecutionContext context) .

+56
Jun 30 '13 at 21:13
source share

The same problem was solved in LINK :

I could find another option from a Spring forum post that you can pass a link to the Spring application context through a SchedulerFactoryBean. As below:

 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <propertyy name="triggers"> <list> <ref bean="simpleTrigger"/> </list> </property> <property name="applicationContextSchedulerContextKey"> <value>applicationContext</value> </property> 

Then, using the code below in your job class, you can get the applicationContext and get all the bean you want.

 appCtx = (ApplicationContext)context.getScheduler().getContext().get("applicationContextSchedulerContextKey"); 

Hope this helps. You can get more information from Mark Mclaren'sBlog

+13
Sep 11 '11 at 10:01
source share

You are correct in your assumption of Spring vs. Quartz creating an instance of the class. However, Spring provides some classes that allow you to do some primitive dependency injection in Quartz. Check out SchedulerFactoryBean.setJobFactory () along with SpringBeanJobFactory . Essentially, with SpringBeanJobFactory you include dependency injection in all Job properties, but only for values ​​that are in the context of the Quartz scheduler or job data map . I don’t know all the DI styles that it supports (constructor, annotation, setter ...), but I know that it supports installer injection.

+7
Aug 09 2018-11-11T00:
source share

for anyone who tries to do this in the future.

org.springframework.scheduling.quartz.JobDetailBean supplies a map of objects, and these objects can be spring beans.

define smth like

 <bean name="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="my.cool.class.myCoolJob" /> <property name="jobDataAsMap"> <map> <entry key="myBean" value-ref="myBean" /> </map> </property> </bean> 

and then inside

 public void executeInternal(JobExecutionContext context) 

call myBean = (myBean) context.getMergedJobDataMap().get("myBean"); and you set everything. I know it looks ugly, but as a workaround, it works

+6
Feb 08 '12 at 3:16
source share
 ApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(ContextLoaderListener .getCurrentWebApplicationContext().getServletContext()); Bean bean = (Bean) springContext.getBean("beanName"); bean.method(); 
+5
Oct 20 '12 at 23:09
source share

Thank Rippon I finally got this job, after many battles, and my solution is very close to what you suggested! The key was to do my own assignment for the QuartzJobBean extension and use schedulerContextAsMap.

I left without specifying the applicationContextSchedulerContextKey property - it worked without it for me.

In the interest of others, here is the final configuration that worked for me:

  <bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="configLocation" value="classpath:spring/quartz.properties"/> <property name="jobFactory"> <bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory" /> </property> <property name="schedulerContextAsMap"> <map> <entry key="mailService" value-ref="mailService" /> </map> </property> </bean> <bean id="jobTriggerFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"> <property name="targetBeanName"> <idref local="jobTrigger" /> </property> </bean> <bean id="jobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean" scope="prototype"> <property name="group" value="myJobs" /> <property name="description" value="myDescription" /> <property name="repeatCount" value="0" /> </bean> <bean id="jobDetailFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"> <property name="targetBeanName"> <idref local="jobDetail" /> </property> </bean> <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean" scope="prototype"> <property name="jobClass" value="com.cambridgedata.notifications.EMailJob" /> <property name="volatility" value="false" /> <property name="durability" value="false" /> <property name="requestsRecovery" value="true" /> </bean> <bean id="notificationScheduler" class="com.cambridgedata.notifications.NotificationScheduler"> <constructor-arg ref="quartzScheduler" /> <constructor-arg ref="jobDetailFactory" /> <constructor-arg ref="jobTriggerFactory" /> </bean> 

Please note that the "mailService" bean is my own Spring managed bean service. I managed to access it in my assignment as follows:

  public void executeInternal(JobExecutionContext context) throws JobExecutionException { logger.info("EMailJob started ..."); .... SchedulerContext schedulerContext = null; try { schedulerContext = context.getScheduler().getContext(); } catch (SchedulerException e1) { e1.printStackTrace(); } MailService mailService = (MailService)schedulerContext.get("mailService"); .... 

And this configuration also allowed me to perform dynamic tasks of the scheduler, using plants to receive triggers and work tasks and programmatically setting them the necessary parameters:

  public NotificationScheduler(final Scheduler scheduler, final ObjectFactory<JobDetail> jobDetailFactory, final ObjectFactory<SimpleTrigger> jobTriggerFactory) { this.scheduler = scheduler; this.jobDetailFactory = jobDetailFactory; this.jobTriggerFactory = jobTriggerFactory; ... // create a trigger SimpleTrigger trigger = jobTriggerFactory.getObject(); trigger.setRepeatInterval(0L); trigger.setStartTime(new Date()); // create job details JobDetail emailJob = jobDetailFactory.getObject(); emailJob.setName("new name"); emailJob.setGroup("immediateEmailsGroup"); ... 

Thanks to everyone who helped

Marina

+4
Sep 20 '11 at 1:27
source share

Here's what the code looks like using @Component:

The main class that schedules the task:

 public class NotificationScheduler { private SchedulerFactory sf; private Scheduler scheduler; @PostConstruct public void initNotificationScheduler() { try { sf = new StdSchedulerFactory("spring/quartz.properties"); scheduler = sf.getScheduler(); scheduler.start(); // test out sending a notification at startup, prepare some parameters... this.scheduleImmediateNotificationJob(messageParameters, recipients); try { // wait 20 seconds to show jobs logger.info("sleeping..."); Thread.sleep(40L * 1000L); logger.info("finished sleeping"); // executing... } catch (Exception ignore) { } } catch (SchedulerException e) { e.printStackTrace(); throw new RuntimeException("NotificationScheduler failed to retrieve a Scheduler instance: ", e); } } public void scheduleImmediateNotificationJob(){ try { JobKey jobKey = new JobKey("key"); Date fireTime = DateBuilder.futureDate(delayInSeconds, IntervalUnit.SECOND); JobDetail emailJob = JobBuilder.newJob(EMailJob.class) .withIdentity(jobKey.toString(), "immediateEmailsGroup") .build(); TriggerKey triggerKey = new TriggerKey("triggerKey"); SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() .withIdentity(triggerKey.toString(), "immediateEmailsGroup") .startAt(fireTime) .build(); // schedule the job to run Date scheduleTime1 = scheduler.scheduleJob(emailJob, trigger); } catch (SchedulerException e) { logger.error("error scheduling job: " + e.getMessage(), e); e.printStackTrace(); } } @PreDestroy public void cleanup(){ sf = null; try { scheduler.shutdown(); } catch (SchedulerException e) { e.printStackTrace(); } } 

EmailJob is the same as in my first post, with the exception of the @Component annotation:

 @Component public class EMailJob implements Job { @Autowired private JavaMailSenderImpl mailSenderImpl; ... } 

And the Spring configuration file has:

 ... <context:property-placeholder location="classpath:spring/*.properties" /> <context:spring-configured/> <context:component-scan base-package="com.mybasepackage"> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" /> </context:component-scan> <bean id="mailSenderImpl" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="${mail.host}"/> <property name="port" value="${mail.port}"/> ... </bean> <bean id="notificationScheduler" class="com.mybasepackage.notifications.NotificationScheduler"> </bean> 

Thanks for the help!

Marina

+3
Aug 15 2018-11-11T00:
source share

A simple solution is to set the spring bean in the Job Data Map and then retrieve the bean in the job class, for example

 // the class sets the configures the MyJob class SchedulerFactory sf = new StdSchedulerFactory(); Scheduler sched = sf.getScheduler(); Date startTime = DateBuilder.nextGivenSecondDate(null, 15); JobDetail job = newJob(MyJob.class).withIdentity("job1", "group1").build(); job.getJobDataMap().put("processDataDAO", processDataDAO); 

`

  // this is MyJob Class ProcessDataDAO processDataDAO = (ProcessDataDAO) jec.getMergedJobDataMap().get("processDataDAO"); 
+2
Jun 13 '16 at 19:21
source share

Hary.site/questions/73431 / ...'s solution works very well. It is simpler, you don’t need so many special bean factories and supports several triggers and tasks. Just add that the Quartz task can be made universal, and specific tasks are performed like regular spring beans.

 public interface BeanJob { void executeBeanJob(); } public class GenericJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap dataMap = context.getMergedJobDataMap(); ((BeanJob)dataMap.get("beanJob")).executeBeanJob(); } } @Component public class RealJob implements BeanJob { private SomeService service; @Autowired public RealJob(SomeService service) { this.service = service; } @Override public void executeBeanJob() { //do do job with service } } 
+2
Mar 06 '18 at 13:49
source share

An easy way to do this would be to simply comment on Quartz jobs with the @Component annotation, and then Spring will do all the DI magic for you, since now it is recognized as a Spring bean, I should have done something similar for AspectJ - it was not a Spring bean until I annotated it using the Spring @Component stereotype.

+1
Aug 14 2018-11-11T00:
source share

This is a pretty old post that is still useful. All solutions that these two offer have few conditions that do not correspond to all:

  • SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); Does this suggest or require that it be a spring based project
  • AutowiringSpringBeanJobFactory mentioned in the previous answer is very useful, but the answer is specific for those who do not use the pure vanilla quartz api, but rather Spring wrapper for the quartz to do the same.

If you want to stay with a clean Quartz implementation for planning (quartz with Autowiring capabilities with Spring), I was able to do this as follows:

I tried to do this in a quartz way, as much as possible, and thus a little hack is useful.

  public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory{ private AutowireCapableBeanFactory beanFactory; public AutowiringSpringBeanJobFactory(final ApplicationContext applicationContext){ beanFactory = applicationContext.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); beanFactory.initializeBean(job, job.getClass().getName()); return job; } } @Configuration public class SchedulerConfig { @Autowired private ApplicationContext applicationContext; @Bean public AutowiringSpringBeanJobFactory getAutowiringSpringBeanJobFactory(){ return new AutowiringSpringBeanJobFactory(applicationContext); } } private void initializeAndStartScheduler(final Properties quartzProperties) throws SchedulerException { //schedulerFactory.initialize(quartzProperties); Scheduler quartzScheduler = schedulerFactory.getScheduler(); //Below one is the key here. Use the spring autowire capable job factory and inject here quartzScheduler.setJobFactory(autowiringSpringBeanJobFactory); quartzScheduler.start(); } 

quartzScheduler.setJobFactory(autowiringSpringBeanJobFactory); gives us a copy with auto-preparation. AutowiringSpringBeanJobFactory JobFactory , . Hope this helps!

+1
16 . '18 8:56
source share

,

 AutowiringSpringBeanJobFactory extends SpringBeanJobFactory 

  "org.springframework:spring-context-support:4..." 

  "org.springframework:spring-support:2..." 

,

 @Override public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) 

instead

 @Override protected Object createJobInstance(final TriggerFiredBundle bundle) 

.

0
07 . '15 14:32
source share

AspectJ , bean @Configurable . Spring , new

0
07 . '16 9:59
source share

:

 <!-- Quartz Job --> <bean name="JobA" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- <constructor-arg ref="dao.DAOFramework" /> --> <property name="jobDataAsMap"> <map> <entry key="daoBean" value-ref="dao.DAOFramework" /> </map> </property> <property name="jobClass" value="com.stratasync.jobs.JobA" /> <property name="durability" value="true"/> </bean> 

dao.DAOFramework bean JobA bean ExecuteInternal bean :

  daoFramework = (DAOFramework)context.getMergedJobDataMap().get("daoBean"); 

Hope this helps! Thank.

0
23 . '16 5:53
source share

, . autowireBeanProperties, , - :

 import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.scheduling.quartz.SpringBeanJobFactory; public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; @Override public void setApplicationContext(final ApplicationContext context) { beanFactory = context.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); //beanFactory.autowireBean(job); beanFactory.autowireBeanProperties(job, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true); return job; } } 
0
27 . '17 10:18
source share

qaru.site/questions/73431/... . . web.xml applicationContext.xml, . , Context

 public class MYSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; @Override public void setApplicationContext(final ApplicationContext context) { try { PathMatchingResourcePatternResolver pmrl = new PathMatchingResourcePatternResolver(context.getClassLoader()); Resource[] resources = new Resource[0]; GenericApplicationContext createdContext = null ; resources = pmrl.getResources( "classpath*:my-abc-integration-applicationContext.xml" ); for (Resource r : resources) { createdContext = new GenericApplicationContext(context); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(createdContext); int i = reader.loadBeanDefinitions(r); } createdContext.refresh();//important else you will get exceptions. beanFactory = createdContext.getAutowireCapableBeanFactory(); } catch (IOException e) { e.printStackTrace(); } } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; } } 

, .

0
19 . '18 19:33
source share

Spring 5 Hibernate 5 Quartz 2.2.3, !

, . dzone . , , Spring Configuration , Spring.

:

 @Configuration public class QuartzConfiguration { @Autowired ApplicationContext applicationContext; @Bean public SchedulerFactoryBean scheduler(@Autowired JobFactory jobFactory) throws IOException { SchedulerFactoryBean sfb = new SchedulerFactoryBean(); sfb.setOverwriteExistingJobs(true); sfb.setAutoStartup(true); sfb.setJobFactory(jobFactory); Trigger[] triggers = new Trigger[] { cronTriggerTest().getObject() }; sfb.setTriggers(triggers); return sfb; } @Bean public JobFactory cronJobFactory() { AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); return jobFactory; } @Bean public CronTriggerFactoryBean cronTriggerTest() { CronTriggerFactoryBean tfb = new CronTriggerFactoryBean(); tfb.setCronExpression("0 * * ? * * *"); JobDetail jobDetail = JobBuilder.newJob(CronTest.class) .withIdentity("Testjob") .build() ; tfb.setJobDetail(jobDetail); return tfb; } } 

, , cron. , , , . AutowiringSpringBeanJobFactory, :

 public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { @Autowired private ApplicationContext applicationContext; private SchedulerContext schedulerContext; @Override public void setApplicationContext(final ApplicationContext context) { this.applicationContext = context; } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { Job job = applicationContext.getBean(bundle.getJobDetail().getJobClass()); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap()); pvs.addPropertyValues(bundle.getTrigger().getJobDataMap()); if (this.schedulerContext != null) { pvs.addPropertyValues(this.schedulerContext); } bw.setPropertyValues(pvs, true); return job; } public void setSchedulerContext(SchedulerContext schedulerContext) { this.schedulerContext = schedulerContext; super.setSchedulerContext(schedulerContext); } } 

. , Quartz , . mehtods. , , - .

 @Component public class CronTest implements Job { @Autowired private MyService s; public CronTest() { } @Override public void execute(JobExecutionContext context) throws JobExecutionException { s.execute(); } } 

, . .

0
23 . '18 9:04
source share

Jdbc JobStore

jdbc jobstore, Quartz . , , .

, :

 org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper 

: https://github.com/quartz-scheduler/quartz/issues/221

0
22 . '18 13:47
source share

QuartzJobBean

 public class MyJob extends QuartzJobBean { @Autowired private SomeBean someBean; @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("Some bean is " + someBean.toString()); } } 
0
18 . '19 7:48
source share



All Articles