springmvc定时任务注入问题

ramer 发布于 2016/04/28 12:19
阅读 1K+
收藏 1

    数据库中有一个字段会不断更新,并且本地有一个文件存储着这个字段的信息,我写了一个定时器,自动更新文件,但是出问题了,下面是定时器代码:

package org.ramer.diary.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.ramer.diary.service.TopicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;

/**
 * schedule job:
 *  execute  every ten seconds;
 *  query tags from table topic and remove duplicates ,and compare to local file "/xml/tags.xml";
 *  new tags will be append to file.
 *
 * @author ramer
 *
 */
@Controller
public class ScheduleWork implements ServletContextListener {

  public ScheduleWork() {
  }

  /**
   * get millis for 'time'
   * @param time "HH🇲🇲ss"
   * @return
   */
  private long getTimeMillis(String time) {
    try {
      DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH🇲🇲ss");
      DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd");
      Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time);
      return curDate.getTime();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return 0;
  }

  @Override
  public void contextDestroyed(ServletContextEvent arg0) {

  }

  @Autowired
  TopicService topicService;
  @Value("#{diaryProperties['tags.xml.position']}")
  private String file;

  @Override
  public void contextInitialized(ServletContextEvent servletContextEvent) {
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    // execute every ten seconds
    long oneDay = 10 * 1000;

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH🇲🇲ss");
    // start now
    long initDelay = getTimeMillis(simpleDateFormat.format(new Date()))
        - System.currentTimeMillis();
    initDelay = initDelay > 0 ? initDelay : oneDay + initDelay;
    // start execute job
    executor.scheduleAtFixedRate(() -> {
      System.out.println("----------start update tags-----------");
      // tags in database
      System.out.println(topicService);
      System.out.println(file);
      List<String> tags = topicService.getAllTags();
      // remove duplicate
      StringBuilder stringBuilder = new StringBuilder();
      for (String string : tags) {
        stringBuilder.append(string + ";");
      }
      String[] strings = stringBuilder.toString().split(";");
      // Arrays.asList will return a proxy with doesn't implement add() and remove(),so create a list.
      List<String> tagslist = Arrays.asList(strings);
      tagslist = new ArrayList<>(tagslist);
      for (int i = 0; i < tagslist.size(); i++) {
        for (int j = i + 1; j < tagslist.size(); j++) {
          if (tagslist.get(i).equals(tagslist.get(j))) {
            tagslist.remove(j);
            j--;
          }
        }
      }
      // tags no duplicate.
      tags = tagslist;
      System.out.println("tags in database: ");
      for (String string : tags) {
        System.out.println("\t" + string);
      }
      List<String> tagsInFile = new ArrayList<>();
      try {
        // read tags in local file
        tagsInFile = FileUtils.readTag(file, servletContextEvent.getServletContext());
      } catch (Exception e) {
        System.out.println("Exception ScheduleWork(Line 111)");
        e.printStackTrace();
      }
      System.out.println("文件中的tags: ");
      for (String string : tagsInFile) {
        System.out.println("\t" + string);
      }
      // less than tags in database ,so each the tags in local file
      for (int i = 0; i < tags.size(); i++) {
        if (!tagsInFile.contains(tags.get(i))) {
          tagsInFile.add(tags.get(i));
          i++;
        }
      }
      System.out.println("update tags: ");
      for (String string : tagsInFile) {
        System.out.println("\t" + string);
      }

      try {
        // update tags in local file
        FileUtils.writeTag(tagsInFile, file, servletContextEvent.getServletContext());
      } catch (Exception e) {
        System.out.println("Exception ScheduleWork(Line 129)");
        e.printStackTrace();
      }

    }, initDelay, oneDay, TimeUnit.MILLISECONDS);
  }

}



运行时,发现上面的‘topicService’和file总是null,也就是注入失败了,请问是什么原因呢?

加载中
0
maradona
maradona

虽然感觉楼上说的比较清楚,但楼主貌似没理解

俺就懒得说其他了

@Controller可以换成其他注解,@Service之类都行

实现接口换成org.springframework.context.ApplicationListener,其作用跟ServletContextListener类似,但一个是web容器的listener,一个是spring的listener

if(event instanceof ContextRefreshedEvent){

判断事件类型是 ContextRefreshedEvent, 然后再写你的调度逻辑

百度搜索 spring初始化成功 第一条大概或许能解决你的问题

http://blog.csdn.net/fatherican/article/details/9130165

maradona
maradona
回复 @ramer : 本地文件,那你就写死路径不就行了,除非你文件发布在系统中的, xxx.class.getResource("").getPath() 可以获取部署的目录 具体可以搜索 java web容器获取部署目录 http://www.2cto.com/kf/201212/176368.html
ramer
ramer
任务能执行了,问题是我的文件路径是通过servletContext得到的,这里没法得到ServletContext。实际发布的项目文件路径一般是怎么写的呢?我还是学生,烦您悉心指导。
0
南湖船老大
南湖船老大

不要闹。。。满满的槽点啊

contextInitialized 阶段,Spring的注解都还没生效呢,你去拿什么那些用注解注入的对象当然拿不到了。ServletContextListener 是在servlet容器初始化时监听。先有servlet后有spring,你这是都还没结婚呢,就想着抱孙子了。。

而且你这么写又是什么鬼

@Controller
public class ScheduleWork implements ServletContextListener {

再者,spring有自己的task实现,为嘛又要自己去实现

ramer
ramer
回复 @南湖船老大 : 我是学生,没接触这个,能用基础写当然最好了,框架后面看看也就懂了
南湖船老大
南湖船老大
回复 @ramer : 搜索 spring task 就出来了
ramer
ramer
开始注入不进去,我就像加个@Controller试试。。。。,spring自带的怎么实现呢,,我也是临时想到要做个定时器的以前没用过,还请指点一二
0
Happy猪猪
Happy猪猪

spring quart


返回顶部
顶部