在本篇博文中,我们将构建一个简单的Spring Boot应用来演示如何创建一个股票价格更新系统,并在股票价格变动时自动通知订阅用户。这个示例将涵盖Spring Boot的核心功能,包括Web模块、数据持久化、消息队列以及简单的用户订阅机制。
项目结构和依赖
首先,我们需要创建一个新的Spring Boot项目,并添加必要的依赖。在pom.xml文件中加入以下依赖:
xml
深色版本
1<dependencies>
2 <dependency>
3 <groupId>org.springframework.boot</groupId>
4 <artifactId>spring-boot-starter-web</artifactId>
5 </dependency>
6 <dependency>
7 <groupId>org.springframework.boot</groupId>
8 <artifactId>spring-boot-starter-data-jpa</artifactId>
9 </dependency>
10 <dependency>
11 <groupId>org.springframework.boot</groupId>
12 <artifactId>spring-boot-starter-amqp</artifactId>
13 </dependency>
14 <dependency>
15 <groupId>com.h2database</groupId>
16 <artifactId>h2</artifactId>
17 <scope>runtime</scope>
18 </dependency>
19 <dependency>
20 <groupId>org.projectlombok</groupId>
21 <artifactId>lombok</artifactId>
22 <optional>true</optional>
23 </dependency>
24 <dependency>
25 <groupId>org.springframework.boot</groupId>
26 <artifactId>spring-boot-devtools</artifactId>
27 <scope>runtime</scope>
28 <optional>true</optional>
29 </dependency>
30 <dependency>
31 <groupId>org.springframework.boot</groupId>
32 <artifactId>spring-boot-starter-test</artifactId>
33 <scope>test</scope>
34 </dependency>
35</dependencies>
配置文件
接下来,在application.properties中配置数据库连接和RabbitMQ:
properties
深色版本
1spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
2spring.datasource.driverClassName=org.h2.Driver
3spring.datasource.username=sa
4spring.datasource.password=
5spring.jpa.hibernate.ddl-auto=create-drop
6
7spring.rabbitmq.host=localhost
8spring.rabbitmq.port=5672
9spring.rabbitmq.username=guest
10spring.rabbitmq.password=guest
实体类和数据模型
定义两个实体类:StockPrice 和 Subscriber。
java
深色版本
1import javax.persistence.Entity;
2import javax.persistence.GeneratedValue;
3import javax.persistence.GenerationType;
4import javax.persistence.Id;
5
6@Entity
7public class StockPrice {
8 @Id
9 @GeneratedValue(strategy = GenerationType.AUTO)
10 private Long id;
11 private String symbol;
12 private double price;
13
14 // Getters and setters
15}
16
17@Entity
18public class Subscriber {
19 @Id
20 @GeneratedValue(strategy = GenerationType.AUTO)
21 private Long id;
22 private String email;
23 private String symbol;
24
25 // Getters and setters
26}
数据访问层 (DAO)
创建两个接口继承JpaRepository以实现基本的CRUD操作:
java
深色版本
1import org.springframework.data.jpa.repository.JpaRepository;
2
3public interface StockPriceRepository extends JpaRepository<StockPrice, Long> {
4}
5
6public interface SubscriberRepository extends JpaRepository<Subscriber, Long> {
7}
服务层
定义服务类来处理业务逻辑:
java
深色版本
1import org.springframework.amqp.rabbit.core.RabbitTemplate;
2import org.springframework.beans.factory.annotation.Autowired;
3import org.springframework.stereotype.Service;
4
5@Service
6public class StockPriceService {
7 private final StockPriceRepository stockPriceRepository;
8 private final SubscriberRepository subscriberRepository;
9 private final RabbitTemplate rabbitTemplate;
10
11 @Autowired
12 public StockPriceService(StockPriceRepository stockPriceRepository,
13 SubscriberRepository subscriberRepository,
14 RabbitTemplate rabbitTemplate) {
15 this.stockPriceRepository = stockPriceRepository;
16 this.subscriberRepository = subscriberRepository;
17 this.rabbitTemplate = rabbitTemplate;
18 }
19
20 public void updatePrice(String symbol, double price) {
21 StockPrice stockPrice = stockPriceRepository.findBySymbol(symbol);
22 if (stockPrice == null) {
23 stockPrice = new StockPrice();
24 stockPrice.setSymbol(symbol);
25 }
26 stockPrice.setPrice(price);
27 stockPriceRepository.save(stockPrice);
28
29 notifySubscribers(symbol, price);
30 }
31
32 private void notifySubscribers(String symbol, double price) {
33 subscriberRepository.findAllBySymbol(symbol).forEach(subscriber -> {
34 rabbitTemplate.convertAndSend("stock-price-updates", "New price for " + symbol + ": " + price);
35 });
36 }
37}
控制器
创建一个REST控制器来接收股票价格更新请求:
java
深色版本
1import org.springframework.web.bind.annotation.PostMapping;
2import org.springframework.web.bind.annotation.RequestBody;
3import org.springframework.web.bind.annotation.RestController;
4
5@RestController
6public class StockPriceController {
7 private final StockPriceService stockPriceService;
8
9 @Autowired
10 public StockPriceController(StockPriceService stockPriceService) {
11 this.stockPriceService = stockPriceService;
12 }
13
14 @PostMapping("/update-price")
15 public void updatePrice(@RequestBody StockPriceUpdateRequest request) {
16 stockPriceService.updatePrice(request.getSymbol(), request.getPrice());
17 }
18}
19
20class StockPriceUpdateRequest {
21 private String symbol;
22 private double price;
23
24 // Getters and setters
25}
消息队列消费者
定义一个消费者来处理从RabbitMQ接收到的消息,并发送电子邮件通知订阅者:
java
深色版本
1import org.springframework.amqp.rabbit.annotation.RabbitListener;
2import org.springframework.stereotype.Component;
3
4@Component
5public class NotificationConsumer {
6 @RabbitListener(queues = "stock-price-updates")
7 public void receiveNotification(String message) {
8 System.out.println("Received notification: " + message);
9 // Here you can add code to send an email or other notifications
10 }
11}
测试
最后,我们可以编写一个简单的测试来验证系统的功能:
java
深色版本
1import org.junit.jupiter.api.Test;
2import org.springframework.beans.factory.annotation.Autowired;
3import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
4import org.springframework.boot.test.context.SpringBootTest;
5import org.springframework.test.web.servlet.MockMvc;
6
7import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
8import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
9
10@SpringBootTest
11@AutoConfigureMockMvc
12public class StockPriceControllerTest {
13 @Autowired
14 private MockMvc mockMvc;
15
16 @Test
17 public void testUpdatePrice() throws Exception {
18 mockMvc.perform(post("/update-price")
19 .content("{\"symbol\": \"AAPL\", \"price\": 150.0}")
20 .contentType("application/json"))
21 .andExpect(status().isOk());
22 }
23}
以上就是整个股票价格更新系统的设计和实现过程。你可以根据实际需求进一步扩展和完善这个系统,例如增加安全性、异常处理、更复杂的业务逻辑等。
版权归原作者 潘多编程 所有, 如有侵权,请联系我们删除。