I am creating an autoconfiguration library for SpringBoot 3.1.0. The source code can by found here https://github.com/ugwun/spring-boot-starter-openai
I am following this documentation for creating autoconfiguration libraries: https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/boot-features-developing-auto-configuration.html
I created:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.github.ugwun.springbootstarteropenai.configuration.OpenAIAutoconfiguration
@Configuration
public class OpenAIAutoconfiguration {
@Value("${openai.api.key}")
private String apiKey;
@Bean
@ConditionalOnMissingBean
public AiApiClient openAIApiClient() {
return new OpenAiApiClient(apiKey);
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.github.ugwun</groupId>
<artifactId>springbootstarteropenai</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>${project.groupId}:${project.artifactId}</name>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
However, when I try to use the autoconfiguration library in a different project, the bean isn't created.
Example usage from a different SpringBoot app:
@SpringBootApplication
public class SpringboottestingApplication {
public static void main(String[] args) {
SpringApplication.run(SpringboottestingApplication.class, args);
}
}
@RestController
class HelloController {
private final AiApiClient client;
HelloController(AiApiClient client) {
this.client = client;
}
@GetMapping("/")
String hello() {
Map<String, String>[] messages = new Map[]{
Map.of("role", "system", "content", "You are a helpful assistant."),
Map.of("role", "user", "content", "Who won the world series in 2020?")
};
try {
return client.generateChatMessage("gpt-3.5-turbo", messages);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
I get this error:
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-06-27T18:14:14.224+02:00 ERROR 3352 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.springboottesting.HelloController required a bean of type 'io.github.ugwun.springbootstarteropenai.client.AiApiClient' that could not be found.
Action:
Consider defining a bean of type 'io.github.ugwun.springbootstarteropenai.client.AiApiClient' in your configuration.
Process finished with exit code 1
The only way how I was able to get the SpringBoot app to load the AiApiClient
bean was by using the scanBasePackages
:
@SpringBootApplication(scanBasePackages = {"com.example", "io.github.ugwun.springbootstarteropenai"})
If I understand the autoconfiguration correctly, this isn't something that I have to be doing. Autoconfigured beans should be loaded out of the box.
Help or a pointer would be very appreciated.
Your starter project uses spring-boot version 3.1.x
and you follow a 2.x
tutorial.
Here is the correct documentation features.developing-auto-configuration
in short:
don't use META-INF/spring.factories
but META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports