@SpringBootApplicationがあるプロジェクトに依存するSpringBootApplicationの実行方法
Spring Bootアプリケーションには、普通、@SpringBootApplication
アノテーションのついたクラスが一つあると思う。
このプロジェクト(プロジェクトA)の機能を使う別のSpringBootApplication(プロジェクトB)を作りたいとする。
きれいなのは共通機能を別プロジェクトにする方法だと思うが、様々な要因からそうするしかなかった。
そうすると、プロジェクトBから見たとき、@SpringBootApplication
のついたクラスが二つになってしまう。
特にTomcat環境にデプロイする前提で開発しているとSpringBootServletInitializer
の使用が必須だが、
これが複数クラスで使われていると不具合が出るようだ。
自分の環境ではSpring Securityを使っていたが、permitAll
が効かずにすべてのページで認証が必要になったりした。
これを防ぐためには、プロジェクトBの@SpringBootApplication
を以下のように実装する。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication @ComponentScan(basePackages = { "my.projectA", "my.projectB" } , excludeFilters = { @Filter(type = FilterType.ASPECTJ, pattern = "my.projectA.controllers.*") }) @EnableJpaRepositories(basePackages={"my.jpa.repository"}) @EntityScan(basePackages={"my.jpa.entity"}) public class MyWebApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(MyWebApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(MyWebApplication.class); } }
JPAリポジトリを使用していない場合、@EnableJpaRepositories
、@EntityScan
の行は必要ない。
今回、プロジェクトAのエンドポイントが必要なかっため、excludeFilters
に@Filter(type = FilterType.ASPECTJ, pattern = "my.projectA.controllers.*")
を追加し、プロジェクトAのパスが生えないようにしている。
加えて、プロジェクトAにpom.xml
をコピーしたpom2.xml
を作成し、以下の修正をする。
<packaging>jar</packaging> ↓ <packaging>war</packaging>
以下の箇所を削除する。
... <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>...</mainClass> <layout>WAR</layout> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> ...
さらに以下を追加する。
... <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.3.1</version> <executions> <execution> <id>default-jar</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> <configuration> <excludes> <exclude>**/MyWebApplicationA.class</exclude> </excludes> </configuration> </execution> </executions> </plugin> ...
ここで、MyWebApplicationA
は@SpringBootApplication
アノテーション付きでSpringBootServletInitializer
を継承したクラス。
参考: medium.com