Ever wished your Spring Boot project could tap into the expressive, dynamic world of Clojure? Now it can! With Spring Boot Clojure Starter, you get seamless, annotation-driven access to Clojure functions and namespacesβright from your Java code. No more glue code, no more reflection headaches. Just pure, idiomatic interop that lets you:
- π Call Clojure functions as if they were native Java methods
- π§ββοΈ Mix object-oriented and functional paradigms in one codebase
- β‘ Rapidly prototype, extend, and refactor with the power of the JVM
- π€ Enjoy automatic proxying, and name conversion
Whether you're a Clojure wizard or just want to sprinkle some functional magic into your Spring Boot app, this starter is your ticket to a more expressive, maintainable, and fun development experience.
Add the dependency to your pom.xml:
<dependency>
<groupId>io.github.isource</groupId>
<artifactId>clojure-spring-boot-starter</artifactId>
<version>1.0.1</version>
</dependency>- Recommended: Place your
.cljfiles undersrc/main/clojure/. This keeps your Clojure code managed as source, and your IDE will provide better code completion and navigation. To ensure these files are packaged as resources, add the following to yourpom.xml:
<build>
<resources>
<resource>
<directory>src/main/clojure</directory>
<includes>
<include>**/*.clj</include>
</includes>
</resource>
</resources>
</build>- Alternative: You can also place
.cljfiles undersrc/main/resources/clojure/, but IDE support for code completion and navigation may be limited.
Add to your build.gradle:
dependencies {
implementation 'io.github.isource:clojure-spring-boot-starter:1.0.1'
}- Recommended: Place your
.cljfiles undersrc/main/clojure/for better IDE support. Add this to your build script to package them as resources:
processResources {
from('src/main/clojure') {
include '**/*.clj'
}
}- Alternative: You can also use
src/main/resources/clojure/for your.cljfiles, but IDE features may be less robust.
Suppose you have a Clojure file at src/main/clojure/myapp/util.clj:
(ns myapp.util)
(defn do-something-cool [input]
(str "Doing something cool with " input "!"))Now, define a Java interface to call this function:
@ClojureNamespace("myapp.util")
public interface Util {
// The method name 'doSomethingCool' will be implicitly converted to the Clojure function 'do-something-cool'
String doSomethingCool(String input);
}- By default, Java method names in camelCase are converted to Clojure's kebab-case (e.g.,
doSomethingCoolβdo-something-cool). - If your Java method name matches the Clojure function name (after conversion), you don't need to annotate with
@ClojureFn. - If you want to map to a different Clojure function, use
@ClojureFn("clojure-fn-name"):
@ClojureNamespace("myapp.util")
public interface Util {
@ClojureFn("do-something-cool")
String customMethod(String input); // Maps 'customMethod' to Clojure 'do-something-cool'
}@Autowired
private Util util;
public void demo() {
System.out.println(util.doSomethingCool("Spring Boot")); // Doing something cool with Spring Boot!
System.out.println(util.customMethod("Clojure")); // Doing something cool with Clojure!
}No reflection, no manual wiringβjust annotate, inject, and call. The starter handles proxying, resource loading, and name conversion for you. Mix Java and Clojure with confidence!
Ready to supercharge your Spring Boot app with Clojure? Fork, star, and start coding! π