Appearance
Spring AI 与其他 Spring 组件集成
Spring AI 的一个重要优势是它能够与 Spring 生态系统中的其他组件无缝集成。本文将介绍如何将 Spring AI 与其他 Spring 组件和框架结合使用,构建功能完整的 AI 增强型应用。
Spring Boot 集成
Spring AI 与 Spring Boot 的集成是最基础和常见的集成场景:
依赖配置
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>0.8.0</version>
</dependency>
自动配置
Spring Boot 自动配置会自动设置 Spring AI 的核心组件:
java
@SpringBootApplication
public class AiApplication {
public static void main(String[] args) {
SpringApplication.run(AiApplication.class, args);
}
// 自动配置会创建并注册:
// - ChatClient
// - EmbeddingClient
// - ImageClient (如果适用)
}
配置属性
在 application.properties
或 application.yml
中配置 AI 服务:
yaml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
model: gpt-4
temperature: 0.7
max-tokens: 2000
Spring Data 集成
Spring AI 可以与 Spring Data 集成,特别是在实现向量存储和 RAG 应用时:
Spring Data JPA 与向量存储
将嵌入存储在关系数据库中:
java
@Entity
@Table(name = "document_embeddings")
public class DocumentEmbedding {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String documentId;
@Column(nullable = false, length = 1000)
private String content;
@Column(name = "embedding", columnDefinition = "VECTOR")
private float[] embedding;
// getters, setters, etc.
}
@Repository
public interface DocumentEmbeddingRepository extends JpaRepository<DocumentEmbedding, Long> {
// 使用 JPQL 查询 (假设数据库支持向量相似度计算)
@Query(value = "SELECT d FROM DocumentEmbedding d ORDER BY cosine_similarity(d.embedding, :embedding) DESC LIMIT :limit")
List<DocumentEmbedding> findSimilarDocuments(@Param("embedding") float[] embedding, @Param("limit") int limit);
}
Spring Data Redis 集成
使用 Redis 作为向量存储:
java
@Configuration
public class RedisVectorStoreConfig {
@Bean
public RedisVectorStore redisVectorStore(
RedisConnectionFactory connectionFactory,
EmbeddingClient embeddingClient) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.afterPropertiesSet();
return new RedisVectorStore(redisTemplate, embeddingClient);
}
}
Spring MVC 和 Spring WebFlux 集成
Spring MVC RESTful API
创建基于 Spring MVC 的 AI 服务 API:
java
@RestController
@RequestMapping("/api/ai")
public class AiController {
private final ChatClient chatClient;
private final ImageClient imageClient;
// 构造函数注入
@PostMapping("/chat")
public ResponseEntity<ChatResponseDto> chat(@RequestBody ChatRequestDto request) {
ChatResponse response = chatClient.call(new Prompt(request.getMessage()));
return ResponseEntity.ok(new ChatResponseDto(response.getResult().getOutput().getContent()));
}
@PostMapping("/image")
public ResponseEntity<byte[]> generateImage(@RequestBody ImageRequestDto request) {
ImageResponse response = imageClient.call(new ImagePrompt(request.getDescription()));
byte[] imageData = response.getResult().getOutput().getImageData();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<>(imageData, headers, HttpStatus.OK);
}
// DTO 类...
}
Spring WebFlux 流式响应
使用 WebFlux 实现流式聊天响应:
java
@RestController
@RequestMapping("/api/ai")
public class StreamingAiController {
private final StreamingChatClient streamingChatClient;
@PostMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestBody ChatRequestDto request) {
return streamingChatClient.stream(new Prompt(request.getMessage()))
.map(chunk -> chunk.getResult().getOutput().getContent());
}
}
Spring Security 集成
保护 AI 服务的访问:
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/ai/**").authenticated()
.anyRequest().authenticated()
)
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()))
.csrf(csrf -> csrf.disable());
return http.build();
}
@Bean
public RateLimitingFilter aiRateLimitingFilter() {
return new RateLimitingFilter("/api/ai/**", 10); // 每分钟 10 次请求
}
}
用户特定的 AI 访问权限
根据用户权限和订阅级别限制 AI 功能:
java
@Service
public class SubscriptionAwareAiService {
private final ChatClient openAiChatClient;
private final ChatClient anthropicChatClient;
private final ChatClient llamaChatClient;
private final UserSubscriptionService subscriptionService;
public ChatResponse generateResponse(String userId, String prompt) {
UserSubscription subscription = subscriptionService.getUserSubscription(userId);
return switch (subscription.getLevel()) {
case PREMIUM -> openAiChatClient.call(new Prompt(prompt)); // 高级模型
case STANDARD -> anthropicChatClient.call(new Prompt(prompt)); // 标准模型
case BASIC -> llamaChatClient.call(new Prompt(prompt)); // 基础模型
};
}
}
Spring Cache 集成
缓存 AI 响应以提高性能和减少 API 调用:
java
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("aiResponses", "embeddings");
}
}
@Service
public class CachedAiService {
private final ChatClient chatClient;
@Cacheable(value = "aiResponses", key = "#prompt.hashCode()")
public String getAiResponse(String prompt) {
ChatResponse response = chatClient.call(new Prompt(prompt));
return response.getResult().getOutput().getContent();
}
}
Spring Events 集成
使用事件驱动架构与 AI 服务集成:
java
@Service
public class EventDrivenAiService {
private final ChatClient chatClient;
private final ApplicationEventPublisher eventPublisher;
@EventListener
public void handleDocumentUploadEvent(DocumentUploadedEvent event) {
// 处理新上传的文档
String documentContent = event.getDocumentContent();
// 生成文档摘要
String summaryPrompt = "请总结以下文档内容:\n\n" + documentContent;
ChatResponse response = chatClient.call(new Prompt(summaryPrompt));
String summary = response.getResult().getOutput().getContent();
// 发布摘要生成事件
eventPublisher.publishEvent(new DocumentSummarizedEvent(
event.getDocumentId(), summary));
}
// 事件类
@Data
public static class DocumentUploadedEvent {
private final String documentId;
private final String documentContent;
}
@Data
public static class DocumentSummarizedEvent {
private final String documentId;
private final String summary;
}
}
Spring Batch 集成
使用 Spring Batch 进行大规模 AI 处理:
java
@Configuration
@EnableBatchProcessing
public class AiBatchConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final EmbeddingClient embeddingClient;
private final VectorStore vectorStore;
@Bean
public Job documentIndexingJob() {
return jobBuilderFactory.get("documentIndexingJob")
.start(documentProcessingStep())
.build();
}
@Bean
public Step documentProcessingStep() {
return stepBuilderFactory.get("documentProcessingStep")
.<Document, Document>chunk(10)
.reader(documentReader())
.processor(documentProcessor())
.writer(documentWriter())
.build();
}
@Bean
public ItemReader<Document> documentReader() {
// 实现从数据源读取文档
return new DocumentReader();
}
@Bean
public ItemProcessor<Document, Document> documentProcessor() {
return document -> {
// 文档预处理
String processedContent = preprocess(document.getContent());
document.setContent(processedContent);
// 生成嵌入
Embedding embedding = embeddingClient.embed(processedContent);
document.setEmbedding(embedding);
return document;
};
}
@Bean
public ItemWriter<Document> documentWriter() {
return documents -> {
// 将文档和嵌入存储到向量存储
vectorStore.add(documents);
};
}
private String preprocess(String content) {
// 实现文档预处理逻辑
return content.trim();
}
}
Spring Cloud 集成
在微服务架构中集成 Spring AI:
java
@SpringBootApplication
@EnableDiscoveryClient
public class AiServiceApplication {
public static void main(String[] args) {
SpringApplication.run(AiServiceApplication.class, args);
}
}
@RestController
@RequestMapping("/api/ai")
public class AiServiceController {
private final ChatClient chatClient;
@Value("${spring.application.name}")
private String serviceName;
@PostMapping("/generate")
public ResponseEntity<GenerationResponse> generate(@RequestBody GenerationRequest request) {
try {
ChatResponse response = chatClient.call(new Prompt(request.getPrompt()));
String content = response.getResult().getOutput().getContent();
return ResponseEntity.ok(new GenerationResponse(content, serviceName));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new GenerationResponse("Error generating content: " + e.getMessage(), serviceName));
}
}
// 请求/响应模型...
}
Spring Cloud Stream 与 AI 集成
使用消息流处理 AI 任务:
java
@Configuration
public class AiStreamConfig {
@Bean
public Consumer<DocumentMessage> processDocument(ChatClient chatClient, VectorStore vectorStore) {
return document -> {
// 生成文档摘要
String summary = generateSummary(chatClient, document.getContent());
// 生成嵌入
Embedding embedding = generateEmbedding(document.getContent());
// 存储到向量库
vectorStore.add(new Document(
document.getId(),
document.getContent(),
Map.of("summary", summary),
embedding.getVector()
));
};
}
private String generateSummary(ChatClient chatClient, String content) {
ChatResponse response = chatClient.call(new Prompt("总结以下内容:\n\n" + content));
return response.getResult().getOutput().getContent();
}
private Embedding generateEmbedding(String content) {
// 实现嵌入生成逻辑
return new OpenAiEmbedding(/* 嵌入向量 */);
}
@Data
public static class DocumentMessage {
private String id;
private String content;
private String metadata;
}
}
Spring Integration 集成
使用 Spring Integration 构建 AI 处理流程:
java
@Configuration
@EnableIntegration
public class AiIntegrationConfig {
@Bean
public IntegrationFlow aiProcessingFlow(
ChatClient chatClient,
EmbeddingClient embeddingClient,
VectorStore vectorStore) {
return IntegrationFlow.from("documentInputChannel")
.<DocumentDto>filter(doc -> doc.getContent() != null && !doc.getContent().isEmpty())
.split()
.<DocumentDto, DocumentDto>transform(doc -> {
// 生成摘要
String summary = generateSummary(chatClient, doc.getContent());
doc.getMetadata().put("summary", summary);
return doc;
})
.<DocumentDto, Document>transform(doc -> {
// 生成嵌入
Embedding embedding = embeddingClient.embed(doc.getContent());
// 创建文档对象
return new Document(
doc.getId(),
doc.getContent(),
doc.getMetadata(),
embedding.getVector()
);
})
.handle(message -> {
Document doc = (Document) message.getPayload();
vectorStore.add(Collections.singletonList(doc));
})
.channel("documentOutputChannel")
.get();
}
private String generateSummary(ChatClient chatClient, String content) {
ChatResponse response = chatClient.call(new Prompt("总结以下内容:\n\n" + content));
return response.getResult().getOutput().getContent();
}
@Data
public static class DocumentDto {
private String id;
private String content;
private Map<String, String> metadata = new HashMap<>();
}
}
集成的最佳实践
- 模块化设计:使用 Spring 的 DI 和组件化系统,将 AI 功能封装在专用服务中
- 抽象和接口:使用接口定义 AI 服务,便于切换实现和模拟测试
- 配置外部化:将 AI 服务配置(API 密钥、模型选择等)外部化
- 缓存策略:对适当的 AI 响应实施缓存,减少 API 调用
- 错误处理:实现适当的错误处理和回退策略
- 异步处理:对耗时的 AI 任务使用异步处理
- 安全防护:保护 AI 服务免受滥用和过度使用
- 监控与指标:使用 Spring 的监控和指标收集功能跟踪 AI 服务性能
总结
Spring AI 能够与 Spring 生态系统中的其他组件无缝集成,包括 Spring Boot、Spring Data、Spring MVC/WebFlux、Spring Security、Spring Cache、Spring Batch 和 Spring Cloud 等。这种集成能力使开发人员能够构建复杂的 AI 增强型应用,同时利用 Spring 框架的成熟特性和最佳实践。无论是构建简单的 AI API 服务,还是复杂的企业级 AI 应用,Spring AI 与其他 Spring 组件的集成都提供了强大的基础。