Java spring quartz 定时任务

首先,需要导入quartz 的jar包 

①  applicationContext.xml
 <!-- 轮询任务 -->
 <import resource="classpath:/conf/quartz/ctmanage-schedule.xml" />

②  ctmanage-schedule.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

<!-- 配置该项目的定时任务 -->

<!-- 生成账单-定义调用对象和调用对象的方法 -->
<bean id="generateBillTaskMethod"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="generateBillService" />
<property name="targetMethod" value="generateBill" />
<property name="concurrent" value="false" />
</bean>

<!-- 生成账单-定义触发时间 -->
<!-- 0 0 2 1 * ?    每个月1号凌晨2点执行 正式-->
<!-- 1/15 * * * * ? 启动就执行  每隔15秒执行一次-->
<!-- 0 0/3 * * * ?  每三分钟执行一次 启动服务器三分钟后执行第一次-->
<bean id="generateBillTaskMethodTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="generateBillTaskMethod" />
<property name="cronExpression">
<value>0 0 2 1 * ?</value>
   </property>
</bean>

<!-- 轮询任务列表  -->
<bean id="timerFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
 <ref local="generateBillTaskMethodTrigger" />
</list>
</property>
        <property name="quartzProperties">
  <props>
  <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
  <prop key="org.quartz.threadPool.threadCount">10</prop>
  <prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
  </props>
</property>
<property name="startupDelay" value="5"></property>
</bean>
</beans> 

③ 配置实现类
    <!-- 定时任务 配置 -->
    <bean id="generateBillService" class="com.bontai.ct.manager.helper.timed.GenerateBillService">
        <property name="generateBillBiz" ref="generateBillBiz" />
    </bean>
    <bean id="generateBillBiz" class="com.bontai.ct.manager.helper.timed.impl.GenerateBillBizImpl">
        <property name="ctUserDAO"             ref="ctUserDAO"/>
        <property name="ctGroupDAO"             ref="ctGroupDAO"/>
        <property name="fmOrderDAO"             ref="fmOrderDAO"/>
        <property name="acBillDAO"             ref="acBillDAO"/>
        <property name="acBillOrderDAO"         ref="acBillOrderDAO"/>
        <property name="billDAO"             ref="billDAO"/>
    </bean>

④ 代码
//service
package com.bontai.ct.manager.helper.timed;
public class GenerateBillService {

private GenerateBillBiz generateBillBiz;
public GenerateBillBiz getGenerateBillBiz() {
return generateBillBiz;
}
public void setGenerateBillBiz(GenerateBillBiz generateBillBiz) {
this.generateBillBiz = generateBillBiz;
}

//定时任务-生成账单(每月1日为所有机构自动生成账单)
public synchronized void generateBill(){
System.out.println("=================开始执行轮询任务==================");
this.generateBillBiz.generateBill();
}

}

//biz
package com.bontai.ct.manager.helper.timed;
public interface GenerateBillBiz {
public void generateBill();
}

//bizImpl
package com.bontai.ct.manager.helper.timed.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;

import com.bontai.ct.manager.dao.custom.mybatis.BillDAO;
import com.bontai.ct.manager.dao.db.AcBillDAO;
import com.bontai.ct.manager.dao.db.AcBillOrderDAO;
import com.bontai.ct.manager.dao.db.CtGroupDAO;
import com.bontai.ct.manager.dao.db.CtUserDAO;
import com.bontai.ct.manager.dao.db.FmOrderDAO;
import com.bontai.ct.manager.entity.mapping.AcBill;
import com.bontai.ct.manager.entity.mapping.AcBillOrder;
import com.bontai.ct.manager.entity.mapping.CtUser;
import com.bontai.ct.manager.entity.mapping.FmOrder;
import com.bontai.ct.manager.helper.timed.DatePoint;
import com.bontai.ct.manager.helper.timed.GenerateBillBiz;

