Browse Source

Cleanup and upgrade of the Spring implementations to Spring Boot 3.3 (#9167)

* Upgrade spring test to Spring Boot 3.3.1

This commit also introduces several refinements:
- Upgrade to Java 21 with Liberica JRE
- Make Message a top level class
- Properly exclude autoconfigurations based on profiles
- Use Spring Boot 3.3 executable JAR unpack feature
- Remove java options enabled by default
- Keep debug symbol in JVM bytecode for parameter name resolution

* Upgrade spring-webflux test to Spring Boot 3.3.1

This commit also introduces several refinements
- Reactivate the test
- Remove unmaintained variants to keep only r2dbc and mongo
- Upgrade to Spring Boot 3.3.1
- Upgrade to Java 21 with Liberica JRE
- Dependency cleanup
- Various related updates
- Add JSON and textplain endpoints
- Properly exclude autoconfigurations based on profiles
- Use Spring Boot 3.3 executable JAR unpack feature
- Add -Dreactor.netty.http.server.lastFlushWhenNoRead=true property
- Keep debug symbol in JVM bytecode for parameter name resolution
Sébastien Deleuze 1 year ago
parent
commit
dbaaefa53c
34 changed files with 148 additions and 814 deletions
  1. 0 9
      frameworks/Java/spring-webflux/README.md
  2. 4 63
      frameworks/Java/spring-webflux/benchmark_config.json
  3. 0 45
      frameworks/Java/spring-webflux/config.toml
  4. 9 41
      frameworks/Java/spring-webflux/pom.xml
  5. 0 13
      frameworks/Java/spring-webflux/spring-webflux-jdbc.dockerfile
  6. 6 3
      frameworks/Java/spring-webflux/spring-webflux-mongo.dockerfile
  7. 0 13
      frameworks/Java/spring-webflux/spring-webflux-pgclient.dockerfile
  8. 0 13
      frameworks/Java/spring-webflux/spring-webflux-rxjdbc.dockerfile
  9. 5 3
      frameworks/Java/spring-webflux/spring-webflux.dockerfile
  10. 1 38
      frameworks/Java/spring-webflux/src/main/java/benchmark/App.java
  11. 0 19
      frameworks/Java/spring-webflux/src/main/java/benchmark/DateHandler.java
  12. 0 19
      frameworks/Java/spring-webflux/src/main/java/benchmark/PgClients.java
  13. 18 3
      frameworks/Java/spring-webflux/src/main/java/benchmark/ServerFilter.java
  14. 0 22
      frameworks/Java/spring-webflux/src/main/java/benchmark/config/JdbcConfig.java
  15. 0 94
      frameworks/Java/spring-webflux/src/main/java/benchmark/config/PgClientConfig.java
  16. 0 63
      frameworks/Java/spring-webflux/src/main/java/benchmark/config/R2dbcConfig.java
  17. 0 54
      frameworks/Java/spring-webflux/src/main/java/benchmark/config/ReactiveMongoConfig.java
  18. 0 25
      frameworks/Java/spring-webflux/src/main/java/benchmark/config/RxJdbcConfig.java
  19. 15 0
      frameworks/Java/spring-webflux/src/main/java/benchmark/model/Message.java
  20. 8 9
      frameworks/Java/spring-webflux/src/main/java/benchmark/repository/MongoDbRepository.java
  21. 0 79
      frameworks/Java/spring-webflux/src/main/java/benchmark/repository/PgClientDbRepository.java
  22. 2 2
      frameworks/Java/spring-webflux/src/main/java/benchmark/repository/R2dbcDbRepository.java
  23. 0 60
      frameworks/Java/spring-webflux/src/main/java/benchmark/repository/RxJdbcDbRepository.java
  24. 13 10
      frameworks/Java/spring-webflux/src/main/java/benchmark/web/WebfluxHandler.java
  25. 9 23
      frameworks/Java/spring-webflux/src/main/java/benchmark/web/WebfluxRouter.java
  26. 10 53
      frameworks/Java/spring-webflux/src/main/resources/application.yml
  27. 2 5
      frameworks/Java/spring/pom.xml
  28. 5 5
      frameworks/Java/spring/spring-jpa.dockerfile
  29. 5 5
      frameworks/Java/spring/spring-mongo.dockerfile
  30. 5 5
      frameworks/Java/spring/spring.dockerfile
  31. 1 1
      frameworks/Java/spring/src/main/java/hello/App.java
  32. 2 13
      frameworks/Java/spring/src/main/java/hello/controller/HelloController.java
  33. 15 0
      frameworks/Java/spring/src/main/java/hello/model/Message.java
  34. 13 4
      frameworks/Java/spring/src/main/resources/application.yml

+ 0 - 9
frameworks/Java/spring-webflux/README.md

@@ -37,15 +37,6 @@ For mongoDB access, spring-data-mongodb with reactive support is used. See [Mong
 
 * [Template rendering test source](src/main/java/benchmark/web/WebfluxRouter.java)
 
-## Versions
-
-* [Java OpenJDK 10](http://openjdk.java.net/)
-* [Spring boot 2.1.0.RELEASE](https://spring.io/projects/spring-boot)
-* [Spring data mongodb 2.1.0.RELEASE](https://projects.spring.io/spring-data-mongodb/)
-* [reactive-pg-client 0.10.6](https://github.com/reactiverse/reactive-pg-client)
-* [rxjava2-jdbc 0.2.0](https://github.com/davidmoten/rxjava2-jdbc)
-* [r2dbc-postgresql 1.0.0.BUILD-SNAPSHOT](https://github.com/r2dbc/r2dbc-postgresql)
-
 ## Test URLs
 
 ### Plaintext Test

+ 4 - 63
frameworks/Java/spring-webflux/benchmark_config.json

@@ -2,9 +2,11 @@
   "framework": "spring-webflux",
   "tests": [{
     "default": {
+      "json_url": "/json",
       "db_url": "/db",
       "query_url": "/queries?queries=",
       "fortune_url": "/fortunes",
+      "plaintext_url": "/plaintext",
       "update_url": "/updates?queries=",
       "port": 8080,
       "approach": "Realistic",
@@ -23,9 +25,11 @@
       "versus": "spring"
     },
     "mongo": {
+      "json_url": "/json",
       "db_url": "/db",
       "query_url": "/queries?queries=",
       "fortune_url": "/fortunes",
+      "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Fullstack",
@@ -41,69 +45,6 @@
       "display_name": "spring-webflux-mongo",
       "notes": "",
       "versus": "spring"
-    },
-    "pgclient": {
-      "db_url": "/db",
-      "query_url": "/queries?queries=",
-      "fortune_url": "/fortunes",
-      "update_url": "/updates?queries=",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "Postgres",
-      "framework": "spring",
-      "language": "Java",
-      "flavor": "None",
-      "orm": "Micro",
-      "platform": "Netty",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "spring-webflux-pgclient",
-      "notes": "",
-      "versus": "spring"
-    },
-    "rxjdbc": {
-      "db_url": "/db",
-      "query_url": "/queries?queries=",
-      "fortune_url": "/fortunes",
-      "update_url": "/updates?queries=",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "Postgres",
-      "framework": "spring",
-      "language": "Java",
-      "flavor": "None",
-      "orm": "Micro",
-      "platform": "Netty",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "spring-webflux-rxjdbc",
-      "notes": "",
-      "versus": "spring"
-    },
-    "jdbc": {
-      "db_url": "/db",
-      "query_url": "/queries?queries=",
-      "fortune_url": "/fortunes",
-      "update_url": "/updates?queries=",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "Postgres",
-      "framework": "spring",
-      "language": "Java",
-      "flavor": "None",
-      "orm": "Micro",
-      "platform": "Netty",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "spring-webflux-jdbc",
-      "notes": "",
-      "versus": "spring"
     }
   }]
 }

+ 0 - 45
frameworks/Java/spring-webflux/config.toml

@@ -16,36 +16,6 @@ platform = "Netty"
 webserver = "None"
 versus = "spring"
 
-[pgclient]
-urls.db = "/db"
-urls.query = "/queries?queries="
-urls.update = "/updates?queries="
-urls.fortune = "/fortunes"
-approach = "Realistic"
-classification = "Fullstack"
-database = "Postgres"
-database_os = "Linux"
-os = "Linux"
-orm = "Micro"
-platform = "Netty"
-webserver = "None"
-versus = "spring"
-
-[jdbc]
-urls.db = "/db"
-urls.query = "/queries?queries="
-urls.update = "/updates?queries="
-urls.fortune = "/fortunes"
-approach = "Realistic"
-classification = "Fullstack"
-database = "Postgres"
-database_os = "Linux"
-os = "Linux"
-orm = "Micro"
-platform = "Netty"
-webserver = "None"
-versus = "spring"
-
 [mongo]
 urls.db = "/db"
 urls.query = "/queries?queries="
@@ -59,18 +29,3 @@ orm = "Full"
 platform = "Netty"
 webserver = "None"
 versus = "spring"
-
-[rxjdbc]
-urls.db = "/db"
-urls.query = "/queries?queries="
-urls.update = "/updates?queries="
-urls.fortune = "/fortunes"
-approach = "Realistic"
-classification = "Fullstack"
-database = "Postgres"
-database_os = "Linux"
-os = "Linux"
-orm = "Micro"
-platform = "Netty"
-webserver = "None"
-versus = "spring"

+ 9 - 41
frameworks/Java/spring-webflux/pom.xml

@@ -8,19 +8,18 @@
 
     <groupId>benchmark</groupId>
     <artifactId>spring-webflux-benchmark</artifactId>
-    <version>1.1-SNAPSHOT</version>
+    <version>1.0-SNAPSHOT</version>
 
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>3.3.0</version>
+        <version>3.3.1</version>
     </parent>
 
     <properties>
-        <java.version>17</java.version>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <pgclient.version>0.11.4</pgclient.version>
-        <rxjava2-jdbc.version>0.2.14</rxjava2-jdbc.version>
     </properties>
 
     <dependencies>
@@ -30,7 +29,11 @@
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-jdbc</artifactId>
+            <artifactId>spring-boot-starter-data-r2dbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>r2dbc-postgresql</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -40,38 +43,6 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.reactiverse</groupId>
-            <artifactId>reactive-pg-client</artifactId>
-            <version>${pgclient.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.github.davidmoten</groupId>
-            <artifactId>rxjava2-jdbc</artifactId>
-            <version>${rxjava2-jdbc.version}</version>
-        </dependency>
-
-		<dependency>
-		    <groupId>org.postgresql</groupId>
-		    <artifactId>r2dbc-postgresql</artifactId>
-		</dependency>
-        <dependency>
-            <groupId>io.r2dbc</groupId>
-            <artifactId>r2dbc-pool</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.data</groupId>
-            <artifactId>spring-data-r2dbc</artifactId>
-        </dependency>
-        <dependency>
-        	<groupId>org.springframework.boot</groupId>
-        	<artifactId>spring-boot-configuration-processor</artifactId>
-        	<optional>true</optional>
-        </dependency>
     </dependencies>
 
     <build>
@@ -84,9 +55,6 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <debug>false</debug>
-                </configuration>
             </plugin>
         </plugins>
     </build>

+ 0 - 13
frameworks/Java/spring-webflux/spring-webflux-jdbc.dockerfile

@@ -1,13 +0,0 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
-WORKDIR /spring
-COPY src src
-COPY pom.xml pom.xml
-RUN mvn package -q
-
-FROM eclipse-temurin:21.0.3_9-jre-jammy
-WORKDIR /spring
-COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
-
-EXPOSE 8080
-
-CMD ["java", "-server", "-XX:+UseNUMA", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=jdbc,postgres"]

+ 6 - 3
frameworks/Java/spring-webflux/spring-webflux-mongo.dockerfile

@@ -1,13 +1,16 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
+FROM maven:3.9.5-eclipse-temurin-21 as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM eclipse-temurin:21.0.3_9-jre-jammy
+FROM bellsoft/liberica-openjre-debian:21
 WORKDIR /spring
 COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
+# See https://docs.spring.io/spring-boot/reference/packaging/efficient.html
+RUN java -Djarmode=tools -jar app.jar extract
+
 
 EXPOSE 8080
 
-CMD ["java", "-server", "-XX:+UseNUMA", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=mongo"]
+CMD ["java", "-Dlogging.level.root=OFF", "-Dreactor.netty.http.server.lastFlushWhenNoRead=true", "-jar", "app/app.jar", "--spring.profiles.active=mongo"]

+ 0 - 13
frameworks/Java/spring-webflux/spring-webflux-pgclient.dockerfile

@@ -1,13 +0,0 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
-WORKDIR /spring
-COPY src src
-COPY pom.xml pom.xml
-RUN mvn package -q
-
-FROM eclipse-temurin:21.0.3_9-jre-jammy
-WORKDIR /spring
-COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
-
-EXPOSE 8080
-
-CMD ["java", "-server", "-XX:+UseNUMA", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=pgclient,postgres"]

+ 0 - 13
frameworks/Java/spring-webflux/spring-webflux-rxjdbc.dockerfile

@@ -1,13 +0,0 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
-WORKDIR /spring
-COPY src src
-COPY pom.xml pom.xml
-RUN mvn package -q
-
-FROM eclipse-temurin:21.0.3_9-jre-jammy
-WORKDIR /spring
-COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
-
-EXPOSE 8080
-
-CMD ["java", "-server", "-XX:+UseNUMA", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=rxjdbc,postgres"]

+ 5 - 3
frameworks/Java/spring-webflux/spring-webflux.dockerfile

@@ -1,13 +1,15 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
+FROM maven:3.9.5-eclipse-temurin-21 as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM eclipse-temurin:21.0.3_9-jre-jammy
+FROM bellsoft/liberica-openjre-debian:21
 WORKDIR /spring
 COPY --from=maven /spring/target/spring-webflux-benchmark.jar app.jar
+# See https://docs.spring.io/spring-boot/reference/packaging/efficient.html
+RUN java -Djarmode=tools -jar app.jar extract
 
 EXPOSE 8080
 
-CMD ["java", "-server", "-XX:+UseNUMA", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=r2dbc,postgres"]
+CMD ["java", "-Dlogging.level.root=OFF", "-Dreactor.netty.http.server.lastFlushWhenNoRead=true", "-jar", "app/app.jar", "--spring.profiles.active=r2dbc"]

+ 1 - 38
frameworks/Java/spring-webflux/src/main/java/benchmark/App.java

@@ -1,52 +1,15 @@
 package benchmark;
 
-import java.util.concurrent.Executors;
-
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.web.reactive.result.view.MustacheViewResolver;
-import org.springframework.context.annotation.Bean;
 import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.web.reactive.config.EnableWebFlux;
-import org.springframework.web.reactive.config.ViewResolverRegistry;
-import org.springframework.web.reactive.config.WebFluxConfigurer;
-
-import reactor.core.scheduler.Scheduler;
-import reactor.core.scheduler.Schedulers;
 
 @SpringBootApplication
-@EnableWebFlux
 @EnableScheduling
-@EnableConfigurationProperties
-public class App implements WebFluxConfigurer {
-
-    @Autowired
-    private MustacheViewResolver mustacheViewResolver;
+public class App  {
 
     public static void main(String[] args) {
         SpringApplication.run(App.class, args);
     }
 
-    @Bean
-    ServerFilter serverFilter() {
-        return new ServerFilter();
-    }
-
-    @Bean
-    DateHandler dateHandler() {
-        return new DateHandler();
-    }
-
-    @Bean
-    Scheduler ioScheduler() {
-        return Schedulers.fromExecutor(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2));
-    }
-
-    @Override
-    public void configureViewResolvers(ViewResolverRegistry registry) {
-        registry.viewResolver(mustacheViewResolver);
-    }
-
 }

+ 0 - 19
frameworks/Java/spring-webflux/src/main/java/benchmark/DateHandler.java

@@ -1,19 +0,0 @@
-package benchmark;
-
-import org.springframework.scheduling.annotation.Scheduled;
-
-import java.util.Date;
-
-public class DateHandler {
-
-    private Date date = new Date();
-
-    @Scheduled(fixedRate = 1000)
-    public void update() {
-        this.date = new Date();
-    }
-
-    public Date getDate() {
-        return date;
-    }
-}

+ 0 - 19
frameworks/Java/spring-webflux/src/main/java/benchmark/PgClients.java

@@ -1,19 +0,0 @@
-package benchmark;
-
-import io.reactiverse.pgclient.PgClient;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.stream.Stream;
-
-public class PgClients {
-    private final Iterator<PgClient> iterator;
-
-    public PgClients(Collection<PgClient> clients) {
-        iterator = Stream.generate(() -> clients).flatMap(Collection::stream).iterator();
-    }
-
-    public synchronized PgClient getOne() {
-        return iterator.next();
-    }
-}

+ 18 - 3
frameworks/Java/spring-webflux/src/main/java/benchmark/ServerFilter.java

@@ -1,20 +1,35 @@
-package benchmark;
+package benchmark.web;
 
 import io.netty.handler.codec.http.HttpHeaderNames;
 import org.springframework.http.HttpHeaders;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
 import org.springframework.web.server.ServerWebExchange;
 import org.springframework.web.server.WebFilter;
 import org.springframework.web.server.WebFilterChain;
 import reactor.core.publisher.Mono;
 
+@Component
 public class ServerFilter implements WebFilter {
+
     private static final String SERVER_NAME = "spring-webflux";
 
+    private String date;
+
+    public ServerFilter() {
+        updateDate();
+    }
+
+    @Scheduled(fixedRate = 1000)
+    public void updateDate() {
+        this.date = java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME.format(java.time.ZonedDateTime.now());
+    }
+
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
         HttpHeaders headers = exchange.getResponse().getHeaders();
         headers.add(HttpHeaderNames.SERVER.toString(), SERVER_NAME);
-        headers.add(HttpHeaderNames.DATE.toString(), java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME.format(java.time.ZonedDateTime.now()));
+        headers.add(HttpHeaderNames.DATE.toString(), this.date);
         return chain.filter(exchange);
     }
-}
+}

+ 0 - 22
frameworks/Java/spring-webflux/src/main/java/benchmark/config/JdbcConfig.java

@@ -1,22 +0,0 @@
-package benchmark.config;
-
-import com.zaxxer.hikari.HikariDataSource;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-
-import javax.sql.DataSource;
-
-@Configuration
-@Profile("jdbc")
-public class JdbcConfig {
-
-    @Bean
-    DataSource datasource(DataSourceProperties dataSourceProperties) {
-        HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
-        dataSource.setMaximumPoolSize(Runtime.getRuntime().availableProcessors() * 2);
-
-        return dataSource;
-    }
-}

+ 0 - 94
frameworks/Java/spring-webflux/src/main/java/benchmark/config/PgClientConfig.java

@@ -1,94 +0,0 @@
-package benchmark.config;
-
-import benchmark.PgClients;
-import io.reactiverse.pgclient.PgClient;
-import io.reactiverse.pgclient.PgPool;
-import io.reactiverse.pgclient.PgPoolOptions;
-import io.vertx.core.Vertx;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Configuration
-@Profile("pgclient")
-@ConfigurationProperties(prefix = "database")
-public class PgClientConfig {
-    private String name;
-    private String host;
-    private int port;
-    private String username;
-    private String password;
-
-    @Bean
-    Vertx vertx() {
-        return Vertx.vertx();
-    }
-
-    @Bean
-    PgClients pgClients(Vertx vertx) {
-        List<PgClient> clients = new ArrayList<>();
-
-        for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
-            clients.add(pgClient(vertx));
-        }
-
-        return new PgClients(clients);
-    }
-
-
-    public PgPool pgClient(Vertx vertx) {
-        PgPoolOptions options = new PgPoolOptions();
-        options.setDatabase(name);
-        options.setHost(host);
-        options.setPort(port);
-        options.setUser(username);
-        options.setPassword(password);
-        options.setCachePreparedStatements(true);
-        options.setMaxSize(1);
-        return PgClient.pool(vertx, options);
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getHost() {
-        return host;
-    }
-
-    public void setHost(String host) {
-        this.host = host;
-    }
-
-    public int getPort() {
-        return port;
-    }
-
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-}

+ 0 - 63
frameworks/Java/spring-webflux/src/main/java/benchmark/config/R2dbcConfig.java

@@ -1,63 +0,0 @@
-package benchmark.config;
-
-
-import io.r2dbc.spi.ConnectionFactories;
-import io.r2dbc.spi.ConnectionFactory;
-
-import io.r2dbc.spi.ConnectionFactoryOptions;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-import org.springframework.r2dbc.core.DatabaseClient;
-
-import static io.r2dbc.spi.ConnectionFactoryOptions.*;
-
-@Configuration
-@Profile("r2dbc")
-@ConfigurationProperties(prefix = "database")
-public class R2dbcConfig {
-    private String name;
-    private String host;
-    private int port;
-    private String username;
-    private String password;
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setHost(String host) {
-        this.host = host;
-    }
-
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    @Bean
-    ConnectionFactory connectionFactory() {
-        return ConnectionFactories.get(ConnectionFactoryOptions.builder()
-                .option(DRIVER,"pool")
-                .option(PROTOCOL,"postgresql")
-                .option(HOST, host)
-                .option(PORT, port)
-                .option(USER, username)
-                .option(PASSWORD, password)
-                .option(DATABASE, name)
-                .build());
-    }
-
-    @Bean
-    DatabaseClient databaseClient(ConnectionFactory connectionFactory) {
-        return DatabaseClient.create(connectionFactory);
-    }
-}

+ 0 - 54
frameworks/Java/spring-webflux/src/main/java/benchmark/config/ReactiveMongoConfig.java

@@ -1,54 +0,0 @@
-package benchmark.config;
-
-import com.mongodb.reactivestreams.client.MongoClient;
-import com.mongodb.reactivestreams.client.MongoClients;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration;
-import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
-import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
-
-@Configuration
-@EnableReactiveMongoRepositories
-@Profile("mongo")
-@ConfigurationProperties(prefix = "database")
-public class ReactiveMongoConfig extends AbstractReactiveMongoConfiguration {
-    private String url;
-    private String name;
-
-    @Override
-    @Bean
-    public MongoClient reactiveMongoClient() {
-        LoggerFactory.getLogger(getClass()).info("Connecting to mongo url: {}/{}", url, name);
-        return MongoClients.create(url);
-    }
-
-    @Override
-    protected String getDatabaseName() {
-        return name;
-    }
-
-    @Bean
-    ReactiveMongoTemplate reactiveMongoTemplate() {
-        return new ReactiveMongoTemplate(reactiveMongoClient(), getDatabaseName());
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}

+ 0 - 25
frameworks/Java/spring-webflux/src/main/java/benchmark/config/RxJdbcConfig.java

@@ -1,25 +0,0 @@
-package benchmark.config;
-
-import org.davidmoten.rx.jdbc.ConnectionProvider;
-import org.davidmoten.rx.jdbc.Database;
-import org.davidmoten.rx.jdbc.pool.NonBlockingConnectionPool;
-import org.davidmoten.rx.jdbc.pool.Pools;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-
-@Configuration
-@Profile("rxjdbc")
-public class RxJdbcConfig {
-    @Bean
-    Database database(DataSourceProperties dsProps) {
-        NonBlockingConnectionPool pool =
-                Pools.nonBlocking()
-                        .maxPoolSize(Runtime.getRuntime().availableProcessors() * 2)
-                        .connectionProvider(ConnectionProvider.from(dsProps.getUrl(), dsProps.getUsername(), dsProps.getPassword()))
-                        .build();
-
-        return Database.from(pool);
-    }
-}

+ 15 - 0
frameworks/Java/spring-webflux/src/main/java/benchmark/model/Message.java

@@ -0,0 +1,15 @@
+package benchmark.model;
+
+public class Message {
+
+	private final String message;
+
+	public Message(String message) {
+		this.message = message;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+}

+ 8 - 9
frameworks/Java/spring-webflux/src/main/java/benchmark/repository/MongoDbRepository.java

@@ -5,7 +5,7 @@ import benchmark.model.World;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Profile;
-import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
+import org.springframework.data.mongodb.core.ReactiveMongoOperations;
 import org.springframework.stereotype.Component;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
@@ -18,22 +18,21 @@ import static org.springframework.data.mongodb.core.query.Update.update;
 @Component
 @Profile("mongo")
 public class MongoDbRepository implements DbRepository {
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final ReactiveMongoTemplate mongoTemplate;
 
-    public MongoDbRepository(ReactiveMongoTemplate mongoTemplate) {
-        this.mongoTemplate = mongoTemplate;
+    private final ReactiveMongoOperations operations;
+
+    public MongoDbRepository(ReactiveMongoOperations operations) {
+        this.operations = operations;
     }
 
     @Override
     public Mono<World> getWorld(int id) {
-        log.debug("getWorld({})", id);
-        return mongoTemplate.findById(id, World.class);
+        return operations.findById(id, World.class);
     }
 
     @Override
     public Mono<World> findAndUpdateWorld(int id, int randomNumber) {
-        return mongoTemplate.findAndModify(
+        return operations.findAndModify(
                 query(where("id").is(id)),
                 update("randomNumber", randomNumber),
                 options().returnNew(true),
@@ -42,6 +41,6 @@ public class MongoDbRepository implements DbRepository {
 
     @Override
     public Flux<Fortune> fortunes() {
-        return mongoTemplate.findAll(Fortune.class);
+        return operations.findAll(Fortune.class);
     }
 }

+ 0 - 79
frameworks/Java/spring-webflux/src/main/java/benchmark/repository/PgClientDbRepository.java

@@ -1,79 +0,0 @@
-package benchmark.repository;
-
-import benchmark.PgClients;
-import benchmark.model.Fortune;
-import benchmark.model.World;
-import io.reactiverse.pgclient.PgIterator;
-import io.reactiverse.pgclient.Row;
-import io.reactiverse.pgclient.Tuple;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Component;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-@Component
-@Profile("pgclient")
-public class PgClientDbRepository implements DbRepository {
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final PgClients pgClients;
-
-    public PgClientDbRepository(PgClients pgClients) {
-        this.pgClients = pgClients;
-    }
-
-    @Override
-    public Mono<World> getWorld(int id) {
-        return Mono.create(sink ->
-                pgClients.getOne().preparedQuery("SELECT * FROM world WHERE id = $1", Tuple.of(id), ar -> {
-                    if (ar.failed()) {
-                        sink.error(ar.cause());
-                    } else {
-
-                        final Row row = ar.result().iterator().next();
-
-                        World world = new World(row.getInteger(0), row.getInteger(1));
-                        sink.success(world);
-                    }
-                }));
-    }
-
-    private Mono<World> updateWorld(World world) {
-        return Mono.create(sink -> {
-            pgClients.getOne().preparedQuery("UPDATE world SET randomnumber = $1 WHERE id = $2", Tuple.of(world.randomnumber, world.id), ar -> {
-                if (ar.failed()) {
-                    sink.error(ar.cause());
-                } else {
-                    sink.success(world);
-                }
-            });
-        });
-    }
-
-    @Override
-    public Mono<World> findAndUpdateWorld(int id, int randomNumber) {
-        return getWorld(id).flatMap(world -> {
-            world.randomnumber = randomNumber;
-            return updateWorld(world);
-        });
-    }
-
-    @Override
-    public Flux<Fortune> fortunes() {
-        return Flux.create(sink ->
-                pgClients.getOne().preparedQuery("SELECT * FROM fortune", ar -> {
-                    if (ar.failed()) {
-                        sink.error(ar.cause());
-                        return;
-                    }
-
-                    PgIterator resultSet = ar.result().iterator();
-                    while (resultSet.hasNext()) {
-                        Tuple row = resultSet.next();
-                        sink.next(new Fortune(row.getInteger(0), row.getString(1)));
-                    }
-                    sink.complete();
-                }));
-    }
-}

+ 2 - 2
frameworks/Java/spring-webflux/src/main/java/benchmark/repository/R2dbcDbRepository.java

@@ -22,7 +22,7 @@ public class R2dbcDbRepository implements DbRepository {
         return databaseClient
                 .sql("SELECT id, randomnumber FROM world WHERE id = $1")
                 .bind("$1", id)
-                .map((row, rowMetaData) -> new World(row.get("id", Integer.class), row.get("randomnumber", Integer.class)))
+                .mapProperties(World.class)
                 .first();
 
     }
@@ -48,7 +48,7 @@ public class R2dbcDbRepository implements DbRepository {
     public Flux<Fortune> fortunes() {
         return databaseClient
                 .sql("SELECT id, message FROM fortune")
-                .map((row, rowMetaData) -> new Fortune(row.get("id", Integer.class), row.get("message", String.class)))
+                .mapProperties(Fortune.class)
                 .all();
     }
 }

+ 0 - 60
frameworks/Java/spring-webflux/src/main/java/benchmark/repository/RxJdbcDbRepository.java

@@ -1,60 +0,0 @@
-package benchmark.repository;
-
-import benchmark.model.Fortune;
-import benchmark.model.World;
-import io.reactivex.Flowable;
-import org.davidmoten.rx.jdbc.Database;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Component;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-@Component
-@Profile("rxjdbc")
-public class RxJdbcDbRepository implements DbRepository {
-    private final Database db;
-
-    public RxJdbcDbRepository(Database db) {
-        this.db = db;
-    }
-
-    @Override
-    public Mono<World> getWorld(int id) {
-        String sql = "SELECT * FROM world WHERE id = ?";
-
-        Flowable<World> worldFlowable = db.select(sql)
-                .parameters(id)
-                .get(rs -> {
-                    World world = new World(rs.getInt("id"), rs.getInt("randomnumber"));
-                    return world;
-                });
-
-        return Mono.from(worldFlowable);
-    }
-
-    public Mono<World> updateWorld(World world) {
-        String sql = "UPDATE world SET randomnumber = ? WHERE id = ?";
-
-        Flowable<World> worldFlowable = db.update(sql)
-                .parameters(world.randomnumber, world.id)
-                .counts().map(cnt -> world);
-        return Mono.from(worldFlowable);
-    }
-
-    public Mono<World> findAndUpdateWorld(int id, int randomNumber) {
-        return getWorld(id).flatMap(world -> {
-            world.randomnumber = randomNumber;
-            return updateWorld(world);
-        });
-    }
-
-    @Override
-    public Flux<Fortune> fortunes() {
-        String sql = "SELECT * FROM fortune";
-
-        Flowable<Fortune> fortuneFlowable = db.select(sql)
-                .get(rs -> new Fortune(rs.getInt("id"), rs.getString("message")));
-
-        return Flux.from(fortuneFlowable);
-    }
-}

+ 13 - 10
frameworks/Java/spring-webflux/src/main/java/benchmark/web/WebfluxHandler.java

@@ -1,8 +1,16 @@
 package benchmark.web;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ThreadLocalRandom;
+
 import benchmark.model.Fortune;
+import benchmark.model.Message;
 import benchmark.model.World;
 import benchmark.repository.DbRepository;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
 
 import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.http.MediaType;
@@ -10,16 +18,11 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.reactive.function.server.ServerRequest;
 import org.springframework.web.reactive.function.server.ServerResponse;
 
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.util.*;
-import java.util.concurrent.ThreadLocalRandom;
-
 import static java.util.Comparator.comparing;
 
 @Component
 public class WebfluxHandler {
+
     private final DbRepository dbRepository;
 
     public WebfluxHandler(DbRepository dbRepository) {
@@ -29,13 +32,13 @@ public class WebfluxHandler {
     public Mono<ServerResponse> plaintext(ServerRequest request) {
         return ServerResponse.ok()
                 .contentType(MediaType.TEXT_PLAIN)
-                .body(Mono.just("Hello, World!"), String.class);
+                .bodyValue("Hello, World!");
     }
 
     public Mono<ServerResponse> json(ServerRequest request) {
         return ServerResponse.ok()
                 .contentType(MediaType.APPLICATION_JSON)
-                .body(Mono.just(Map.of("message", "Hello, World!")), Map.class);
+                .bodyValue(new Message("Hello, World!"));
     }
 
     public Mono<ServerResponse> db(ServerRequest request) {
@@ -76,7 +79,7 @@ public class WebfluxHandler {
 
     public Mono<ServerResponse> updates(ServerRequest request) {
         int queries = getQueries(request);
-        
+
         Mono<List<World>> worlds = Flux.range(0, queries)
                 .flatMap(i -> dbRepository.findAndUpdateWorld(randomWorldNumber(), randomWorldNumber()))
                 .collectList();
@@ -105,4 +108,4 @@ public class WebfluxHandler {
     private static int randomWorldNumber() {
         return 1 + ThreadLocalRandom.current().nextInt(10000);
     }
-}
+}

+ 9 - 23
frameworks/Java/spring-webflux/src/main/java/benchmark/web/WebfluxRouter.java

@@ -6,32 +6,18 @@ import org.springframework.web.reactive.function.server.RouterFunction;
 import org.springframework.web.reactive.function.server.RouterFunctions;
 import org.springframework.web.reactive.function.server.ServerResponse;
 
-import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
-
 @Configuration
 public class WebfluxRouter {
 
     @Bean
-    RouterFunction<ServerResponse> route(WebfluxHandler handler) {
-        return RouterFunctions
-                .route(
-                        GET("/plaintext"),
-                        handler::plaintext)
-                .andRoute(
-                        GET("/json"),
-                        handler::json)
-                .andRoute(
-                        GET("/db"),
-                        handler::db)
-                .andRoute(
-                        GET("/queries"),
-                        handler::queries)
-                .andRoute(
-                        GET("/updates"),
-                        handler::updates)
-                .andRoute(
-                        GET("/fortunes"),
-                        handler::fortunes)
-                ;
+    public RouterFunction<ServerResponse> route(WebfluxHandler handler) {
+        return RouterFunctions.route()
+                .GET("/plaintext", handler::plaintext)
+                .GET("/json", handler::json)
+                .GET("/db", handler::db)
+                .GET("/queries", handler::queries)
+                .GET("/updates", handler::updates)
+                .GET("/fortunes", handler::fortunes)
+                .build();
     }
 }

+ 10 - 53
frameworks/Java/spring-webflux/src/main/resources/application.yml

@@ -1,17 +1,3 @@
-spring:
-  jpa:
-    open-in-view: false
-
----
-spring:
-  config:
-    activate:
-      on-profile: postgres
-  datasource:
-    url: jdbc:postgresql://${database.host}:${database.port}/${database.name}
-    username: ${database.username}
-    password: ${database.password}
-
 database:
   name: hello_world
   host: tfb-database
@@ -19,45 +5,17 @@ database:
   username: benchmarkdbuser
   password: benchmarkdbpass
 
----
-spring:
-  config:
-    activate:
-      on-profile: jdbc
-  autoconfigure:
-    exclude:
-    - org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
-    - org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration 
-
----
-spring:
-  config:
-    activate:
-      on-profile: pgclient
-  autoconfigure:
-    exclude:
-    - org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
-    - org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration 
-
----
-spring:
-  config:
-    activate:
-      on-profile: rxjdbc
-  autoconfigure:
-    exclude:
-    - org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
-    - org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration 
-
 ---
 spring:
   config:
     activate:
       on-profile: r2dbc
   autoconfigure:
-    exclude:
-    - org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
-    - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 
+    exclude: org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
+  r2dbc:
+    username: ${database.username}
+    password: ${database.password}
+    url: r2dbc:postgresql://${database.host}:${database.port}/${database.name}
 
 ---
 spring:
@@ -65,10 +23,9 @@ spring:
     activate:
       on-profile: mongo
   autoconfigure:
-    exclude:
-    - org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration 
-    - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 
+    exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration
 
-database:
-  url: mongodb://tfb-database:27017/?waitQueueMultiple=200
-  name: hello_world
+  data:
+    mongodb:
+      uri: mongodb://tfb-database:27017/?waitQueueMultiple=200
+      database: hello_world

+ 2 - 5
frameworks/Java/spring/pom.xml

@@ -11,11 +11,11 @@
 	<parent>
 		<groupId>org.springframework.boot</groupId>
 		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>3.3.0</version>
+		<version>3.3.1</version>
 	</parent>
 
 	<properties>
-		<java.version>17</java.version>
+		<java.version>21</java.version>
 	</properties>
 
 	<dependencies>
@@ -61,9 +61,6 @@
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-compiler-plugin</artifactId>
-				<configuration>
-					<debug>false</debug>
-				</configuration>
 			</plugin>
 		</plugins>
 	</build>

+ 5 - 5
frameworks/Java/spring/spring-jpa.dockerfile

@@ -1,15 +1,15 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
-RUN mvn -version
+FROM maven:3.9.5-eclipse-temurin-21 as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM eclipse-temurin:21.0.3_9-jre-jammy
-RUN java -version
+FROM bellsoft/liberica-openjre-debian:21
 WORKDIR /spring
 COPY --from=maven /spring/target/hello-spring-1.0-SNAPSHOT.jar app.jar
+# See https://docs.spring.io/spring-boot/reference/packaging/efficient.html
+RUN java -Djarmode=tools -jar app.jar extract
 
 EXPOSE 8080
 
-CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseG1GC", "-XX:+DisableExplicitGC", "-XX:+UseStringDeduplication", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=jpa"]
+CMD ["java", "-XX:+DisableExplicitGC", "-XX:+UseStringDeduplication", "-Dlogging.level.root=OFF", "-jar", "app/app.jar", "--spring.profiles.active=jpa"]

+ 5 - 5
frameworks/Java/spring/spring-mongo.dockerfile

@@ -1,15 +1,15 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
-RUN mvn -version
+FROM maven:3.9.5-eclipse-temurin-21 as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM eclipse-temurin:21.0.3_9-jre-jammy
-RUN java -version
+FROM bellsoft/liberica-openjre-debian:21
 WORKDIR /spring
 COPY --from=maven /spring/target/hello-spring-1.0-SNAPSHOT.jar app.jar
+# See https://docs.spring.io/spring-boot/reference/packaging/efficient.html
+RUN java -Djarmode=tools -jar app.jar extract
 
 EXPOSE 8080
 
-CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseG1GC", "-XX:+DisableExplicitGC", "-XX:+UseStringDeduplication", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=mongo"]
+CMD ["java", "-XX:+DisableExplicitGC", "-XX:+UseStringDeduplication", "-Dlogging.level.root=OFF", "-jar", "app/app.jar", "--spring.profiles.active=mongo"]

+ 5 - 5
frameworks/Java/spring/spring.dockerfile

@@ -1,15 +1,15 @@
-FROM maven:3.9.6-eclipse-temurin-21 as maven
-RUN mvn -version
+FROM maven:3.9.5-eclipse-temurin-21 as maven
 WORKDIR /spring
 COPY src src
 COPY pom.xml pom.xml
 RUN mvn package -q
 
-FROM eclipse-temurin:21.0.3_9-jre-jammy
-RUN java -version
+FROM bellsoft/liberica-openjre-debian:21
 WORKDIR /spring
 COPY --from=maven /spring/target/hello-spring-1.0-SNAPSHOT.jar app.jar
+# See https://docs.spring.io/spring-boot/reference/packaging/efficient.html
+RUN java -Djarmode=tools -jar app.jar extract
 
 EXPOSE 8080
 
-CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+DisableExplicitGC", "-XX:+UseStringDeduplication", "-Dlogging.level.root=OFF", "-jar", "app.jar", "--spring.profiles.active=jdbc"]
+CMD ["java", "-XX:+DisableExplicitGC", "-XX:+UseStringDeduplication", "-Dlogging.level.root=OFF", "-jar", "app/app.jar", "--spring.profiles.active=jpa"]

+ 1 - 1
frameworks/Java/spring/src/main/java/hello/App.java

@@ -14,7 +14,7 @@ import org.springframework.context.event.EventListener;
 
 import com.zaxxer.hikari.HikariDataSource;
 
-@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class})
+@SpringBootApplication
 public class App {
 
 	public static void main(String[] args) {

+ 2 - 13
frameworks/Java/spring/src/main/java/hello/controller/HelloController.java

@@ -6,6 +6,7 @@ import java.util.List;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.stream.IntStream;
 
+import hello.model.Message;
 import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -31,7 +32,7 @@ public final class HelloController {
 		this.updateWorldService = updateWorldService;
 	}
 
-	@GetMapping(value = "/plaintext")
+	@GetMapping("/plaintext")
 	String plaintext(HttpServletResponse response) {
 		response.setContentType(MediaType.TEXT_PLAIN_VALUE);
 		return "Hello, World!";
@@ -102,16 +103,4 @@ public final class HelloController {
 		}
 		return Math.min(500, Math.max(1, parsedValue));
 	}
-
-	static class Message {
-		private final String message;
-
-		public Message(String message) {
-			this.message = message;
-		}
-
-		public String getMessage() {
-			return message;
-		}
-	}
 }

+ 15 - 0
frameworks/Java/spring/src/main/java/hello/model/Message.java

@@ -0,0 +1,15 @@
+package hello.model;
+
+public class Message {
+
+	private final String message;
+
+	public Message(String message) {
+		this.message = message;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+}

+ 13 - 4
frameworks/Java/spring/src/main/resources/application.yml

@@ -1,10 +1,15 @@
 ---
 spring:
-  threads:
-    virtual:
-      enabled: true
   jpa:
     open-in-view: false
+  config:
+    activate:
+      on-profile: jdbc
+  autoconfigure:
+    exclude: org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration
+
+---
+spring:
   config:
     activate:
       on-profile: jdbc,jpa
@@ -25,6 +30,8 @@ spring:
   config:
     activate:
       on-profile: jpa
+  autoconfigure:
+    exclude: org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration
   jpa:
     database-platform: org.hibernate.dialect.PostgreSQLDialect
 
@@ -33,6 +40,8 @@ spring:
   config:
     activate:
       on-profile: mongo
+  autoconfigure:
+    exclude: org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
 
 spring.data.mongodb:
   host: tfb-database
@@ -45,4 +54,4 @@ spring:
     active: jdbc
 
 server.server-header: Spring
-server.servlet.encoding.force: true
+server.servlet.encoding.force: true