Announcement Announcement Module
Collapse
No announcement yet.
Can't make autowiring with QuartzJobBean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can't make autowiring with QuartzJobBean

    greetings all, 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:

    Code:
    <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:

    Code:
    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:

    Code:
    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 ?

  • #2
    Solved by making the DAO a service:

    Code:
    @Repository
    @Service("myDao")
    public class MyDaoImpl implements MyDao {
    ....
    }

    the xml:

    Code:
    <property name="jobDataAsMap">
    			<map>
    				<entry key="myDao" value-ref="myDao" />
    			</map>			
    </property>
    the job class:

    Code:
    public class MyJob extends QuartzJobBean {
    
    	public MyJob() {
    	}
    
    	MyDao myDao;
    
    	@Autowired
    	public void seMyDao(MyDao myDao) {
    		this.myDao = myDao;
    	}
    
    @Override
    	protected void executeInternal(JobExecutionContext context)
    			throws JobExecutionException {
    
     //accessing the DAO
    
    }
    }
    Last edited by sword101; Nov 24th, 2010, 03:29 AM.

    Comment


    • #3
      I would advise that you use the scheduler context instead of passing this as job data; it doesn't belong as job data. In fact, if the moment comes along that you decide to switch to persisted jobs you'll find that quartz will barf when it attempts to serialize your myDao and stuff it in the database.

      Also, your autowiring is not valid there. Quartz creates a new instance of MyJob at runtime every time this job runs; as this is not a spring managed bean, spring wont be injecting that dependency for you. The reason you're seeing this work is because myDao is stuffed into the jobData -- see my first point.

      Code:
      <bean name="myScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
      	<property name="schedulerContextAsMap">
      		<map>
      			<entry key="myDao"><ref bean="myDao"/></entry>
      		</map>
      	</property>
      </bean>
      
      ...
      
      public class MyJob extends QuartzJobBean {
      
      	public MyJob() {
      	}
      
      	MyDao myDao; // Set by QuartzJobBean.execute()
      
      	@Override
      	protected void executeInternal(JobExecutionContext context)
      			throws JobExecutionException {
       		//accessing the DAO
      	}
      }

      Comment


      • #4
        This is such a very good note that i didn't notice, i will see it, and thanks a lot for the important feedback.

        Comment


        • #5
          @ jglynn , can you please give me the full xml configuration for this solution ?

          Comment


          • #6
            Code:
            <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 -->
            	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            		<property name="schedulerContextAsMap">
            			<map>
            				<entry key="myDao"><ref bean="myDao"/></entry>
            			</map>
            		</property>
            		<property name="triggers">
            			<list><ref bean="myJobCronTrigger" /></list>
            		</property>
            	</bean>
            	
            	<!-- MyJob CronTrigger -->
            	<bean id="myJobCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            		<property name="jobDetail" ref="myJob" />
            		<property name="cronExpression" value="0/10 * * * * ?" />
            	</bean>
            	
            	<!-- MyJob JobDetail -->
            	<bean name="myJob" class="org.springframework.scheduling.quartz.JobDetailBean">
            		<property name="jobClass" value="com.mkyong.quartz.MyJob" />
            	</bean>
            	
            </beans>
            Code:
            package com.mkyong.quartz;
            
            public class MyJob extends QuartzJobBean {
            
            	MyDao myDao;
            
            	@Override
            	public void executeInternal(JobExecutionContext executionContext) {
            		this.myDao.doDaoStuff();
            	}
            	
            }
            See QuartzJobBean.execute() for the magic which sets myDao with the myDao from the schedulerContext.

            Comment


            • #7
              Thanks a lot man, works fine for me
              still have one more question
              about how to repeat this job every 6 hours ?

              Comment


              • #8
                I'm happy to hear that this new configuration is working well for you.

                Regarding the trigger expression: have a look at the docs, there are some great examples.
                http://www.quartz-scheduler.org/docs...ontrigger.html

                Your expression will depend on what you mean by "every 6 hours", especially taking into consideration what the starting point should be, if it should run on weekends, etc.

                A cron expression to literally run every 6 hours would look something like:
                Code:
                <property name="cronExpression" value="0 0 */6 * * ?" />

                Comment

                Working...
                X