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 ?
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.
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.
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.
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).
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With