昨天 老大 交下一件任務,在Spring框架下構建一個郵件自動發送模塊,接到此任務的第一個想法是利用Timer, 它小巧功能夠用.
以下是寫的一個測試類.写道
package umt.michael.tsk.test;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* @Title: Test.java
* @Package umt.michael.tsk.test
* @Description: TODO
* @author MichaelYang
* @Email apac.yang@gmail.com
* @date 2011/10/13 下午9:19:01
* @version V1.0
*/
class DateTask extends TimerTask{
@Override
public void run() {
System.out.println("現在時間:" + new Date());
}
}
public class Test {
/**
* @Title: main
* @Description: TODO
* @param args
* @return void
*/
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new DateTask(), 1000,5000);
try{
Thread.sleep(20000);
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
}
System.out.println("結束時間是:" + new Date());
timer.cancel();
}
}
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* @Title: Test.java
* @Package umt.michael.tsk.test
* @Description: TODO
* @author MichaelYang
* @Email apac.yang@gmail.com
* @date 2011/10/13 下午9:19:01
* @version V1.0
*/
class DateTask extends TimerTask{
@Override
public void run() {
System.out.println("現在時間:" + new Date());
}
}
public class Test {
/**
* @Title: main
* @Description: TODO
* @param args
* @return void
*/
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new DateTask(), 1000,5000);
try{
Thread.sleep(20000);
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
}
System.out.println("結束時間是:" + new Date());
timer.cancel();
}
}
結果為:
現在時間:Thu Oct 13 21:30:12 CST 2011 現在時間:Thu Oct 13 21:30:17 CST 2011 現在時間:Thu Oct 13 21:30:22 CST 2011 現在時間:Thu Oct 13 21:30:27 CST 2011 結束時間是:Thu Oct 13 21:30:31 CST 2011
頭兒卻明確要用Quartz 這個任務調度框架.沒辦法,只好拼了,从Quartz官网 http://www.quartz-scheduler.org/ 上下载jar包 现在该版本已经到了2.10,但是在国外一个网站发现貌似 2.1 和Spring3.x 无法兼容,没有验证,为了安全起见,我下载的是穩定版本quartz1.8.5. 相關配置如下.
Web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/spring-quartz.xml</param-value> </context-param> <!-- 配置日誌文件打印 --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/properties/log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>6000</param-value> </context-param> <listener> <listener-class> org.springframework.web.util.Log4jConfigListener </listener-class> </listener> <!-- 此監聽器 用於加載組件 --> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 字符流過濾器 --> <filter> <filter-name>characterEncoding</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置代理轉發請求 --> <servlet> <servlet-name>login</servlet-name> <servlet-class>com.saq.michael.servlet.HttpServletProxy</servlet-class> <init-param> <param-name>targetServlet</param-name> <param-value>loginServlet</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>
<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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <import resource="db-config.xml" /> <!-- 定時執行的任務 --> <bean id="jobDetailBean" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="com.saq.michael.job.SendEmailJob"/> <property name="jobDataAsMap"> <map> <entry key="sendEmailService" value-ref="sendEmailService"/> </map> </property> </bean> <!--觸發器 --> <bean id="simpleTriggerBean" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail"> <ref bean="jobDetailBean"/> </property> <property name="repeatInterval"> <value>45000</value> </property> <property name="startDelay"> <value>1000</value> </property> </bean> <!-- 任務調度器, 可配置 dataSoure --> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="simpleTriggerBean"/> </list> </property> </bean> </beans>
db-config.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!--加載屬性文件 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>/WEB-INF/properties/common.properties</value> </list> </property> </bean> --> <bean id="loginServlet" class="com.saq.michael.servlet.CommonServlet"> <property name="operation" ref="operation" /> </bean> <bean id="sendEmailService" class="com.saq.michael.service.impl.SendEmailService"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="url" value="jdbc:sqlserver://XXXXXXX:1433;DatabaseName=testPaper" /> <property name="username" value="XXX" /> <property name="password" value="XXXXX" /> </bean> <!-- set TransactionManager message--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!--利用了拦截器的原理--> <bean id="transactionInterceptor" lazy-init="true" scope="singleton" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager"> </property> <!-- 配置事务属性 -Exception 表示有Exception抛出时,事务回滚. readonly 就是read only, 一般用于查询的方法,优化作用. prop key="delete*" 表示方法名 可以用戶通配符* PROPAGATION_REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 --> <property name="transactionAttributes"> <props> <prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="operate*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="update*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="save*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="sendMail">PROPAGATION_REQUIRED,-Exception</prop> <prop key="find*">PROPAGATION_NEVER,readOnly</prop> <prop key="get*">PROPAGATION_NEVER,readOnly</prop> </props> </property> </bean> <!--Spring 自動代理所有的 ServiceName 為 *ServiceImpl 的Service--> <bean id="txProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>*Service</value> </list> </property> <property name="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> </bean> </beans>
SendEmailService.java
package com.saq.michael.service.impl; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import javax.servlet.ServletException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.log4j.Logger; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import com.saq.michael.bean.EmailAddress; import com.saq.michael.method.reportViaUrl; /** * @Title: SendEmailService.java * @Package com.saq.michael.service.impl * @Description: 郵件發送,數據更新. * @author MichaelYang * @Email michael.yang@earlylight.com.hk * @date Oct 20, 2011 2:48:34 PM * @version V1.0 */ public class SendEmailService { private JdbcTemplate jdbcTemplate; private Connection con ; private static final Log logger = LogFactory.getLog(SendEmailService.class); public void setDataSource(DataSource dataSource) { if (this.jdbcTemplate == null) this.jdbcTemplate = new JdbcTemplate(dataSource); } /** * 發送郵件的相關信息 * @param mailSender * @return * @throws SQLException * @throws Exception * @throws IOException * @throws ServletException */ public boolean sendMail(EmailAddress emailAddress,File file) throws MessagingException, SQLException{ logger.info(" ... 開始發送郵件.... "); if(con == null || con.isClosed()) { con = this.getConnection(); logger.info(con.hashCode()); } String msg = reportViaUrl.reportHTMLStringViaURL(emailAddress.getUrl(),con); //獲取郵件內容 JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); mailSender.setHost("XXXXX"); MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); message.setContent(msg, "text/html;charset=UTF-8");//文本類型 message.setSubject(msg, "UTF-8"); helper.setTo(emailAddress.getRecipients()); helper.setText(msg); if(file!=null && file.length()>0){ helper.addAttachment(file.getName(), file);//添加附件 } mailSender.send(message); logger.info(" ....... "); return true; } /** * 獲取異常信息. * @param throwable * @return String exceptionMsg */ public String getException(Throwable throwable){ StringBuffer resultMess =new StringBuffer(); if(resultMess.length()>500){ return resultMess.substring(0, 500); }else{ resultMess.append(throwable.toString()+"\n"); if(throwable.getCause()!=null){ resultMess.append("Cause By: "); resultMess.append(getException(throwable.getCause())); } } return resultMess.length()>500?resultMess.substring(0, 500):resultMess.toString(); } /** * 從數據庫中讀取相應的數據,并執行相應操作 * @param <EmaillAddress> * @param con * @return * @throws SQLException * @throws IOException */ @SuppressWarnings({"unused","unchecked"}) public List<EmailAddress> getEmailAddress(String sql){ System.out.println(" ... 查詢出郵件地址以及對應的URL ... "); System.out.println(" ... SQL:"+sql+"... "); List<EmailAddress> list = this.jdbcTemplate.query(sql, new EmailAddressRowMapper()); return list; } /** * 更新發送成功的數據 * @param list * @return */ @SuppressWarnings("unchecked") public boolean updateEmailSuccess(final List<Integer> list){ this.jdbcTemplate.update(new PreparedStatementCreator(){ public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = con.prepareStatement("UPDATE EMAIL_ADDRESS_URL SET ENABLE=0 WHERE PK_EAU_ID = ?"); for(int pk_id:list){ System.out.println(" PK_ID: "+pk_id); ps.setInt(1, pk_id); ps.addBatch(); } return ps; } }); return true; } /** * * @param list * @return */ @SuppressWarnings("unchecked") public boolean updateEmailSuccess(final int pk_id){ this.jdbcTemplate.update(new PreparedStatementCreator(){ public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = con.prepareStatement("UPDATE EMAIL_ADDRESS_URL SET ENABLE=0 WHERE PK_EAU_ID = ?"); System.out.println(" PK_ID: "+pk_id); ps.setInt(1, pk_id); return ps; } }); return true; } public boolean updateEmailFailed(final EmailAddress address){ final String SQL = "UPDATE EMAIL_ADDRESS_URL SET modifiedDate = ?),SET tryAgain =1 WHERE PK_EAU_ID = ?"; logger.info(SQL); this.jdbcTemplate.update(new PreparedStatementCreator(){ public PreparedStatement createPreparedStatement(Connection con) throws SQLException{ PreparedStatement ps = con.prepareStatement(SQL); //System.out.println(" PK_ID: "+address.getId()); ps.setDate(1, (java.sql.Date) new Date()); ps.setInt(2, address.getId()); return ps; } }); return true; } public boolean updateEmailFailed(final List<EmailAddress> list){ final String SQL = "UPDATE EMAIL_ADDRESS_URL SET modifiedDate = getDate(),SET tryAgain =1,SET exceptionMsg =? WHERE PK_EAU_ID = ?"; logger.info(SQL); this.jdbcTemplate.update(new PreparedStatementCreator(){ public PreparedStatement createPreparedStatement(Connection con) throws SQLException{ PreparedStatement ps = con.prepareStatement(SQL); for(EmailAddress address:list){ System.out.println(" PK_ID: "+address.getId()); ps.setString(1, address.getExceptionMsg()); ps.setInt(2, address.getId()); ps.addBatch(); } return ps; } }); return true; } public Connection getConnection() throws CannotGetJdbcConnectionException, SQLException{ if(con == null || con.isClosed()){ con = DataSourceUtils.getConnection(this.jdbcTemplate.getDataSource()); logger.info(" [創建Connection hashCode:"+con.hashCode()+" ]"); } return con; } }
SendEmailJob.java
package com.saq.michael.job; import java.sql.SQLException; import java.util.List; import javax.mail.MessagingException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; import com.saq.michael.bean.EmailAddress; import com.saq.michael.service.impl.SendEmailService; /** * @Title: TestJob.java * @Package com.saq.michael.job * @Description: 郵件發送. * @author MichaelYang * @Email michael.yang@earlylight.com.hk * @date Oct 13, 2011 8:41:30 PM * @version V1.0 * @param <EmaillAddress> */ public class SendEmailJob extends QuartzJobBean { private SendEmailService sendEmailService; private static final Log logger = LogFactory.getLog(SendEmailJob.class); public void setSendEmailService(SendEmailService sendEmailService) { if(this.sendEmailService == null)this.sendEmailService = sendEmailService; } @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { logger.info("...開始執行任務..."); List<EmailAddress> addressList =this.sendEmailService.getEmailAddress("select * from EMAIL_ADDRESS_URL WHERE ENABLE=1"); for(EmailAddress emailAddress:addressList){ try { boolean flag =this.sendEmailService.sendMail(emailAddress, null); if(flag){ this.sendEmailService.updateEmailSuccess(emailAddress.getId()); }else{ this.sendEmailService.updateEmailFailed(emailAddress); } } catch (MessagingException e) { logger.error(e.getLocalizedMessage()); e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } logger.info("...任務執行完畢..."); } }
其中用到了iReport,關於java中iReport開發,留給下次總計
发表评论
-
关于如何在linux 下配置nginx+php+mysql
2013-12-06 14:51 0最近刚刚迁移完公司的B2B网站 [ www.b2b179.c ... -
Apache 配置需注意的事情
2013-07-19 16:41 828在LINUX 下构建Apache环境时需要特别注意seli ... -
phpb2b 会员登录系统 java 实现
2013-07-03 14:30 0一直忙与php 开发,对老本行 java 放下很久了,因公司 ... -
linux 系统日志
2013-03-27 12:12 759日志分类: 1. 连接时间的日志 连接时间日志一般由/va ... -
centos 关于禁用触摸板
2013-03-25 10:31 1965装上centos 6 后,发现没办法禁用触摸板 解决方法 ... -
Centos5.4 安装mysql
2012-08-31 00:00 777最近老哥在万网买了一台服务器,坑人的万网,里面的配置基本为零 ... -
Install EclipseIDE ,Tomcat 6 on Ubuntu11.04
2011-10-08 09:15 893Setp1: Create Folder michael@X ... -
Install sun-jdk-1.6 on Ubuntu11.04
2011-10-06 21:29 1174setp1: download jdk ...
相关推荐
3. **调度器配置**:`SchedulerFactoryBean`是Spring对Quartz调度器的包装,它管理所有的触发器和任务。在这里,我们将`cron`触发器添加到调度器中,使得任务与触发器关联起来。 接下来,我们看下服务类和服务的...
这篇博客“Spring下使用Quartz任务调度”将深入探讨如何在Spring环境中集成并使用Quartz进行任务管理。 Quartz是一个开源的作业调度框架,它可以被用来创建、调度和执行任务,支持复杂的调度策略。其核心特性包括可...
Spring框架和Quartz是两个广泛使用的工具,它们可以协同工作以实现复杂和灵活的任务调度。本篇文章将深入探讨如何使用Spring与Quartz结合来创建一个任务调度的小例子。 首先,Spring是一个开源的Java企业级应用开发...
Spring框架作为Java领域广泛使用的轻量级框架,提供了与第三方库Quartz的整合,使得开发者能够轻松地在Spring应用中实现复杂的定时任务调度。Quartz是一款开源的作业调度框架,支持丰富的调度策略,可以满足各种定时...
本项目"spring+quartz任务调度代码版"显然是一个结合了这两者的实践案例,旨在展示如何在Spring环境下集成和使用Quartz进行任务调度。 Spring框架是一个开源的应用框架,它提供了丰富的功能,包括依赖注入、AOP...
标题“Spring quartz任务调度”指的是在Java开发中利用Spring框架集成Quartz库来实现应用程序的任务调度功能。Quartz是一款开源的作业调度框架,它允许开发者安排任务在特定时间执行,而Spring框架则提供了与Quartz...
本源码为基于Spring和Quartz的任务调度监控管理平台设计,共包含553个文件,其中css文件...该项目使用maven编译,是一个基于spring、quartz的任务调度和监控管理平台,采用了easyui、springMVC、hibernate等技术构建。
总的来说,Quartz任务调度器与Spring的整合使得我们能够在应用中轻松地实现定时任务的管理,而无需关心任务执行的具体细节。它为开发者提供了一套强大的工具,帮助我们在项目中实现定时任务的自动化,提高系统的运行...
通过深入学习和实践这个示例,你将能够掌握如何利用Spring和Quartz构建灵活、可扩展的定时任务系统,这对于开发企业级应用,特别是需要定期执行数据处理、报告生成或其他后台任务的应用来说,是非常有价值的。
本项目名为“schedule-job”,是基于Spring Boot框架与Quartz库构建的分布式任务调度系统,它允许开发者方便地定义、管理和执行定时任务。 【Spring Boot基础知识】 Spring Boot是由Pivotal团队提供的全新框架,其...
Spring Quartz 是一个强大的开源任务调度框架,它允许开发者在Java应用程序中定义和执行定时任务。在Spring框架中集成Quartz,可以充分利用Spring的IoC(Inversion of Control)和AOP(Aspect Oriented Programming...
在Spring的配置文件(如`applicationContext.xml`)中,定义`SchedulerFactoryBean`以创建和配置Quartz调度器。 ```xml <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean...
总结,Spring支持的Quartz程序调度提供了强大的定时任务管理能力,结合Spring的依赖注入和管理功能,可以帮助开发者高效地构建和维护复杂的应用程序。在实际使用中,理解并熟练掌握Spring与Quartz的集成方式,以及...
通过这种方式,Spring会自动启动Quartz调度器,并根据配置的触发器执行相应的任务。你还可以使用`@Scheduled`注解在方法级别定义定时任务,这是一种更简单的调度方式,适用于简单的场景。 总之,Spring Quartz定时...
本篇将深入探讨如何利用Spring进行任务调度,并结合代码演示和Quartz库的使用来丰富这一主题。 首先,Spring提供了两种主要的任务调度机制:Spring内置的`TaskExecution`和`TaskScheduling`以及与Quartz Scheduler...
【Quartz任务调度集群】是Java开发中解决定时任务需求的一种高效方案,它由OpenSymphony团队开发,自2001年...总之,Quartz为Java开发者提供了一个强大且易用的任务调度框架,使得构建可靠的定时任务系统变得更加便捷。
### 三、Quartz调度策略 Quartz提供了多种调度策略,包括: - **简单触发器(SimpleTrigger)**:按固定间隔重复执行任务。 - **Cron触发器(CronTrigger)**:基于Cron表达式来定义触发时间,支持复杂的定时规则...
SpringMVC 是一个用于构建 Web 应用程序的轻量级、模型-视图-控制器(MVC)框架,而 Quartz 是一个开源的任务调度库,能够帮助开发者在应用程序中实现定时任务的管理。接下来,我们将深入探讨这两个框架如何协同工作...
总的来说,Spring、MyBatis和Quartz的结合,为Java开发者提供了一套强大的工具集,可以方便地构建和管理具有动态定时任务功能的企业级应用。这种技术栈的使用,不仅可以提高开发效率,还能保证应用的稳定性和扩展性...
通过以上知识,你可以有效地在Spring环境中构建和管理任务调度。无论是简单的周期性任务还是复杂的调度逻辑,Spring都提供了足够的灵活性和强大功能来满足需求。在实际项目中,应根据业务需求选择合适的任务调度策略...