89. 従来のデプロイ

Spring Boot は、従来のデプロイだけでなく、より新しい形式のデプロイもサポートします。このセクションでは、従来のデプロイに関する一般的な質問に回答します。

89.1 デプロイ可能な War ファイルを作成する

[Warning] 警告

Spring WebFlux はサーブレット API に厳密に依存せず、アプリケーションはデフォルトで組み込み Reactor Netty サーバーにデプロイされるため、War デプロイは WebFlux アプリケーションではサポートされていません。

デプロイ可能な war ファイルを作成する最初のステップは、SpringBootServletInitializer サブクラスを提供し、その configure メソッドをオーバーライドすることです。これにより、Spring Framework の Servlet 3.0 サポートが利用され、サーブレットコンテナーによって起動されたときにアプリケーションを設定できます。通常、次の例に示すように、SpringBootServletInitializer を継承するには、アプリケーションのメインクラスを更新する必要があります。

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

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

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

}

次のステップは、プロジェクトが jar ファイルではなく war ファイルを生成するようにビルド構成を更新することです。Maven および spring-boot-starter-parent (Maven の war プラグインを構成する)を使用している場合は、次のように、pom.xml を変更してパッケージを war に変更するだけです。

<packaging>war</packaging>

Gradle を使用する場合は、build.gradle を変更して、war プラグインをプロジェクトに次のように適用する必要があります。

apply plugin: 'war'

プロセスの最後のステップは、組み込みサーブレットコンテナーが war ファイルのデプロイ先のサーブレットコンテナーと干渉しないようにすることです。そのためには、埋め込まれたサーブレットコンテナーの依存関係を提供済みとしてマークする必要があります。

Maven を使用する場合、次の例では、サーブレットコンテナー(この場合は Tomcat)が提供されているとマークします。

<dependencies>
	<!-- … -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-tomcat</artifactId>
		<scope>provided</scope>
	</dependency>
	<!-- … -->
</dependencies>

Gradle を使用する場合、次の例では、サーブレットコンテナー(この場合は Tomcat)が提供されているとマークします。

dependencies {
	// …
	providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
	// …
}
[Tip] ヒント

providedRuntime は、Gradle の compileOnly 構成よりも優先されます。他の制限の中でも、compileOnly 依存関係はテストクラスパスにないため、Web ベースの統合テストはすべて失敗します。

Spring Boot ビルドツールを使用する場合、組み込みサーブレットコンテナーの依存関係を提供済みとしてマークすると、提供された依存関係が lib-provided ディレクトリにパッケージ化された実行可能な war ファイルが生成されます。つまり、サーブレットコンテナーにデプロイできることに加えて、コマンドラインで java -jar を使用してアプリケーションを実行することもできます。

[Tip] ヒント

前述の構成の Maven ベースの例 (GitHub) の Spring Boot のサンプルアプリケーションを参照してください。

89.2 既存のアプリケーションを Spring Boot に変換する

非 Web アプリケーションの場合、既存の Spring アプリケーションを Spring Boot アプリケーションに簡単に変換できるはずです。そのためには、ApplicationContext を作成するコードを破棄し、SpringApplication または SpringApplicationBuilder の呼び出しに置き換えます。Spring MVC Web アプリケーションは、通常、最初にデプロイ可能な war アプリケーションを作成し、それを後で実行可能な war または jar に移行するのに適しています。jar から war への変換に関する入門ガイドを参照してください。

SpringBootServletInitializer を継承して(たとえば Application というクラスに)、Spring Boot @SpringBootApplication アノテーションを追加してデプロイ可能な war を作成するには、次の例に示すようなコードを使用します。

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		// Customize the application or call application.sources(...) to add sources
		// Since our example is itself a @Configuration class (via @SpringBootApplication)
		// we actually don't need to override this method.
		return application;
	}

}

sources に入れるものはすべて Spring ApplicationContext に過ぎないことを忘れないでください。通常、すでに動作しているものはすべてここで動作するはずです。後で削除できる Bean があり、Spring Boot に独自のデフォルトを提供させることもありますが、それを行う前に何かを機能させることができるはずです。

静的リソースは、クラスパスルートの /public (または /static または /resources または /META-INF/resources)に移動できます。同じことが messages.properties (Spring Boot がクラスパスのルートで自動的に検出します)にも当てはまります。

