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}

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

相关推荐
customer082 分钟前
【开源免费】基于SpringBoot+Vue.JS在线视频教育平台(JAVA毕业设计)
java·jvm·vue.js·spring boot·spring cloud·java-ee·intellij-idea
技术无疆5 分钟前
TitleBar:打造高效Android标题栏的新选择
android·java·ui·android studio·android-studio
青龙摄影14 分钟前
【自动化】BB自动化获取视频和音频地址并下载
java·python
Y雨何时停T16 分钟前
Java中的深拷贝与浅拷贝详解
java
纵横君=_=22 分钟前
Day7 | Java框架 | SpringMVC
java·开发语言
艾伦~耶格尔39 分钟前
常用Java API
java·开发语言·学习
QX_Java_Learner40 分钟前
【Redis】缓存和数据库一致性问题及解决方案
数据库·redis·缓存
武子康40 分钟前
大数据-131 - Flink CEP 案例:检测交易活跃用户、超时未交付
java·大数据·flink·spark·scala
请叫我江同学呀1 小时前
关于elasticsearch的terms查询超过最大terms数
数据库·elasticsearch·搜索引擎·es·非关系型数据库
LazySideny1 小时前
Maven创建项目中的groupId, artifactId, 和 version的意思
java·maven