1. 项目背景与核心需求
在当今高校环境中,学生群体对于线上社交平台的需求日益增长。传统的社交软件往往无法满足校园场景下的特定需求,比如课程讨论、社团活动、学术交流等垂直领域的互动。这正是我们设计这款基于SpringBoot的交友平台的初衷——打造一个真正贴合大学生社交习惯的校园专属空间。
这个毕业设计项目的核心目标是通过技术手段解决三个实际问题:
- 为同校学生提供安全可靠的实名制交友渠道
- 实现基于兴趣标签的精准匹配功能
- 构建包含即时通讯、动态分享的完整社交生态
从技术实现角度看,项目需要平衡毕业设计的教学要求与实际应用的可行性。这意味着在技术选型上既要展示学生对主流框架的掌握程度,又要确保系统具备真实可运行的完整功能链路。
2. 技术架构设计解析
2.1 整体技术栈选型
项目采用经典的SpringBoot全家桶技术组合:
- 核心框架:SpringBoot 2.7.x(兼顾稳定性和新特性)
- 数据持久层:MyBatis-Plus + MySQL 8.0
- 前端展示层:Thymeleaf + Bootstrap 5
- 异步通信:WebSocket + STOMP协议
- 辅助工具:Lombok、Hutool、PageHelper
特别说明:没有选择前后端分离架构是考虑到毕业设计的完整性展示需求。Thymeleaf模板引擎可以让评审老师直接通过浏览器查看完整功能,避免额外部署前端服务的复杂度。
2.2 分层架构设计
系统采用典型的三层架构,但针对社交平台特性做了特殊强化:
code复制├── 表现层
│ ├── 传统MVC控制器
│ └── WebSocket消息处理器
├── 业务层
│ ├── 用户服务
│ ├── 匹配服务
│ └── 内容审核服务
└── 持久层
├── MyBatis-Plus通用Mapper
└── 自定义SQL仓库
其中最具特色的是双通道通信设计:
- HTTP请求处理常规CRUD操作
- WebSocket长连接处理即时消息和在线状态同步
3. 核心功能实现细节
3.1 用户匹配算法实现
交友平台的核心竞争力在于匹配算法的设计。考虑到毕业设计的实现复杂度,我们采用多维度加权评分模型:
java复制// 匹配得分计算示例
public BigDecimal calculateMatchScore(User user1, User user2) {
// 基础分:相同学院+20分
BigDecimal score = new BigDecimal(user1.getCollege().equals(user2.getCollege()) ? 20 : 0);
// 兴趣标签匹配:每个共同标签+5分
long commonTags = user1.getTags().stream()
.filter(tag -> user2.getTags().contains(tag))
.count();
score = score.add(BigDecimal.valueOf(commonTags * 5));
// 距离衰减因子:同校区*1.2,同城*1.0,异地*0.8
score = score.multiply(getLocationFactor(user1, user2));
return score.setScale(2, RoundingMode.HALF_UP);
}
实际项目中还应该考虑:
- 避免频繁计算的缓存策略(Redis)
- 分页查询优化(使用MyBatis-Plus的selectPage)
- 敏感词过滤(引入DFA算法)
3.2 即时通讯模块
基于WebSocket的实现需要注意三个关键问题:
- 会话管理:使用SimpUserRegistry跟踪在线用户
java复制@EventListener
public void handleWebSocketConnectListener(SessionConnectedEvent event) {
String username = event.getUser().getName();
onlineUsers.put(username, new UserStatus(true, LocalDateTime.now()));
}
- 消息持久化:采用写扩散模式存储消息
sql复制CREATE TABLE `chat_message` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`sender_id` BIGINT NOT NULL,
`receiver_id` BIGINT NOT NULL,
`content` TEXT NOT NULL,
`is_read` TINYINT(1) DEFAULT 0,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `idx_pair` (`sender_id`, `receiver_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 离线消息处理:通过定时任务检查未读消息
java复制@Scheduled(fixedRate = 300000)
public void checkOfflineMessages() {
List<Long> offlineUsers = userService.getOfflineUsers();
offlineUsers.forEach(userId -> {
List<ChatMessage> unread = messageService.getUnreadMessages(userId);
if (!unread.isEmpty()) {
emailService.sendMessageNotification(userId, unread.size());
}
});
}
4. 典型问题解决方案
4.1 跨域会话保持问题
在开发过程中遇到的最棘手问题是WebSocket会话与HTTP会话的同步问题。当用户通过HTTP登录后,WebSocket连接仍然提示未认证。解决方案是:
- 实现自定义HandshakeInterceptor
java复制@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Map<String, Object> attributes) {
// 从HTTP请求头获取token
String token = ((ServletServerHttpRequest) request).getServletRequest().getHeader("Authorization");
Authentication auth = tokenProvider.validateToken(token);
SecurityContextHolder.getContext().setAuthentication(auth);
return true;
}
- 配置StompEndpoint时添加拦截器
java复制registry.addEndpoint("/ws")
.setHandshakeHandler(new DefaultHandshakeHandler())
.addInterceptors(new AuthHandshakeInterceptor())
.withSockJS();
4.2 性能优化实践
在压力测试阶段发现的几个性能瓶颈及解决方案:
- N+1查询问题:
- 现象:获取用户列表时触发大量标签查询
- 解决:使用MyBatis-Plus的@TableField注解实现自动填充
java复制@TableField(typeHandler = JsonTypeHandler.class)
private List<String> tags;
- WebSocket消息堆积:
- 现象:高并发时消息延迟严重
- 解决:引入消息队列做削峰填谷
java复制@Bean
public Executor asyncMessageExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(1000);
executor.setThreadNamePrefix("MessageAsync-");
executor.initialize();
return executor;
}
5. 项目部署与测试
5.1 多环境配置方案
毕业设计需要演示本地开发和生产环境切换,采用SpringBoot的Profile机制:
yaml复制# application-dev.yml
server:
port: 8080
datasource:
url: jdbc:mysql://localhost:3306/social_dev?useSSL=false
username: devuser
password: dev123
# application-prod.yml
server:
port: 80
datasource:
url: jdbc:mysql://prod-db:3306/social_prod?useSSL=true
username: ${DB_USER}
password: ${DB_PASS}
启动时通过VM参数指定环境:
bash复制java -jar social-platform.jar --spring.profiles.active=prod
5.2 自动化测试策略
虽然毕业设计对测试要求不高,但良好的测试实践能显著提升代码质量:
- Controller层测试:使用MockMvc模拟HTTP请求
java复制@Test
void testUserRegistration() throws Exception {
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"username\":\"test\",\"password\":\"123456\"}"))
.andExpect(status().isCreated());
}
- Service层测试:结合H2内存数据库
java复制@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
@Import({UserServiceImpl.class})
class UserServiceTest {
@Autowired
private UserRepository userRepo;
@Test
void shouldCreateUser() {
User user = new User("test", "123456");
User saved = userService.createUser(user);
assertNotNull(saved.getId());
}
}
6. 毕设答辩准备建议
基于这个项目的答辩需要特别注意三个要点:
- 技术亮点展示:
- WebSocket的双向通信机制
- 匹配算法的设计思路
- MyBatis-Plus的灵活应用
- 演示脚本设计:
markdown复制1. 用户注册(展示表单验证)
2. 完善资料(演示标签选择)
3. 查找好友(演示匹配算法)
4. 发送消息(展示实时通信)
5. 查看动态(演示内容审核)
- 常见问题准备:
-
Q:为什么不用Redis做缓存?
A:考虑到项目规模较小,MySQL查询性能已足够,但架构上预留了缓存层接口 -
Q:如何保证用户隐私?
A:采用手机号验证注册,敏感信息加密存储,通信内容端到端加密
这个项目源码已经整理成标准的Maven工程结构,包含完整的数据库脚本和示例数据。建议学弟学妹们在理解核心逻辑的基础上,可以尝试扩展以下方向:
- 引入Elasticsearch实现全文搜索
- 增加短视频分享功能
- 实现基于Spring Security的精细化权限控制
