「透明マント」や「透明シールド」はフィクションの世界で頻繁に登場します。
それらの実現を夢見て、これまでにも「透明シールドのようなもの」はいくつか開発されてきました。
しかし、それらはどれも技術的に完成度が低く、一時的に話題を集めただけだったようです。
そして最近、イギリスのスタートアップ企業「Invisiblity Shield Co」は、”透明シールドもどき”のイメージを払拭するような、完成度の高いステルスシールドを発表しました。
⇧ 透明と聞くと、
『お前もボディを透明にしてやろうか!(「冷たい熱帯魚[監督:園子温]」)』
という台詞を思い出してしまいますね。
俳優の演技力が凄まじいです。
冒頭から脱線しましたが、今回はJava関連です。レッツトライ~。
deprecatedにするって言ってたような...
なかなかカオスな感じなのですが、
Gradle 7.1 deprecated project layouts where subprojects were located outside of the project root. However, based on community feedback we decided to roll back in Gradle 7.4 and removed the deprecation. As a consequence, the Settings.includeFlat() method is deprecated in Gradle 7.1, 7.2, and 7.3 only.
https://docs.gradle.org/current/userguide/upgrading_version_7.html
⇧ コミュニティの声を反映して、deprecatedを撤回となってるのだけど、そもそもとして、何でdeprecatedにしようとしたのかがいまいち判然としないんですよね...
フラットな構造のMulti Projectは、application.propertiesで別プロジェクトのapplication.propertiesを読み込めない...
何て言うか、Spring Frameworkがイケてないのかが分からんのだけど、フラットな構造のMulti Projectだと、別プロジェクトのapplication.propertiesを読み込むことはできないっぽい...というか、一番需要がありそうなとこだと思うのだけど、何故かドキュメントでも触れられていないというね...
そもそもとして、
spring.config.name
および spring.config.location
は、どのファイルをロードする必要があるかを判断するために非常に早い段階で使用されるため、環境プロパティ(通常は OS 環境変数、システムプロパティ、またはコマンドライン引数)として定義する必要があります。
⇧ OS依存してしまってる時点で、Javaが謳ってる「Write once, run anywhere」とは相容れないと言った感じでしょうか。
Windowsでは、ドライブプレフィックスが絶対に付いている場合は、ファイルURLに追加の「/」が必要です(たとえばfile:///${user.home}/config-repo)。
https://docs.spring.io/spring-cloud-config/docs/3.0.0/reference/html/
⇧ う~ん、どうにもイケてない...
なんか、multi projectにするメリットって、共通で使いたいものを分けておくってことに尽きるとは思うんですが、それを読み込む方法が無いっていうのが残念過ぎるという...
結局2重管理になってしまうのが哀しい...
フラットな構造でmulti project作ってみた
というわけで、Eclipseで「Spring Boot」なプロジェクトを2つ作ります。
⇧「api」「dao」ってプロジェクトを作成。
まずは、「dao」のほうから。
利用するデータベースやデータベースのポート番号などデータベース接続情報は、ご自身の環境に合わせてください。
■/dao/settings.gradle
rootProject.name = 'dao'
■/dao/build.gradle
plugins { id 'org.springframework.boot' version '2.6.4' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.postgresql:postgresql' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
■/dao/src/main/resources/application.properties
spring.datasource.driver-class-name=org.postgresql.Driver #spring.datasource.url=jdbc:postgresql://localhost:5434/test?currentSchema=public spring.datasource.url=jdbc:postgresql://localhost:5434/test spring.jpa.properties.hibernate.default_schema=public spring.datasource.username=postgres spring.datasource.password=postgres
■/dao/src/main/java/com/example/demo/model/entity/User.java
package com.example.demo.model.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import lombok.Data; @Data @Entity @Table(name="user") public class User { @Id @Column(name="id") private Long id; @Column(name="name") private String name; }
■/dao/src/main/java/com/example/demo/repository/UserRepository.java
package com.example.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; import com.example.demo.model.entity.User; public interface UserRepository extends JpaRepository<User, Long>, CrudRepository<User, Long> { }
■/dao/src/main/java/com/example/demo/DaoApplication.java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DaoApplication { public static void main(String[] args) { SpringApplication.run(DaoApplication.class, args); } }
続きまして、「api」プロジェクトのほう。
■/api/settings.gradle
rootProject.name = 'api' includeFlat 'dao'
■/api/build.gradle
plugins { id 'org.springframework.boot' version '2.6.4' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' "implementation"(project(":dao")) } tasks.named('test') { useJUnitPlatform() }
■/api/src/main/resources/application.properties
server.port=8080 #spring.config.import=file:/dao/src/main/resources/application.properties #spring.config.additional-location=classpath:/dao/src/main/resources/application.properties spring.datasource.driver-class-name=org.postgresql.Driver #spring.datasource.url=jdbc:postgresql://localhost:5434/test?currentSchema=public spring.datasource.url=jdbc:postgresql://localhost:5434/test spring.jpa.properties.hibernate.default_schema=public spring.datasource.username=postgres spring.datasource.password=postgres
■/api/src/main/java/com/example/demo/service/user/UserService.java
package com.example.demo.service.user; import java.util.List; import com.example.demo.model.entity.User; public interface UserService { public List<User> findAllUser (); }
■/api/src/main/java/com/example/demo/service/user/UserServiceImpl.java
package com.example.demo.service.user; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.demo.model.entity.User; import com.example.demo.repository.UserRepository; @Service public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; @Override public List<User> findAllUser () { List<User> userList = this.userRepository.findAll(); return userList; } }
■/api/src/main/java/com/example/demo/controller/UserController.java
package com.example.demo.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.demo.model.entity.User; import com.example.demo.service.user.UserService; @RestController @RequestMapping(value="/user") public class UserController { @Autowired private UserService userService; @GetMapping public String hello() { return "Hello World"; } @GetMapping(value="/all") public List<user> getAllUser () { return this.userService.findAllUser(); } }
■/api/src/main/java/com/example/demo/ApiApplication.java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApiApplication { public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); } }
で保存。
テーブルは、PostgreSQLのpublicスキーマにtestって名前のデータベースを作って、userテーブルを作ってデータを入れておきます。
カラムが2つだけのシンプルな構成です。idが主キーです。
⇧アプリケーションサーバーのTomcatが起動したらば、ブラウザで「http://localhost:8080/user/all」にアクセス。
「daoプロジェクト」の処理を利用してデータベースから取得できました。
「daoプロジェクト」単体で動かすこともできるので、「daoプロジェクト」のほうで単体テストなど確認もできるかと。
毎度モヤモヤ感が半端ない...
今回はこのへんで。