Spring DispatcherServlet および Spring Security のバニラ使用には、それ以上の変更は必要ありません。アプリケーションに他の機能がある場合(たとえば、他のサーブレットやフィルターを使用する場合)、web.xml の要素を次のように置き換えることにより、Application コンテキストに設定を追加する必要がある場合があります。

  • タイプ Servlet または ServletRegistrationBean の @Bean は、あたかも web.xml の <servlet/> および <servlet-mapping/> であるかのように、その Bean をコンテナーにインストールします。
  • タイプ Filter または FilterRegistrationBean の @Bean は、同様に動作します(<filter/> および <filter-mapping/> として)。
  • XML ファイルの ApplicationContext は、Application の @ImportResource を介して追加できます。あるいは、アノテーション構成がすでに頻繁に使用されている単純なケースは、数行で @Bean 定義として再作成できます。

war ファイルが機能したら、次の例に示すように、main メソッドを Application に追加して実行可能にすることができます。

public static void main(String[] args) {
	SpringApplication.run(Application.class, args);
}
[Note] メモ

アプリケーションを war または実行可能アプリケーションとして開始する場合は、SpringBootServletInitializer コールバックと次のようなクラスの main メソッドの両方で使用可能なメソッドでビルダーのカスタマイズを共有する必要があります。

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
		return configureApplication(builder);
	}

	public static void main(String[] args) {
		configureApplication(new SpringApplicationBuilder()).run(args);
	}

	private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
		return builder.sources(Application.class).bannerMode(Banner.Mode.OFF);
	}

}

アプリケーションは複数のカテゴリに分類できます。

  • web.xml のない Servlet 3.0+ アプリケーション。
  • web.xml を使用したアプリケーション。
  • コンテキスト階層を持つアプリケーション。
  • コンテキスト階層のないアプリケーション。

これらはすべて翻訳に適しているはずですが、それぞれがわずかに異なる技術を必要とする場合があります。

Servlet 3.0+ アプリケーションは、すでに Spring Servlet 3.0+ 初期化子サポートクラスを使用している場合、非常に簡単に変換できます。通常、既存の WebApplicationInitializer からのすべてのコードは SpringBootServletInitializer に移動できます。既存のアプリケーションに複数の ApplicationContext がある場合(たとえば、AbstractDispatcherServletInitializer を使用する場合)、すべてのコンテキストソースを単一の SpringApplication に結合できる場合があります。発生する可能性のある主な問題は、結合が機能せず、コンテキスト階層を維持する必要がある場合です。例については、階層の構築に関するエントリを参照してください。通常、Web 固有の機能を含む既存の親コンテキストは、すべての ServletContextAware コンポーネントが子コンテキストに含まれるように分割する必要があります。

まだ Spring アプリケーションではないアプリケーションは、Spring Boot アプリケーションに変換できる場合があり、前述のガイダンスが役立つ場合があります。ただし、まだ問題が発生する場合があります。その場合、spring-boot のタグを使用して Stack Overflow で質問する (英語) ことをお勧めします。

89.3 WebLogic への WAR のデプロイ

Spring Boot アプリケーションを WebLogic にデプロイするには、サーブレット初期化子が WebApplicationInitializer を直接実装していることを確認する必要があります(すでに実装している基本クラスから拡張する場合でも)。

WebLogic の一般的な初期化子は、次の例のようになります。

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.WebApplicationInitializer;

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {

}

Logback を使用する場合は、WebLogic に、サーバーにプリインストールされているバージョンではなく、パッケージ化されたバージョンを優先するように指示する必要もあります。これを行うには、次の内容の WEB-INF/weblogic.xml ファイルを追加します。

<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app
	xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		https://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
		http://xmlns.oracle.com/weblogic/weblogic-web-app
		https://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
	<wls:container-descriptor>
		<wls:prefer-application-packages>
			<wls:package-name>org.slf4j</wls:package-name>
		</wls:prefer-application-packages>
	</wls:container-descriptor>
</wls:weblogic-web-app>

89.4 Lettuce の代わりに Jedis を使用する

デフォルトでは、Spring Boot スターター(spring-boot-starter-data-redis)は Lettuce (GitHub) を使用します。その依存関係を除外し、代わりに Jedis (GitHub) を含める必要があります。Spring Boot はこれらの依存関係を管理して、このプロセスを可能な限り簡単にします。

次の例は、Maven でこれを行う方法を示しています。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<exclusions>
		<exclusion>
			<groupId>io.lettuce</groupId>
			<artifactId>lettuce-core</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
</dependency>

次の例は、Gradle でこれを行う方法を示しています。

configurations {
	compile.exclude module: "lettuce"
}

dependencies {
	compile("redis.clients:jedis")
	// ...
}