Java RAG Development Environment Setup
1. Docker Installation and Verification
Verify Docker is installed by running:
docker run hello-world
If Docker is working correctly, this command pulls a test image from Docker Hub and outputs:
Hello from Docker! This message shows that your installation appears to be working correctly.
2. Setting Up Elasticsearch and Qdrant with Docker Compose
With Docker available, launch both Elasticsearch and Qdrant services together using Docker Compose. Create a docker-compose.yml file in your project directory:
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.9.0 # 指定Elasticsearch镜像版本
container_name: elasticsearch
environment:
- discovery.type=single-node # 单节点模式,无需集群配置
- xpack.security.enabled=false # 禁用安全认证,方便本地测试
- bootstrap.memory_lock=false
- ES_JAVA_OPTS=-Xms1g -Xmx1g # 限制ES JVM内存
ulimits:
memlock:
soft: -1
hard: -1
ports:
- 9200:9200 # 映射Elasticsearch端口
qdrant:
image: qdrant/qdrant:latest # 使用最新版本的Qdrant镜像
container_name: qdrant
ports:
- 6333:6333 # REST API端口(HTTP)
- 6334:6334 # gRPC端口(用于Spring AI连接)
Start the services:
docker compose up -d
(or docker-compose up -d on older systems)
Check container status with docker ps; both services should show Up.
Verify Elasticsearch by opening http://localhost:9200 in a browser. You should see JSON cluster information:
{"cluster_name":"docker-cluster",...}
No authentication is required since security is disabled.
Verify Qdrant at http://localhost:6333 in a browser. You should see a welcome page. To confirm health status, run:
curl http://localhost:6333/health
A successful health check returns JSON status information. Both Qdrant and Elasticsearch are now ready.
3. Installing Java JDK and Maven
Install Java 17 or a newer LTS version (such as Java 21). Using Homebrew:
brew install openjdk@17
Add the JDK bin directory to your shell configuration (e.g., ~/.zshrc):
export PATH="/usr/local/opt/openjdk@17/bin:$PATH"
Verify with:
java -version
Install Maven:
brew install maven
Verify Maven:
mvn -v
Both java and mvn commands must be available in your terminal PATH. If not found, check your shell configuration.
4. Creating a Spring Boot Project with Qdrant Support
Use IntelliJ IDEA to create a new Spring Boot project. Select Create New Project → Spring Initializr. Fill in:
- Group:
com.example - Artifact:
rag-demo - Spring Boot version: 3.1 or later
- Project type: Maven
Add the Spring Web dependency. After generation, edit pom.xml and add the Spring AI Qdrant starter:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-qdrant</artifactId>
<version>1.0.0-M7</version> <!-- 使用当前最新的版本号 -->
</dependency>
Open src/main/resources/application.yml and configure Qdrant:
spring:
ai:
vectorstore:
qdrant:
host: localhost # Qdrant 服务主机地址(默认localhost)
port: 6334 # Qdrant gRPC端口 [oai_citation:4‡docs.spring.io](https://docs.spring.io/spring-ai/reference/api/vectordbs/qdrant.html#:~:text=)
collection-name: demo_vectors # 指定向量集合名称
initialize-schema: true # 自动初始化集合schema(如果尚未创建集合)
This tells Spring AI to connect to Qdrant on the default gRPC port (6334), use a collection named demo_vectors, and create it automatically if needed. No API key is required for the default development setup.
Optional: Embedding Model Configuration
To store and search text vectors, configure an embedding model. Add OpenAI integration:
<!-- 在 pom.xml 中添加 OpenAI 集成 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-openai</artifactId>
<version>1.0.0-M7</version>
</dependency>
Then update application.yml:
spring:
ai:
model:
openai:
api-key: sk-xxx... # OpenAI API密钥
embedding-model: text-embedding-ada-002 # 指定使用的嵌入模型名称
Spring AI will automatically create an OpenAI embedding bean. If you don't have an OpenAI API key, you can skip this step and either implement a simple embedding bean for testing or call the Qdrant API directly to store custom vectors.
5. Writing a Test Controller for Vector Operations
Create a REST controller to test vector storage and retrieval. In src/main/java, create a package (e.g., com.example.ragdemo.controller) and add:
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ai.embeddings.Document;
import org.springframework.ai.vectordb.VectorStore;
import org.springframework.ai.search.SearchRequest;
import java.util.List;
import java.util.Map;
@RestController
public class VectorTestController {
@Autowired
private VectorStore vectorStore; // 自动注入 Qdrant 向量存储接口
// 简单GET接口,用于插入向量并检索
@GetMapping("/test-vector")
public List<String> testVectorStore() {
// 1. 构造待插入的文档列表(每个Document包含文本和可选的元数据)
Document doc = new Document("Spring AI 在向量检索中的应用示例",
Map.of("source", "test"));
List<Document> documents = List.of(doc);
// 2. 将文档添加到 Qdrant 向量库(自动完成向量嵌入并存储)
vectorStore.add(documents); // 插入文档向量 [oai_citation:7‡docs.spring.io](https://docs.spring.io/spring-ai/reference/api/vectordbs/qdrant.html#:~:text=List,meta2)
// 3. 使用相似度搜索检索与查询文本语义相近的文档
SearchRequest request = SearchRequest.builder()
.query("向量检索示例") // 查询文本
.topK(5) // 返回前5个相似结果
.build();
List<Document> results = vectorStore.similaritySearch(request); // 执行相似度检索 [oai_citation:8‡docs.spring.io](https://docs.spring.io/spring-ai/reference/api/vectordbs/qdrant.html#:~:text=%2F%2F%20Retrieve%20documents%20similar%20to,topK%285%29.build)
// 4. 提取结果中文档的内容并返回
List<String> resultContents = results.stream()
.map(Document::getContent)
.toList();
return resultContents;
}
}
This controller injects the VectorStore (Spring AI automatically creates a QdrantVectorStore from your configuration). The /test-vector endpoint creates a document, stores it in Qdrant via vectorStore.add(), then performs a similarity search using vectorStore.similaritySearch(). The query text "向量检索示例" matches the inserted document semantically, so the search should return it.
Note: If you skipped embedding model configuration, this step will fail at runtime because the text cannot be converted to vectors. Ensure OpenAI or another embedding model is configured. Alternatively, use the QdrantClient API directly to store custom vectors, though text-based vectors better simulate a real RAG scenario.
Verify the imports are available. If Document, VectorStore, or SearchRequest classes cannot be imported, check that Spring AI dependencies were added correctly and that Maven downloaded them. For milestone versions, confirm that your Maven repositories section includes Spring Milestones or Snapshots repositories, or use Spring AI's BOM for dependency management.
6. Launching and Verifying the Application
Start the Spring Boot application. In IntelliJ IDEA, run the main class, or from your project root:
mvn spring-boot:run
The application reads the Qdrant configuration during startup. Verify successful connection in the console logs. You should see Started RagDemoApplication in [time] seconds with no errors.
Open http://localhost:8080/test-vector in your browser. The first call may be slightly delayed (embedding generation). A successful response returns a JSON array containing the stored document text:
["Spring AI 在向量检索中的应用示例"]
If the search returns your inserted text, the vector pipeline is working end-to-end.
Troubleshooting
If the interface does not respond correctly:
- Application logs: Check for Qdrant connection errors (host not found, port unreachable). Confirm the Docker Compose Qdrant container is running, port mappings are correct, and your application configuration matches. On Mac,
localhosttypically maps to containers correctly; if uncertain, tryhost.docker.internal. - Qdrant container: Run
docker compose psto verify Qdrant status, ordocker logs qdrantto see its output. - Embedding model: Verify the OpenAI API key is configured, valid, and not expired. If using a custom embedding bean, confirm it is properly injected.
- Elasticsearch container: This example does not directly use Elasticsearch, but production RAG systems typically do for text indexing. Verify the container is running by accessing its health endpoint.
You now have a working Java + Spring AI project with Qdrant integration. This foundation supports adding language model calls, refining search strategies that combine vector and text retrieval, and building a complete retrieval-augmented generation system.