Get ahead
VMware offers training and certification to turbo-charge your progress.
Learn moreI am happy to announce that Spring Fu 0.3.0 is available. As a reminder, Spring Fu is an incubator for Spring Boot programmatic configuration using DSLs in order to configure it explicitly with code in a declarative way, achieving great discoverability thanks to auto-complete.
This new milestone brings back JaFu (the Java DSL) in addition to KoFu (the Kotlin DSL). JaFu was removed in 0.1.0 because at that point, I had not the bandwidth to support both Java and Kotlin DSLs, and in term of API I was not sure that the Java variant was attractive enough to justify such effort, but I have changed my mind for various reasons:
I received a lot of requests to bring it back
Java as a language is moving faster
Getting more control on how configuration is applied is interesting for Java developers as well as Kotlin ones
Functional approach is naturally very efficient on the JVM and a good fit with GraalVM native images
2 great new contributors have join the team: Audrey Neveu with a focus on KoFu and Arjen Poutsma with a focus on JaFu. Welcome to them!
This new release is also the opportunity for various improvements like a Spring Boot 2.3.0 baseline or API improvements, see the detailed changelog here.
Spring Fu 0.3.0 also ships with additional optimizations which enable only the functional Web infrastructure, so on my laptop I get pretty fast startup time on OpenJDK 11: Started Application in 0.673 seconds (JVM running for 0.898)
.
Since Spring MVC is now usable in a functional way for both Java and Kotlin, let’s see what looks like a minimal Spring Boot web application configured with those DSLs.
With JaFu:
public class Application {
public static JafuApplication app = webApplication(a -> a.beans(b -> b
.bean(SampleHandler.class)
.bean(SampleService.class))
.enable(webMvc(w -> w
.port(w.profiles().contains("test") ? 8181 : 8080)
.router(router -> {
SampleHandler handler = w.ref(SampleHandler.class);
router
.GET("/", handler::hello)
.GET("/api", handler::json);
}).converters(c -> c
.string()
.jackson(j -> j.indentOutput(true))))));
public static void main (String[] args) {
app.run(args);
}
}
With KoFu:
val app = webApplication {
beans {
bean<SampleService>()
bean<SampleHandler>()
}
webMvc {
port = if (profiles.contains("test")) 8181 else 8080
router {
val handler = ref<SampleHandler>()
GET("/", handler::hello)
GET("/api", handler::json)
}
converters {
string()
jackson {
indentOutput = false
}
}
}
}
fun main() {
app.run()
}
The power of this configuration model lies in the fact that you can define your own configuration slices and assemble them as you want. For example, let’s define 3 configuration slices webConfig
, loggingConfig
and myFeatureConfig
:
val webConfig = configuration {
webMvc {
// ...
}
}
val loggingConfig = configuration {
logging {
level = LogLevel.WARN
}
}
val myFeatureConfig = configuration {
beans {
// ...
}
cassandra {
// ...
}
}
You can then use them all for your regular web application:
val webApp = webApplication {
enable(loggingConfig)
enable(myFeatureConfig)
enable(webConfig)
}
fun main() {
webApp.run()
}
But you can also use just a subset for your integration tests for example:
@Test
fun `My feature integration test`() {
val testApp = application {
enable(loggingConfig)
enable(myFeatureConfig)
}
// ...
}
In term of roadmap, the next 0.4.0 milestone will focus on:
Replacing the autoconfigure-adapter module by leveraging spring-init, an experimental project created by Dave Syer and Andy Clement which automatically converts Spring Boot auto-configurations to functional bean registration.
GraalVM native support without reflection configuration (depends on oracle/graal#2500)
Refined DSL extensibility
Scale-to-zero application sample with JaFu, GraalVM native and Knative
Leverage Spring Framework 5.3 M1 to remove by default XML and SpEL support
Spring Security support via Spring Security 5.3 official Kotlin DSL
As usual, feedback is welcome. Be aware that we have for now mainly a focus on getting the right software design and APIs rather than an extensive coverage of more features.