Spring Bootでアプリケーション起動時にタイムゾーンを設定する

SpringApplicationEventを使用することで実現可能。
Spring Bootがデフォルトで用意しているイベントには以下がある。

イベントクラス名 説明
ApplicationFailedEvent SpringApplicationの開始に失敗したときにSpringApplicationによって発行されるイベント。
ApplicationStartingEvent SpringApplicationが開始され、ApplicationListenerが登録された後(EnvironmentやApplicationContextが使用可能になる前に)できるだけ早くイベントが公開される。
ApplicationContextInitializedEvent SpringApplicationが始動し、ApplicationContextが準備され、ApplicationContextInitializersが呼び出されたが、Bean定義がロードされる前に発行されるイベント。
ApplicationEnvironmentPreparedEvent SpringApplicationが起動し、Environmentがインスペクションおよび変更に最初に利用可能になったときに公開されるイベント。
ApplicationPreparedEvent SpringApplicationが起動し、ApplicationContextが完全に準備されているがリフレッシュされていない場合に発行されるイベント。
Bean定義がロードされ、Environmentがこの段階で使用できるようになる。
ApplicationReadyEvent アプリケーションがリクエストを処理する準備ができていることを示すために、可能な限り遅く発行されたイベント。
ApplicationStartedEvent ApplicationContextがリフレッシュされた後、applicationおよびcommand lineランナーが呼び出される前に発行されたイベント。

イベントリスナーの設定方法

ApplicationListenerを実装する

タイムゾーンの設定がWebアプリ起動時から変更されたのは上記のイベントのうち、ApplicationStartingEventのみであった。
その他は再起動することで反映されるものもあるが。。。といった感じ。

package jp.co.sample.webapp.listener;

import java.util.TimeZone;

import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * アプリケーション起動時にタイムゾーンを設定するイベントリスナー。<br>
 */
@Component
public class WebApplicationListener implements ApplicationListener<ApplicationStartingEvent> {
    /**
     * {@inheritDoc}
     */
    @Override
    public void onApplicationEvent(ApplicationStartingEvent event) {
        TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
        System.setProperty("user.timezone", "Etc/UTC");
    }
}

実装したListenerはWebアプリケーションを起動する際に追加する必要がある。

package jp.co.sample.webapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Webアプリケーションを起動するクラス。<br>
 */
@SpringBootApplication
public class WebappApplication {

    /**
     * Webアプリケーションを起動する。<br>
     * 
     * @param args
     *            起動時引数
     */
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(WebappApplication.class);
        application.addListeners(new WebApplicationListener());
        application.run(args);
    }
}

アノテーションを使用する

ApplicationReadyEventとApplicationStartedEventはアノテーションでも設定可能。

package jp.co.template.webapp.listener;

import java.util.TimeZone;

import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * アプリケーション起動時にタイムゾーンを設定するイベントリスナー。<br>
 */
@Component
public class WebApplicationListener {

    /**
     * 
     */
    @EventListener(ApplicationReadyEvent.class)
    public void loadData() {
        TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
        System.setProperty("user.timezone", "Etc/UTC");
    }
}