Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use @Autowired in a Quartz Job?

i am using quartz with spring and i want to inject/use another class in the job class and i don't know how to do it correctly

the xml:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">     <!-- Scheduler task -->    <bean name="schedulerTask" class="com.mkyong.quartz.SchedulerTask" />     <!-- Scheduler job -->    <bean name="schedulerJob"        class="org.springframework.scheduling.quartz.JobDetailBean">       <property name="jobClass" value="com.mkyong.quartz.SchedulerJob" />       <property name="jobDataAsMap">         <map>           <entry key="schedulerTask" value-ref="schedulerTask" />          </map>       </property>    </bean>     <!-- Cron Trigger -->    <bean id="cronTrigger"     class="org.springframework.scheduling.quartz.CronTriggerBean">      <property name="jobDetail" ref="schedulerJob" />     <property name="cronExpression" value="0/10 * * * * ?" />     </bean>     <!-- Scheduler -->    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">     <property name="jobDetails">        <list>           <ref bean="schedulerJob" />        </list>     </property>      <property name="triggers">         <list>         <ref bean="cronTrigger" />         </list>     </property>    </bean>  </beans> 

the quartz job:

package com.mkyong.quartz;  import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean;  public class SchedulerJob extends QuartzJobBean {     private SchedulerTask schedulerTask;      public void setSchedulerTask(SchedulerTask schedulerTask) {         this.schedulerTask = schedulerTask;     }      protected void executeInternal(JobExecutionContext context)     throws JobExecutionException {          schedulerTask.printSchedulerMessage();      } } 

the task to be executed:

package com.mkyong.quartz;  public class SchedulerTask {     public void printSchedulerMessage() {         System.out.println("Struts 2 + Spring + Quartz ......");     } } 

i want to inject another DTO class that deals with Database in the task class to do some database work in the task, how to do that ?

like image 635
Mahmoud Saleh Avatar asked Nov 23 '10 16:11

Mahmoud Saleh


People also ask

Can I use @autowired in interface?

If you try to use @Autowired on an interface, the Spring framework would throw an exception as it won't be able to decide which implementation class to use.

Where @autowired can be used?

You can use @Autowired annotation on setter methods to get rid of the <property> element in XML configuration file. When Spring finds an @Autowired annotation used with setter methods, it tries to perform byType autowiring on the method.

Can we use @autowired in a class?

We can't use @Autowired on a constructor of an abstract class. Spring doesn't evaluate the @Autowired annotation on a constructor of an abstract class. The subclass should provide the necessary arguments to the super constructor.

Can we use @autowired in pojo?

The @Autowired annotation in spring automatically injects the dependent beans into the associated references of a POJO class. This annotation will inject the dependent beans by matching the data-type (i.e. Works internally as Autowiring byType).


2 Answers

In your solution you are using the spring @Autowired annotation in a class that is not instantiated by Spring. Your solution will still work if you remove the @Autowired annotation because Quartz is setting the property, not Spring.

Quartz will try to set every key within the JobDataMap as a property. E.g. since you have a key "myDao" Quartz will look for a method called "setMyDao" and pass the key's value into that method.

If you want Spring to inject spring beans into your jobs, create a SpringBeanJobFactory and set this into your SchedulerFactoryBean with the jobFactory property within your spring context.

SpringBeanJobFactory javadoc:

Applies scheduler context, job data map and trigger data map entries as bean property values

like image 76
Kieren Dixon Avatar answered Oct 01 '22 14:10

Kieren Dixon


Not sure if this is what you want, but you can pass some configuration values to the Quartz job. I believe in your case you could take advantage of the jobDataAsMap property you already set up, e.g.:

 <property name="jobDataAsMap">     <map>       <entry key="schedulerTask" value-ref="schedulerTask" />       <entry key="param1" value="com.custom.package.ClassName"/>      </map>   </property> 

Then you should be able to access it in your actual Java code in manual way:

protected void executeInternal(JobExecutionContext context) throws JobExecutionException {     schedulerTask.printSchedulerMessage();     System.out.println(context.getJobDetail().getJobDataMap().getString("param1")); } 

Or using the magic Spring approach - have the param1 property defined with getter/setter. You could try defining it with java.lang.Class type then and have the done automatically (Spring would do it for you):

 private Class<?> param1;   // getter & setter   protected void executeInternal(JobExecutionContext context) throws JobExecutionException {     schedulerTask.printSchedulerMessage();     System.out.println("Class injected" + getParam1().getName());  }      

I haven't tested it though.

like image 22
Grzegorz Oledzki Avatar answered Oct 01 '22 13:10

Grzegorz Oledzki