quartz集群(二)

来源:互联网 发布:python pil和opencv 编辑:程序博客网 时间:2024/06/02 04:15
接着上一篇的内容,关于quartz集群,管理session和spring冲突,导致无法从在job方法中无法注入。
环境:quartz:2.2.3,spring:5.0.0。
第一步:

这时候需要新建一个MyJobFactory,继承AdaptableJobFactory:

package com.mys.my.app.job;import org.quartz.spi.TriggerFiredBundle;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.config.AutowireCapableBeanFactory;import org.springframework.scheduling.quartz.AdaptableJobFactory;public class MyJobFactory extends AdaptableJobFactory {    //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.    @Autowired    private AutowireCapableBeanFactory capableBeanFactory;        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {        //调用父类的方法        Object jobInstance = super.createJobInstance(bundle);        //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.        capableBeanFactory.autowireBean(jobInstance);        return jobInstance;    }}
第二步:在quartz.xml中修改为:

<!--  采用AOP拦截的方式实现事务管理; 注释掉事务,与动态  -> -->  <tx:annotation-driven transaction-manager="transactionManager" />  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="writeDataSource" />  </bean>  <bean id="jobFactory" class="com.mys.my.app.job.MyJobFactory"></bean>  <!-- 声明工厂   -->    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">          <property name="dataSource" ref="writeDataSource" />          <property name="configLocation" value="classpath:quartz.properties" />          <property name="transactionManager" ref="transactionManager"/>        <property name="jobFactory" ref="jobFactory"></property><!--         applicationContextSchedulerContextKey:            是org.springframework.scheduling.quartz.SchedulerFactoryBean这个类中   --><!--        把spring上下 文以key/value的方式存放在了quartz的上下文中了,   --><!--         可以用applicationContextSchedulerContextKey所定义的key得到对应的spring上下文-->           <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>           </bean>    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">    <constructor-arg index="0" ref="sqlSessionFactory" />  </bean>    <bean id="multipleDataSource" class="com.mys.my.app.datasource.MultipleDataSource">    <property name="defaultTargetDataSource" ref="writeDataSource" />    <property name="targetDataSources">      <map>        <entry key="writeDataSource" value-ref="writeDataSource" />      </map>    </property>  </bean>    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">    <property name="dataSource" ref="multipleDataSource" />    <property name="configLocation" value="classpath:mybatis.cfg.xml" />    <property name="mapperLocations" value="classpath:com/mys/app/mapper/*.xml" />  </bean>    <bean id="writeDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!--      基本属性 url、user、password -->      <property name="url" value="${jdbc.write.mysql.url}" />      <property name="username" value="${jdbc.write.mysql.username}" />      <property name="password" value="${jdbc.write.mysql.password}" /><!--      本机环境  --><!--    <property name="url" value="jdbc:mysql://127.0.0.1:3306/karma?useUnicode=true&characterEncoding=utf8" /> --><!--    <property name="username" value="root" /> --><!--    <property name="password" value="123456" /> --><!--      配置初始化大小、最小、最大 -->      <property name="initialSize" value="${jdbc.initialSize}" />    <property name="minIdle" value="${jdbc.minIdle}" />    <property name="maxActive" value="${jdbc.maxActive}" />   <!--      配置获取连接等待超时的时间 -->      <property name="maxWait" value="${jdbc.maxWait}" />   <!--      配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->      <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" /><!--      配置一个连接在池中最小生存的时间,单位是毫秒 -->      <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />      <property name="validationQuery" value="${jdbc.validationQuery}" />      <property name="testWhileIdle" value="${jdbc.testWhileIdle}" />      <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />      <property name="testOnReturn" value="${jdbc.testOnReturn}" />  </bean>  <!--  采用AOP拦截的方式实现事务管理; 注释掉事务,与动态  -> -->  <tx:annotation-driven transaction-manager="transactionManager" />  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="writeDataSource" />  </bean><!--  启用Aop AspectJ注解 -->    <aop:aspectj-autoproxy/>      <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">    <property name="location" value="classpath:jdbc.properties" />  </bean>
第三步:

public class testSchedule{    @Resource    private  SystemService systemService;    public void tips() {        //testSevice.sayHi();        String time = new SimpleDateFormat("MMM d,yyyy KK:mm:ss a",Locale.ENGLISH).format(System.currentTimeMillis());          System.out.println("time:"+time);//time:Mar 29,2017 09:25:00 AM        //业务逻辑    }

其实这种共用session的思路并不好,quartz本身是定时任务框架,不应该参与业务。
现在说一下我的解决思路:

quartz是一个单独的工程,只负责触发定时任务。
业务逻辑还在原有的工程。相互调用的方式有很多,RPC,WebService,Dubbo等等。
我这里采用的是dubbo。(关于dubbo的知识自行了解一下,这里只提供实现方式)
先说一下dubbo-api(接口)工程,里边只写接口。
服务提供方和消费方都依赖这个接口工程。
比如(接口工程中):

package com.mys.my.service;public interface DubboTest {  public void doWith();}


业务的项目是服务的提供方,将要暴露的方法(实现DubboTest);
提供一下dubbo-provider.xml:


<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd       http://code.alibabatech.com/schema/dubbo       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">    <!--定义了提供方应用信息,用于计算依赖关系;在 dubbo-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->    <dubbo:application name="demotest-provider" owner="programmer" organization="dubbox"/>    <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->    <dubbo:registry address="zookeeper://localhost:2181"/>    <!-- 用dubbo协议在20880端口暴露服务 -->    <dubbo:protocol name="dubbo" port="20880" />    <!--使用 dubbo 协议实现定义好的 api.PermissionService 接口-->    <dubbo:service interface="com.mys.my.service.IDubboTestService" ref="dubboService" protocol="dubbo" />    <!--具体实现该接口的 bean--><!--     <bean id="demoService" class="com.mys.my.app.service.impl.DubboTestServiceImpl"/> --></beans>

服务方测试类:


package com.mys.my.app.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.io.IOException;public class Provider {        public static void main(String[] args) throws IOException {            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-provider.xml");            System.out.println(context.getDisplayName() + ": here");            context.start();            System.out.println("服务已经启动...");            System.in.read();        }    }

quartz的工程是服务的消费方:
提供一下dubbo-consumer.xml:


<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd       http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">    <dubbo:application name="demotest-consumer" owner="programmer" organization="dubbox"/>    <!--向 zookeeper 订阅 provider 的地址,由 zookeeper 定时推送-->    <dubbo:registry address="zookeeper://47.93.251.85:2181"/>    <!--使用 dubbo 协议调用定义好的 api.PermissionService 接口-->    <dubbo:reference id="permissionService" interface="com.mys.my.api.service.IDubboTestService"/></beans>

消费方测试类:

package com.mys.job;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.mys.my.api.service.IDubboTestService;public class Consumer {    public static void main(String[] args) {        //测试常规服务        ClassPathXmlApplicationContext context =                new ClassPathXmlApplicationContext("dubbo-consumer.xml");        context.start();        System.out.println("consumer start");        IDubboTestService demoService = context.getBean(IDubboTestService.class);        System.out.println("consumer");//        System.out.println(demoService.getPermissions(1L));    }}



这样就可以做到定时任务和业务逻辑区分,降低耦合度,方便对定时任务的管理。


 
原创粉丝点击