Java Spring Boot。 Cron问题。变量未实例化

时间:2017-07-24 14:27:33

标签: java spring cron scheduled-tasks

我的Spring Boot应用程序无法正常运行。主要思想是用户选择他想知道温度的城市。温度值保存到txt文件中,城市名称作为文件名。然后我想安排Cron,因此,同一个城市的每个小时新温度值将保存到同一个文件中。目前一切正常,除了CronManager类。我不明白如何将城市名称传递给它。以下是我的代码部分:

ApplicationLoader

package com.boris2barak.samplemvc.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication

public class ApplicationLoader extends SpringBootServletInitializer {


@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(ApplicationLoader.class);
}

public static void main(String[] args) throws Exception {
    SpringApplication.run(ApplicationLoader.class, args);
}
}

控制器

package com.boris2barak.samplemvc.app;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.IOException;

@Controller
public class myFirstController {

@RequestMapping("/hello")
public String hello(Model model, @RequestParam(value = "name", required = false, defaultValue = "World") String name) {
    model.addAttribute("name", name);
    return "hello";
}

@RequestMapping("/temperature")
public String whatIsTheTemperature(Model model, @RequestParam(value = "city", required = false, defaultValue = "World") String city) throws IOException {
    model.addAttribute("city", city);
    WeatherApp data = new WeatherApp();
    return data.getTemperatureForCity(city);
}
}

WeatherApp

package com.boris2barak.samplemvc.app;
import com.google.gson.Gson;
import org.springframework.web.client.RestTemplate;
import java.io.*;

public class WeatherApp {

public String getTemperatureForCity(String city) throws IOException {
    String URL = "http://api.openweathermap.org/data/2.5/weather?q="+city+"&APPID=9fff4e627587b84fca1ed835321da768";
    RestTemplate restTemplate = new RestTemplate();
    String json = restTemplate.getForObject(URL, String.class);
    WeatherData weatherData = new Gson().fromJson(json, WeatherData.class);

    ////......... (here i have the code to get the other data like coordinates of the city, humidity, etc which is not relevant to my problem)

    String theTemperature = weatherData.getTemperature();
    FileManager myFile = new FileManager();
    myFile.saveTheFile(theTemperature, city);
    return theTemperature;
}
}

文件管理

package com.boris2barak.samplemvc.app;
import org.apache.commons.io.IOUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static org.apache.commons.io.IOUtils.toInputStream;

public class FileManager {

public void saveTheFile(String theTemperature, String cityName) throws IOException {
    InputStream streamIn = toInputStream(theTemperature, "UTF-8");
    OutputStream streamOut = new FileOutputStream(cityName + ".txt", true);
    try {
        IOUtils.copy(streamIn, streamOut);
    } finally {
        IOUtils.closeQuietly(streamIn);
        IOUtils.closeQuietly(streamOut);
    }

}
}

CronManager

package com.boris2barak.samplemvc.app;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.IOException;

@Component
public class CronManager {

@Scheduled(cron = "0 * * ? * *")
public void cronTask() throws IOException {

WeatherApp data = new WeatherApp();
data.getTemperatureForCity(city <<<< how to instantiate this??);


}
}

我已经有2天时间试图解决这个问题了。非常感谢你的帮助!

问题解决了。这是答案: https://stackoverflow.com/a/45287683/8258820

1 个答案:

答案 0 :(得分:0)

@Component
public class CronManager {
private Set<String> cities = new HashSet();// or CopyOnWriteArraySet/ConcurrentSkipListSet

public void addCity(String cityName){
     cities.add(cityName);
}

@Scheduled(cron = "0 * * ? * *")
public void cronTask() throws IOException {

        //iterate cities and execute logic in parallel no not block 
        WeatherApp data = new WeatherApp();
        data.getTemperatureForCity(city <<<< how to instantiate this??);
}
}

将CronManager作为一个组件注入服务/控制器,并在添加新城市时将新城市添加到CronManager.cities中。如果你需要停止写城市温度,只需将其从城市集中删除即可。更好地创建一个新的组件CityHolder并将城市合二为一,在这种情况下,您需要将其注入cronManager和服务/控制器,但服务/控制器将不依赖于cron管理器。 由于所有文件都有一个cron,因此最好通过某些线程执行程序或@Async服务/方法并行执行此代码。

您也可以使用春季活动。在conroller / service中使用发送自定义事件AddNewCity并在CronManager中为此事件添加侦听器,并将城市从事件源放入城市集。

@Controller
public class myFirstController {
    @Autowired
    private CronManager cron;

    @RequestMapping("/temperature")
    public String whatIsTheTemperature(Model model, 
       @RequestParam(value = "city",required = false,defaultValue = "World") String city) 
          throws IOException {
        model.addAttribute("city", city);
        WeatherApp data = new WeatherApp();
        myCron.addCity(city);
        return data.getTemperatureForCity(city);
    }
}