在Spring中注入并使用quartz

配置

spring 配置文件:

<bean lazy-init="false">
   <constructor-arg>
    <props>
     <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
     <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
     <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
   
     <prop key="org.quartz.jobStore.dataSource">qzDS</prop>
     <prop key="org.quartz.dataSource.qzDS.driver">${jdbc.driverClassName}</prop>
     <prop key="org.quartz.dataSource.qzDS.URL">${jdbc.url}</prop>
     <prop key="org.quartz.dataSource.qzDS.user">${jdbc.username}</prop>
     <prop key="org.quartz.dataSource.qzDS.password">${jdbc.password}</prop>
     <prop key="org.quartz.dataSource.qzDS.maxConnections">30</prop>

     <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
     <prop key="org.quartz.threadPool.threadCount">10</prop>
     <prop key="org.quartz.threadPool.threadPriority">5</prop>
     <prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
   
    </props>
   </constructor-arg>
</bean>


<bean id="scheduler" factory-bean="stdSchedulerFactory" factory-method="getScheduler" init-method="start" destroy-method="shutdown" lazy-init="false"/>


scheduler对象使用stdSchedulerFactory的getScheduler方法创建并且马上调用start方法启动quartz,在关闭时使用shutdown关闭quartz,设置scheduler的lazy-init="false"是为了令其在服务器启动时就创建该scheduler并启动服务。


stdSchedulerFactory的配置使用得不再需要quartz.properties文件。

如果要保留quartz.properties文件的配置方式,也可以将stdSchedulerFactory配置修改为:

<bean lazy-init="false">
      <constructor-arg index="0" value="/conf/quartz.properties"></constructor-arg>
</bean>


********************************************************************************************************************************

********************************************************************************************************************************

在Job中使用ServletContext的解决方法

因为quartz线程不是一个HTTP请求,不存在request对象,无法取得servletContext,但是可以通过定义一个静态变量:ServletContext context,通过在服务器启动的时候进行初始化(采用listener或者servlet)。

代码:


public class JobContextListener implements ServletContextListener
{

public void contextDestroyed(ServletContextEvent servletcontextevent)
{
   // TODO Auto-generated method stub
 
}

public void contextInitialized(ServletContextEvent servletcontextevent)
{
   // TODO Auto-generated method stub
   JobContext.getInstance().setContext(servletcontextevent.getServletContext());
}
}

public class JobContext
{
private final static JobContext instance = new JobContext();
private static ServletContext context;

private JobContext()
{
}

public static JobContext getInstance()
{
   return instance;
}

protected void setContext(ServletContext context2)
{
   context = context2;
}

public ServletContext getContext()
{
   return context;
}
}

在web.xml中添加

<!-- 任务监听程序 -->
<listener>
   <listener-class>cms.module.quartz.JobContextListener</listener-class>
</listener>

在Job类的excute方法中使用ServletContext scontext = JobContext.getInstance().getContext();即可取得ServletContext。


使用

ServletContext scontext = JobContext.getInstance().getContext();
    ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(scontext);
    quartzIndexPageService = (ISitePage)ctx.getBean("quartzIndexPageService");

就可以取得spring注入的bean实例

********************************************************************************************************************************

********************************************************************************************************************************

在Job中Spring注入的bean实例,bean实例使用了hibernate出现no session问题的解决方法

因为bean实例使用了hibernate去访问数据库,而且象关系映射使用延迟的对象初始化(也就是说,如果有某一个hibernate请求不是经由web request发起的,而是由quartz这样的定时任务发起的,那么quartz怎么样才能得到hibernate session呢?)


spring配置:

<bean >  
         <property name="sessionFactory">  
           <ref bean="sessionFactory"/>  
         </property>  
    </bean>
   
<!-- Manager template -->  
    <bean id="txProxyTemplate" abstract="true"  
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
        <property name="transactionManager" ref="transactionManager"/>  
        <property name="transactionAttributes">
            <props>  
                <prop key="save*">PROPAGATION_REQUIRED</prop>  
                <prop key="remove*">PROPAGATION_REQUIRED</prop>  
                <prop key="update*">PROPAGATION_REQUIRED</prop>                   
                <prop key="create*">PROPAGATION_REQUIRED</prop>      
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>  
            </props>  
        </property>  
        <property name="preInterceptors">  
            <list>  
             <ref bean="hibernateInterceptor"/>  
            </list>  
        </property>                           
    </bean>


<!-- 配置令columnService的方法在quartz的job中支持延迟加载 -->
<bean id="quartzColumnService" parent="txProxyTemplate" >
   <property name="target" ref="columnService"/>
</bean>
<!-- 配置令indexPageService的方法在quartz的job中支持延迟加载 -->
<bean id="quartzIndexPageService" parent="txProxyTemplate" >
   <property name="target" ref="indexPageService"/>
</bean>


<bean >
   <property name="tagClassMap" ref="tagMap" />
   <property name="siteService" ref="siteService" />
</bean>


这样一来,在job中就可以使用quartzIndexPageService和quartzColumnService这两个bean了,而且这两个bean的实现indexPageService和columnService中使用hibernate(就算hibernate对象使用延迟初始化)查询而不会引起no session 异常。

猜你喜欢

转载自xhpscdx.iteye.com/blog/1171681
今日推荐