文章首发于个人博客:https://yeyouluo.github.io
0 预备知识:cron表达式
见 《5 参考》一节。
1 环境
eclipse mars2 + Maven3.3.9
2 开发步骤
2.1 建立一个maven工程
POM如下:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yeyouluo.spring.timer</groupId>
<artifactId>spring-timer-demo</artifactId>
<version>0.0.1-SNAPSHOT</version> <properties>
<spring.version>4.2.6.RELEASE</spring.version>
<slf4j.version>1.7.2</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- common-logging 实际调用slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- java.util.logging 实际调用slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.lazyluke</groupId>
<artifactId>log4jdbc-remix</artifactId>
<version>0.2.7</version>
</dependency>
<!-- spring核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>4.2.5.RELEASE</version>
</dependency> </dependencies> <packaging>jar</packaging>
</project>POM.xml
pom文件中可能加入了很多没有使用的jar,比如和mybatis、druid、mysql-connector相关的jar,以备后用。
2.2 添加配置文件
①log4j.properties
log4j.rootLogger=INFO, Console, RollingFile
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n #RollingFile
log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.RollingFile.File=logs/log.log
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%nlog4j.xml
②spring-base.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:task="http://www.springframework.org/schema/task"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="readDBTask" class="com.yeyouluo.spring.timer.service.ReadDBTask"></bean> <task:scheduled-tasks>
<task:scheduled ref="readDBTask" method="doSomething" cron="0/3 * * * * ?"/>
</task:scheduled-tasks> </beans>spring-base.xml
注意引入命名空间
xmlns:task=”http://www.springframework.org/schema/task“ 和
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd2.3 创建定时任务ReadDBTask
package com.yeyouluo.spring.timer.service;
import org.apache.log4j.Logger;
public class ReadDBTask {
public static Logger log = Logger.getLogger(ReadDBTask.class);
public void doSomething() {
log.info("********");
log.info("定时任务执行。");
}
}ReadDBTask.java
2.4 添加启动函数Main
package com.yeyouluo.spring.timer.start;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main { public static Logger logger = LoggerFactory.getLogger(Main.class);
public static final String config = "spring-base.xml"; public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(config);
logger.info("spring timer started");
if( ctx != null ) {
ctx.start();
}
}
}Main.java
3 流程分析
在启动函数Main.java右键 –> run as –> Java Application。
结果为:每3秒在控制台输出如下:
2017-10-16 15:03:54,885 [main] INFO [com.yeyouluo.spring.timer.start.Main] - spring timer started
2017-10-16 15:03:57,002 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - **
2017-10-16 15:03:57,003 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - 定时任务执行。
2017-10-16 15:04:00,001 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - **
2017-10-16 15:04:00,001 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - 定时任务执行。
2017-10-16 15:04:03,001 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - **
2017-10-16 15:04:03,001 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - 定时任务执行。
2017-10-16 15:04:06,002 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - **
2017-10-16 15:04:06,002 [pool-1-thread-1] INFO [com.yeyouluo.spring.timer.service.ReadDBTask] - 定时任务执行。- 从入口函数开始,加载spring配置文件spring-base.xml。
- spring-base.xml定义了 ,指向定时任务类com.yeyouluo.spring.timer.service.ReadDBTask的doSomething方法。
- 执行doSomething方法中的逻辑。
4 拓展:打成jar部署到单独的服务器上
目标:用java命令拉起程序。
步骤:
①将依赖jar提取出来,放入D:\timer\lib
②maven打包程序,将生成的jar放入D:\timer\lib
③在D:\timer\lib下新建一个文件start.cmd,内容如下:java -Djava.ext.dirs=D:\timer\lib -Xms1024m -Xmx1024m com.yeyouluo.spring.timer.start.Main
④双击start.cmd。
结果:部署在Linux上是一样的操作,仅仅是替换启动文件类型为.sh,并且内容中的路径改为Linux的路径。
如果是部署在Linux服务器上,还可以编写如下文件:
stop.shjps | grep Main | awk '{print $1}' | xargs kill -9
注:通过kill进程的方式实现,不优雅。尤其要注意还没有其他名称为Main的进程,防止误杀。clean-log.sh
rm -f logs/*
5 参考