如何使用@SpringBootApplication批注从类中运行代码。我想运行代码而不调用控制器,并从终端而不是Web浏览器获取信息。我尝试在@SpringBootApplication中调用weatherService,但是我的应用程序以描述开头失败
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| weatherClientApplication
↑ ↓
| weatherService defined in file [C:\Users\xxx\IdeaProjects\weatherclient\target\classes\com\xxx\restapiclient\service\WeatherService.class]
└─────┘
@SpringBootApplication
public class WeatherClientApplication {
private WeatherService weatherService;
public WeatherClientApplication(WeatherService weatherService) {
this.weatherService = weatherService;
}
private static final Logger log = LoggerFactory.getLogger(WeatherClientApplication.class);
public static void main(String[] args) {
SpringApplication.run(WeatherClientApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
log.info(weatherService.getTemperatureByCityName("Krakow"));
};
}
}
@Service
public class WeatherService {
private RestTemplate restTemplate;
public WeatherService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public String getTemperatureByCityName(String cityName) {
String url = "http://api.openweathermap.org/data/2.5/weather?q=" + cityName + "&APPID=" + API_KEY + "&units=metric";
Quote quote = restTemplate.getForObject(url, Quote.class);
return String.valueOf(quote.getMain().getTemp());
}
}
答案 0 :(得分:1)
您可以使用main方法和ApplicationContext
来完成此操作,在这种方法中,您不需要任何CommandLineRunner
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(WeatherClientApplication.class, args);
WeatherService service = (WeatherService)context.getBean("weatherService");
service. getTemperatureByCityName("cityname");
}
答案 1 :(得分:1)
1)您想要实现CommandLineRunner
,并使用此接口中定义的public void run(String... args)
方法定义应用程序的入口点。
2)正如Spring所说的,您有一个循环:在构造函数外部注入使其中断。
例如:
@SpringBootApplication
public class WeatherClientApplication implements CommandLineRunner{
@Autowired
private WeatherService weatherService;
//...
@Override
public void run(String... args) {
log.info(weatherService.getTemperatureByCityName("Krakow"));
}
//...
}
通常应该优先使用构造函数注入而不是字段注入或二传手注入,但是在您的情况下,这是可以接受的。
答案 2 :(得分:1)
您正在向@SpringBootApplication
本身注入服务时创建周期。构造函数注入意味着在构建类之前不会真正发生任何事情,但是稍后会创建该服务。
请勿在您的@SpringBootApplication
上使用字段注入,因为它表示根上下文。您的CommandLineRunner
注入了RestTemplate
,但您没有使用它。如果将其替换为WeatherService
并删除构造函数注入,那么一切应该正常。
很高兴您发现天气应用程序很有帮助:)