spring调用webservice定时器@scheduled,可以调用service查询数据,为什么不能修改和新增数据

SpringBoot--@Scheduled定时获取access token,并且缓存access token | Souvc
欢迎关注我的微信公众号
常用学习资料导航
问题反馈。如果大家在使用网站的过程中遇到什么问题,欢迎大家在评论中评论,或者发送邮件到邮箱(daliu_)进行反馈。
账号重置密码问题。重置密码的时候,点击邮箱链接如果不能进行重置密码并且造成循环重置的问题,请把重置链接复制到浏览器进行访问。
3. 如何快速找到自己的问题解决方案,可以直接通过搜素框进行搜索。
4. 欢迎大家收藏(ctrl+d),关注我的博客!
5. 哈哈,只学习,不分享,那就是在耍流氓!!那先分享博客给朋友一起使用吧!
6.由于3月份,托管网站的商家说,不给发邮件进行通知,并把端口封了,所以把注册用户以及多说评论官网也宣布关闭评论了,所以这个插件也停止使用了,暂时不能进行评论。
7. 大家如果在百度需要找到我的网站,可以直接搜:souvc+关键字,比如说要找SpringBoot ,那么就找souvc
SpringBoot 即可。使用轻量级Spring @Scheduled注解执行定时任务
时间: 17:09:43
&&&& 阅读:457
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&& & &WEB项目中需要加入一个定时执行任务,可以使用Quartz来实现,由于项目就一个定时任务,所以想简单点,不用去配置那些Quartz的配置文件,所以就采用了Spring @Scheduled注解来实现了定时任务。在这里做个备注。
spring配置文件 &xmlns中加入一段:
xmlns:task="http://www.springframework.org/schema/task"
然后xsi:schemaLocation多加下面的内容:
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
配置文件中启动TASK注解:
&task:annotation-driven/&
编写JAVA代码:
@Component
public class ScheduledTaskManager {
* cron表达式:* * * * * *(共6位,使用空格隔开,具体如下)
* cron表达式:*(秒0-59) *(分钟0-59) *(小时0-23) *(日期1-31) *(月份1-12或是JAN-DEC) *(星期1-7或是SUN-SAT)
* 定时卡点计算。每天凌晨 02:00 执行一次
@Scheduled(cron = "0 0 2 * * *")
public void autoCardCalculate() {
System.out.println("定时卡点计算... " + new Date());
* 心跳更新。启动时执行一次,之后每隔1分钟执行一次
@Scheduled(fixedRate = )
public void heartbeat() {
System.out.println("心跳更新... " + new Date());
@Scheduled有两种方式:cron表达式和fixedRate
两种都可以定时每隔一段时间执行,个人觉得两种方式区别是fixedTate方式是应用启动时候会先执行一次,cron表达式能配置更加复杂的情况。
个人使用中出现了2个问题:
1.项目启动时候会报出异常信息:
  解决:这个错误问题其实是debug级别输出,就是不影响定时任务的使用,在网上看到别人有这样解释
  Spring的定时任务调度器会尝试获取一个注册过的 task scheduler来做任务调度,它会尝试通过BeanFactory.getBean的方法来获取一个注册过的scheduler bean,获取的步骤如下: &
  a.尝试从配置中找到一个TaskScheduler Bean &
  b.寻找ScheduledExecutorService Bean &
  c.使用默认的scheduler &
  前两步,如果找不到的话,就会以debug的方式抛出异常,
  分别是: &logger.debug("Could not find default TaskScheduler bean", ex);
  logger.debug("Could not find default ScheduledExecutorService bean", ex);
  &所以,日志中打印出来的两个异常,根本不是什么错误信息,也不会影响定时器的使用,只不过是spring的自己打印的一些信息罢了
  如果想去掉这个输出,可以在log4j配置文件中增加一行即可:
log4j.logger.org.springframework.scheduling = INFO
2.发现定时任务每次执行都会执行两次
  这个问题后来发现是由于Spring的配置文件被加载了两次造成的,listener和DispatcherServlet都会初始化spring配置文件,所有注释掉listener即可
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&classpath:config/application-context.xml&/param-value&
&/context-param&
&!-- Spring监听器 --&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
&/listener&
&!-- servlet设置,将所有请求接到org.springframework.web.servlet.DispatcherServlet进行处理 --&
&servlet-name&spring&/servlet-name&
&servlet-class&org.springframework.web.servlet.DispatcherServlet&/servlet-class&
&init-param&
&param-name&contextConfigLocation&/param-name&
&param-value&classpath:config/application-context.xml&/param-value&
&/init-param&
&load-on-startup&1&/load-on-startup&
&/servlet&
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://www.cnblogs.com/lylife/p/5977574.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!1054人阅读
【转载来自于http://blog.csdn.net/qq/article/details/】
在使用 @Scheduled注解时很多人都为cron表达式无法进行配置进行烦恼吧,为何不像quartz般能在applicationContext中进行配置。
告诉大家其实是能applicationContext进行配置。
&context:annotation-config /&
上面这一种方式是大家最头痛的问题吧,如果人员需要测试这个任务,你需要不停生成class文件给测试人员替换,是不是非常郁闷,其实我前期也被逼疯了。我前期一直使用的Quartz,因此对该注解不是非常熟悉,趁着这个闲时想看看这个注解,结果一百度,却找不到想要的结果。。换上我的谷歌继续,功夫不负有心人,找到了一篇该注解的详解,因此有了这一篇文章。废话不多说,看原子弹来了!博客分类:
java的几种定时任务的比较:
我最近看了spring的定时任务源码,发现可以使用ScheduledExecutor来实现quartz的cron表达式的配置。并且我加入了可以通过页面修改和配置cron表达式来达到更灵活的配置。
加入的功能如下:
1、开启和关闭任务
2、修改cron表达式并自动重新发布任务
3、基于注解的配置
4、任务持久化到数据库
Spring容器启动时扫描所有被注解的方法,并发布需要启动的任务(代码48行):
@Component
public class TaskConfig implements BeanPostProcessor, ApplicationContextAware, ApplicationListener&ContextRefreshedEvent& {
private ApplicationContext applicationC
private Set&JobDetail& jobDetails = new HashSet&JobDetail&();
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
if (!bean.getClass().getCanonicalName().startsWith("com.xxx.task")) {
final Class&?& targetClass = AopUtils.getTargetClass(bean);
ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Job annotation = AnnotationUtils.getAnnotation(method, Job.class);
if (annotation != null) {
JobDetail job = new JobDetail();
job.setCronExp(annotation.cron());
job.setJobClass(bean.getClass());
job.setJobName(annotation.name());
job.setValid(true);
job.setMethodName(method.getName());
jobDetails.add(job);
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext() != this.applicationContext) {
for (JobDetail job : jobDetails) {
JobService jobService = applicationContext.getBean(JobService.class);
JobDetail jobDetail = jobService.findJobByName(job.getJobName());
if (jobDetail == null) {
jobDetail =
jobService.schedule(jobDetail);
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationC
再来jobService的:
public class JobService {
private TaskScheduler taskScheduler = new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(1));
private final Map&String, ScheduledFuture&?&& scheduledFutures = new HashMap&String, ScheduledFuture&?&&();
* 保存jobName与task的映射关系,等
private Map&String, Runnable& runnableMap = new ConcurrentHashMap&String, Runnable&();
private TriggerContext triggerContext = new SimpleTriggerContext();
* 根据jobDetail计划一次新的任务
* 任务执行完毕自动计算下次任务执行时间并保存
* @param job
@Transactional
public void schedule(final JobDetail job) {
CronTrigger trigger = new CronTrigger(job.getCronExp());
final CronSequenceGenerator sequenceGenerator = new CronSequenceGenerator(job.getCronExp(), TimeZone.getDefault());
job.setNextExecTime(sequenceGenerator.next(new Date()));
commonDao.saveOrUpdate(job);
ErrorHandler errorHandler = new JobErrorHandler(job);
Runnable runnable = new Runnable() {
public void run() {
// 每一次执行任务都需要获取最新的任务状态
JobDetail currentJob = findJobByName(job.getJobName());
if (currentJob != null && currentJob.isValid()) {
Object o = SpringContextUtil.getBean(currentJob.getJobClass());
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(currentJob.getJobClass(),
currentJob.getMethodName()), o);
Date d = new Date();
currentJob.setLastExecTime(d);
currentJob.setNextExecTime(sequenceGenerator.next(new Date()));
commonDao.saveOrUpdate(currentJob);
cancel(job.getJobName());
Runnable delegatingErrorHandlingRunnable = TaskUtils.decorateTaskWithErrorHandler(runnable, errorHandler, false);
this.scheduledFutures.put(job.getJobName(), taskScheduler.schedule(delegatingErrorHandlingRunnable, trigger));
* 停止任务
* @param jobName
@Transactional
public void stopJob(String jobName) {
String update = "update cms_sys_jobdetails set VALID='N' where JOB_NAME='" + jobName + "'";
commonDao.getCurrentSession().createSQLQuery(update).executeUpdate();
this.cancel(jobName);
* 结束任务
* @param jobName
@Transactional
public void startJob(String jobName) {
JobDetail job = this.findJobByName(jobName);
job.setValid(true);
this.schedule(job);
* 重置cron表达式
* @param jobName
* @param cron
@Transactional
public void resetCron(String jobName, String cron) {
new CronSequenceGenerator(cron, TimeZone.getDefault());
JobDetail job = this.findJobByName(jobName);
job.setCronExp(cron);
commonDao.saveOrUpdate(job);
if (job.isValid()) {
this.cancel(jobName);
this.schedule(job);
* 取消未执行的任务
* @param jobName
private void cancel(String jobName) {
ScheduledFuture r = scheduledFutures.get(jobName);
if (r != null) {
r.cancel(true); //参数true表示如果任务正在执行,则强行关闭,否则等待执行完毕关闭
* 任务处理失败时的ErrorHandler
private class JobErrorHandler implements ErrorHandler {
private JobD
public JobErrorHandler(JobDetail job) {
this.job =
private final Log logger = LogFactory.getLog(JobErrorHandler.class);
public void handleError(Throwable t) {
logger.error("Unexpected error occurred in scheduled task===&" + job.getJobName(), t);
JobDetai是需要持久化到数据库的实体:
@Table(name = "CMS_SYS_JOBDETAILS")
public class JobDetail implements Serializable {
private static final long serialVersionUID = 9265016L;
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name="JOB_NAME", length = 255)
private String jobN
@Column(name="CRON_EXP", length = 255)
private String cronE
@Column(name = "LAST_EXEC_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Date lastExecT
@Column(name = "NEXT_EXEC_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Date nextExecT
@Type(type = "yes_no")
@Column(name = "VALID")
@Column(name = "JOB_CLASS")
private Class jobC
@Column(name = "METHOD_NAME")
private String methodN
public String getMethodName() {
return methodN
public void setMethodName(String methodName) {
this.methodName = methodN
public Class getJobClass() {
return jobC
public void setJobClass(Class jobClass) {
this.jobClass = jobC
public Long getId() {
public void setId(Long id) {
public String getJobName() {
return jobN
public void setJobName(String jobName) {
this.jobName = jobN
public String getCronExp() {
return cronE
public void setCronExp(String cronExp) {
this.cronExp = cronE
public Date getLastExecTime() {
return lastExecT
public void setLastExecTime(Date lastExecTime) {
this.lastExecTime = lastExecT
public Date getNextExecTime() {
return nextExecT
public boolean isValid() {
public void setValid(boolean valid) {
this.valid =
public void setNextExecTime(Date nextExecTime) {
this.nextExecTime = nextExecT
自定义注解Job,可以加在所有需要定时任务的方法上
* 用来注解所有需要做定时任务的方法,name和cron是必填项,分别代表任务名称和任务的cron
* 加了这个注解的方法在被加载到spring上下文时会被{@link TaskConfig}拦截并将所有的配置
* 信息加载到数据库里面,接着初始化所有的定时任务。定时任务所有的对外暴露的API都被放到了
* {@link com.xxx.service.JobService}里面了。
* @see com.xxx.service.JobService
* @see TaskConfig
* @author: bigtian
* Date: 12-6-20
* Time: 下午7:26
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Job {
String name();
String cron();
浏览 10236
浏览: 23757 次
来自: 合肥
zhang017 写道basePath /ws/@WebSer ...
basePath /ws/@WebService(servic ...
&script&alert(1);&scri ...
为什么没有找到 findJobByName 这个方法的定义。
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 spring 调用service 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信