Spring Boot 应用案例:打造股票价格自动通知平台

在本篇博文中,我们将构建一个简单的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}

以上就是整个股票价格更新系统的设计和实现过程。你可以根据实际需求进一步扩展和完善这个系统,例如增加安全性、异常处理、更复杂的业务逻辑等。

相关推荐
xmh-sxh-13149 分钟前
jdk各个版本介绍
java
天天扭码28 分钟前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶29 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺33 分钟前
Spring Boot框架Starter组件整理
java·spring boot·后端
小曲程序40 分钟前
vue3 封装request请求
java·前端·typescript·vue
gma9991 小时前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️1 小时前
华为ASP与CSP是什么?
服务器·前端·数据库
陈王卜1 小时前
django+boostrap实现发布博客权限控制
java·前端·django
小码的头发丝、1 小时前
Spring Boot 注解
java·spring boot
午觉千万别睡过1 小时前
RuoYI分页不准确问题解决
spring boot