public class GenerateBillBizImpl implements GenerateBillBiz{

private SimpleDateFormat timeStampFormater = new SimpleDateFormat("yyyyMMddHHmmss");
private SimpleDateFormat batchNOFormat = new SimpleDateFormat("yyyyMM");
private SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
private SimpleDateFormat monthFormat = new SimpleDateFormat("MM");

private CtUserDAO ctUserDAO;
private CtGroupDAO ctGroupDAO;
private FmOrderDAO fmOrderDAO;
private AcBillDAO acBillDAO;
private AcBillOrderDAO acBillOrderDAO;
private BillDAO billDAO;

//定时任务 - 生成每月机构账单
@Transactional
public void generateBill() {

System.out.println("==================== 定时任务 - 生成每月机构账单 start ======================");

//定义账单时间段(上月1日到最后一日)
Date startTime = DatePoint.getLastMonthBeginDate();
Date endTime = DatePoint.getLastMonthEndDate();
System.out.println("====================startTime:"+startTime+"======================");
System.out.println("====================endTime:"+endTime+"======================");

//获得年月信息
int year = Integer.parseInt(yearFormat.format(startTime));
int month = Integer.parseInt(monthFormat.format(startTime));

//账单批次号
String batchNo = batchNOFormat.format(startTime);

//① 查询所有机构用户
List<CtUser> userList = new ArrayList<CtUser>();
CtUser user = new CtUser();
user.setUserType("1");
userList = this.ctUserDAO.queryCtUser(user);

//根据userId循环插入 账单 和 账单订单关系
for(int i = 0;i<userList.size();i++){

Long userId = userList.get(i).getId();//机构用户id
Long billId = null;

//① 查询用户上月的有效订单个数、账单金额、充值金额
List<AcBill> billInfo = new ArrayList<AcBill>();
Map<String,Object> params = new HashMap<String,Object>();
params.put("userId",userId);
params.put("year", year);
params.put("month", month);
billInfo= this.billDAO.queryOrderCountAndInOutMoneyByMonth(params);

//② 开始插入数据 ac_bill 插入账单
if(billInfo.size()>0){

//获得统计值
int orderCount = billInfo.get(0).getOrderCount();
BigDecimal billMoney = billInfo.get(0).getBillMoney();
BigDecimal depositMoney = billInfo.get(0).getDepositMoney();

//插入
AcBill bill = new AcBill();
bill.setUserId(userId);
bill.setInvoiceStat("0");
bill.setUserType("1");
bill.setStartTime(startTime);
bill.setEndTime(endTime);
bill.setBillSeq(timeStampFormater.format(new Date())+userId);
bill.setBatchNo(batchNo);
bill.setOrderCount(orderCount);
bill.setBillMoney(billMoney);
bill.setDepositMoney(depositMoney);
bill.setBadDebtMoney(BigDecimal.ZERO);
bill.setBadDebtId(null);
bill.setCrtTime(new Date());

this.acBillDAO.insertNotNull(bill);
billId = bill.getId();
}

//③ 查询某机构某月的订单
List<FmOrder> orderList = new ArrayList<FmOrder>();
orderList= this.billDAO.queryBillOrderByMonth(params);

//④ 插入账单-订单关系
for(int j = 0;j<orderList.size();j++){
Long orderId = orderList.get(j).getId();
AcBillOrder bo = new AcBillOrder();
bo.setOrderId(orderId);
bo.setBillId(billId);
this.acBillOrderDAO.insertNotNull(bo);
}
}
System.out.println("==================== 定时任务 - 生成每月机构账单 end ======================");
}

//getters and setters
public CtUserDAO getCtUserDAO() {
return ctUserDAO;
}
public CtGroupDAO getCtGroupDAO() {
return ctGroupDAO;
}
public FmOrderDAO getFmOrderDAO() {
return fmOrderDAO;
}
public AcBillDAO getAcBillDAO() {
return acBillDAO;
}
public AcBillOrderDAO getAcBillOrderDAO() {
return acBillOrderDAO;
}
public void setCtUserDAO(CtUserDAO ctUserDAO) {
this.ctUserDAO = ctUserDAO;
}
public void setCtGroupDAO(CtGroupDAO ctGroupDAO) {
this.ctGroupDAO = ctGroupDAO;
}
public void setFmOrderDAO(FmOrderDAO fmOrderDAO) {
this.fmOrderDAO = fmOrderDAO;
}
public void setAcBillDAO(AcBillDAO acBillDAO) {
this.acBillDAO = acBillDAO;
}
public void setAcBillOrderDAO(AcBillOrderDAO acBillOrderDAO) {
this.acBillOrderDAO = acBillOrderDAO;
}
public BillDAO getBillDAO() {
return billDAO;
}
public void setBillDAO(BillDAO billDAO) {
this.billDAO = billDAO;
}
}

