如何在没有控制器的情况下运行@SpringBootApplication

时间:2019-01-22 19:32:29

标签: java spring spring-boot

如何使用@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());
    }
}

3 个答案:

答案 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并删除构造函数注入,那么一切应该正常。

很高兴您发现天气应用程序很有帮助:)