//DatePoint
//获得上月1号的日期
    public static Date getLastMonthBeginDate(){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)-1);
        cal.set(Calendar.DAY_OF_MONTH,1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    //获得上个月最后一天的日期
    public static Date getLastMonthEndDate(){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

⑤ 重要sql 

<!-- 查询某用户某月的完成订单数/账单金额/充值金额 -->
<select id="queryOrderCountAndInOutMoneyByMonth"
parameterType="java.util.Map"
resultType ="com.bontai.ct.manager.entity.mapping.AcBill" >
SELECT DISTINCT
ifnull(
(
SELECT count(*) FROM fm_order o
WHERE o.buyer_user_id = #{userId}
AND o.deal_stat = ‘09‘
AND    YEAR(o.final_time) = #{year}
AND MONTH(o.final_time) = #{month}
),
‘0‘
) as orderCount,
ifnull(
(
SELECT sum(c.pay_money) FROM fm_order o
LEFT JOIN fm_order_cost c ON o.id = c.order_id
WHERE o.buyer_user_id = #{userId}
AND o.deal_stat = ‘09‘
AND YEAR(o.final_time) =  #{year}
AND MONTH(o.final_time) = #{month}
),
‘0‘
) as billMoney,
ifnull(
(
SELECT sum(d.deposit_money) FROM ac_deposit d
WHERE d.user_id = #{userId}
AND d.deposit_stat = ‘1‘
AND d.audit_stat = ‘2‘
AND YEAR(d.deposit_time) = #{year}
AND MONTH(d.deposit_time) = #{month}
),
‘0‘
) as depositMoney
</select>

<!-- 查询某机构某月的订单 -->
<select id="queryBillOrderByMonth"
parameterType="java.util.Map"
resultType ="com.bontai.ct.manager.entity.mapping.FmOrder" >
SELECT o.id as id
FROM fm_order o
WHERE o.buyer_user_id = #{userId}
AND o.deal_stat = ‘09‘
AND YEAR(o.final_time) = #{year}
AND MONTH(o.final_time) = #{month}
</select> 

Java spring quartz 定时任务

时间: 2024-12-16 02:31:19

Java spring quartz 定时任务的相关文章

Spring Quartz定时任务不准时执行

1. 前言 也是前段时间工作上遇到过这样的问题:quartz定时任务没有在预期的时间执行.后来研究了下quartz的机制,查明了原因,这里做个记录和分享. 2. 原因解释 先看一下spring quartz的大致机制或者说原理.quartz任务由一个主线程和线程池中的多个具体的工作线程构成. 主线程是QuartzSchedulerThread, 主要负责获取具体的定时任务和该任务执行的时间(比如可以通过cron expression 得到时间),并分发任务给线程池. 具体的任务由线程池中的工作线

spring quartz 定时任务“Failed to load class &quot;org.slf4j.impl.StaticLoggerBinder”“Checking for available updated version of Quartz”

Failed to load class "org.slf4j.impl.StaticLoggerBinder 需要slf4j-api.jar.slf4j-log4j12.jar Checking for available updated version of Quartz 添加系统属性 System.setProperty("org.terracotta.quartz.skipUpdateCheck", "true"); spring quartz 定

Spring quartz定时任务service注入问题

今天想单元测试一下spring中的quartz定时任务,一顿折腾,到最后总是发现job类里注入的service为null.一开始还以为spring的配置问题,各种找原因,最后还是确定是没有注入. 就去网上搜搜吧.也找出来一些眉目.简单的理解这个原因是job是在quartz中实例化出来的,不受spring的管理.所以就导致注入不进去了.参考这个文章 http://www.tuicool.com/articles/Qjyamu 找着试试的态度,就按照文章里说的.new一个类 public class

spring quartz定时任务配置【基础篇】

一个定时执行的job package dk.spring.quartz; import java.util.Date; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; /** * 使用spring集成的quartz调度 */ public class QuartzTe

[Spring] - Quartz定时任务 - Annotation

Spring + Quartz可以使用annoation方式: 1.AppJob类: package com.my.quartz.testquartz1; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class AppJob { // @Scheduled(fixedDelay=1000)

Spring+Quartz(定时任务)

1.通过maven导入需要jar <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

spring quartz定时任务

配置quartz 在spring中需要三个jar包: quartz-1.8.5.jar.commons-collections-3.2.1.jar.commons-logging-1.1.jar 首先要配置我们的spring.xml xmlns 多加下面的内容. [html] view plaincopy xmlns:task="http://www.springframework.org/schema/task" 然后xsi:schemaLocation多加下面的内容. [html]

spring + quartz定时任务,以及修改定时任务

spring4+quartz2.2.3,定时任务弄好了,修改定时任务没折腾起,没找到合适的解决方案. 最终使用库spring-context-support 3.2.17.RELEASE +  quartz 1.8.0解决,quart1.8.x版本的CronTriggerBean弄起来方便 关键代码如下: 1.maven文件 <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>qu

java中quartz定时任务的执行如何避免并发

在执行定时任务的时候,把定时任务的时间设置为10分钟执行一次,由于数据量很大,第一个十分钟还没执行结束,第二个十分钟已经开始了,这样就造成了并发,但是又不想用 java中的锁,这样很纠结,在网上找了好多资料 其实很简单,我们只要在detail的参数里加上一句话就行了,把这个job设置成有状态的job <property name="concurrent" value="false" /> ③ 指定最终封装出的任务是否有状态 通过concurrent属性指