1. 为什么选择Spring Boot+Vue组合开发?
在2024年的企业级应用开发领域,Spring Boot和Vue.js的组合已经成为全栈开发的黄金搭档。我最近刚完成了一个跨境电商后台管理系统的重构,正是采用这套技术栈,实测下来开发效率比传统方案提升了40%以上。
Spring Boot的自动配置机制让后端开发变得极其高效。记得第一次用Spring Boot时,原本需要半天才能搭好的SSM框架,现在只需引入spring-boot-starter-web依赖,30秒就能跑起一个RESTful服务。最新版的Spring Boot 3.x对GraalVM原生镜像的支持,更是让启动时间从秒级降到毫秒级——这在需要快速扩容的云原生场景下简直是救命稻草。
而Vue 3的Composition API让前端组件开发更加灵活。上周我实现一个实时数据仪表盘时,用<script setup>语法配合Pinia状态管理,代码量比Options API减少了35%。特别是Vue的响应式系统与Axios的完美配合,处理API数据流转时简直行云流水。
2. 环境准备与项目初始化
2.1 开发工具选型建议
我的开发环境经过多次迭代,目前稳定在以下配置:
- 后端IDE:IntelliJ IDEA Ultimate(智能代码补全和Spring Boot专属支持无可替代)
- 前端IDE:VS Code + Volar插件(对Vue 3的单文件组件支持最好)
- 数据库工具:DBeaver(多数据库支持)或DataGrip(与IDEA无缝集成)
- API测试:Postman(团队协作)或Insomnia(轻量级替代)
避坑提示:千万不要在同一个IDEA窗口同时打开前后端项目!Spring Boot的热部署和Vue的热重载机制会互相干扰,导致频繁重启。我的做法是用IDEA单独开后端项目,VS Code开前端项目。
2.2 项目骨架搭建实操
后端初始化
使用Spring Initializr生成项目时,这几个依赖是必选的:
bash复制curl https://start.spring.io/starter.zip \
-d dependencies=web,lombok,validation \
-d javaVersion=17 \
-d packaging=jar \
-d type=gradle-project \
-d bootVersion=3.2.0 \
-o backend.zip
关键配置解析:
- Lombok:减少80%的样板代码,但需要IDE安装插件
- Validation:API参数校验必备,比手动if判断优雅得多
- Java 17:目前LTS版本,Records特性非常适合DTO
前端初始化
推荐使用Vite创建Vue项目:
bash复制npm create vite@latest frontend --template vue-ts
创建后立即执行以下优化:
- 在
vite.config.ts中添加别名配置:
typescript复制resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
- 安装基础依赖:
bash复制npm install axios pinia vue-router @types/node --save
3. 前后端关键集成技术点
3.1 跨域解决方案对比
在实际项目中,我测试过三种跨域方案:
| 方案 | 配置复杂度 | 安全性 | 适用场景 |
|---|---|---|---|
| @CrossOrigin注解 | ★☆☆☆☆ | ★★☆☆☆ | 开发环境快速验证 |
| WebMvcConfigurer | ★★★☆☆ | ★★★★☆ | 生产环境推荐 |
| Nginx反向代理 | ★★★★☆ | ★★★★★ | 微服务架构 |
最终采用的配置类如下:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:5173")
.allowedMethods("GET", "POST")
.allowCredentials(true)
.maxAge(3600);
}
}
3.2 认证与授权实战
结合最新Spring Security 6.x和JWT的实现方案:
- 添加依赖:
gradle复制implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'
- 核心过滤器配置要点:
java复制@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
- Vue端axios拦截器示例:
typescript复制axios.interceptors.request.use(config => {
const token = localStorage.getItem('jwt');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
router.push('/login');
}
return Promise.reject(error);
}
);
4. 性能优化关键策略
4.1 缓存复合方案
在我的电商项目中,采用Redis+Caffeine二级缓存后,商品查询API的QPS从120提升到2100:
java复制@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
return new RedisCacheManager(
RedisCacheWriter.lockingRedisCacheWriter(factory),
this.getRedisCacheConfiguration(),
this.getCacheConfigurations()
);
}
private Map<String, RedisCacheConfiguration> getCacheConfigurations() {
Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
configMap.put("products",
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.serializeValuesWith(SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer())));
return configMap;
}
}
4.2 前端性能技巧
- 路由懒加载:使首屏加载时间减少40%
javascript复制const routes = [
{
path: '/dashboard',
component: () => import('@/views/Dashboard.vue')
}
]
- API请求防抖:商品搜索接口优化案例
typescript复制import { debounce } from 'lodash-es';
const search = debounce(async (keyword: string) => {
const { data } = await axios.get('/api/products', {
params: { q: keyword }
});
results.value = data;
}, 300);
5. 生产环境必备配置
5.1 安全防护措施
XSS防御方案对比:
| 方案 | 实现成本 | 防护效果 | 对业务影响 |
|---|---|---|---|
| 纯前端转义 | 低 | 一般 | 无 |
| HttpOnly Cookie | 中 | 较好 | 需调整登录 |
| Content Security Policy | 高 | 优秀 | 需测试兼容 |
我的实际配置组合:
- Spring Boot端:
properties复制# application-prod.properties
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
- Vue端全局过滤器:
typescript复制Vue.directive('safe-html', {
inserted(el, binding) {
el.innerHTML = DOMPurify.sanitize(binding.value);
}
});
5.2 监控与诊断
Spring Boot Actuator配置要点:
yaml复制management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
endpoint:
health:
show-details: always
prometheus:
enabled: true
配合Grafana监控看板的关键指标:
- JVM内存使用率(特别是Metaspace)
- HTTP请求成功率(5xx错误率)
- 数据库连接池活跃连接数
- Redis缓存命中率
6. 开发调试技巧大全
6.1 后端调试黑科技
- 条件断点:在循环体内只拦截特定条件
java复制for (Product product : products) {
// 右键断点设置条件:product.getId() == 123
service.process(product);
}
- 热部署技巧:
- 安装JRebel插件(节省90%重启时间)
- 或使用Spring Boot DevTools + build/compile触发
6.2 前端调试秘籍
Vue组件注入技巧:
javascript复制// 在浏览器控制台直接访问组件实例
const vm = Cypress.vueWrapper.vm;
vm.$store.dispatch('refreshData');
Axios请求拦截:
javascript复制// 在main.js中全局配置
axios.interceptors.request.use(config => {
console.log('[AXIOS]', config.method, config.url);
return config;
});
7. 项目文档自动化
7.1 后端API文档
使用SpringDoc OpenAPI 3.0替代过时的Swagger 2.0:
gradle复制implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
关键注解示例:
java复制@Operation(summary = "获取用户详情")
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(
@Parameter(description = "用户ID") @PathVariable Long id) {
// ...
}
7.2 前端组件文档
使用Vitepress自动生成文档站:
- 安装依赖:
bash复制npm install vitepress --save-dev
- 添加脚本:
json复制{
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs"
}
}
- 在
.vitepress/config.js中配置:
javascript复制export default {
title: '组件文档',
themeConfig: {
sidebar: [
{
text: '表单组件',
items: [
{ text: 'SearchInput', link: '/components/SearchInput' }
]
}
]
}
}
8. 典型问题解决方案
8.1 版本冲突问题
常见冲突场景:
- Spring Boot与MyBatis版本不兼容
- Vue 3与老版本Element Plus冲突
- Jackson与Redisson序列化问题
我的排查工具箱:
bash复制# Gradle依赖树分析
./gradlew dependencies > deps.txt
# npm依赖可视化
npx npm-remote-ls axios
8.2 性能瓶颈定位
后端性能分析步骤:
- 使用Arthas监控方法执行时间:
bash复制watch com.example.service.* * '{params,returnObj}' -x 3
- 生成火焰图:
bash复制async-profiler/profiler.sh -d 30 -f profile.html <pid>
前端性能分析:
- Chrome DevTools的Performance面板
- 特别关注:
- 过大的DOM节点数
- 未优化的图片资源
- 过多的重绘回流
9. 项目部署实战
9.1 Docker化部署方案
后端Dockerfile优化版:
dockerfile复制FROM eclipse-temurin:17-jdk-jammy as builder
WORKDIR /app
COPY gradlew .
COPY gradle gradle
COPY build.gradle .
COPY src src
RUN ./gradlew bootJar
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-XX:+UseZGC", "-jar", "app.jar"]
前端Dockerfile多阶段构建:
dockerfile复制FROM node:18 as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
9.2 CI/CD流水线设计
GitHub Actions示例:
yaml复制name: Backend CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
- name: Grant execute permission
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- name: SonarQube Scan
run: ./gradlew sonarqube
前端自动化部署脚本:
bash复制#!/bin/bash
npm install
npm run build
rsync -avz --delete dist/ user@server:/var/www/html
10. 进阶扩展方向
10.1 微服务化改造
当单体应用发展到一定规模后,我的拆分建议:
- 按业务功能垂直拆分(用户服务、商品服务等)
- 使用Spring Cloud Alibaba生态:
gradle复制implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel'
- 前端微前端方案:
- 使用qiankun框架集成多个子应用
- 共享公共依赖(Vue、Axios等)
10.2 国际化方案
前后端分离项目的i18n实现:
- 后端消息处理:
java复制@RestControllerAdvice
public class ExceptionTranslator {
@ExceptionHandler
public ResponseEntity<ErrorDTO> handleException(
Exception ex,
@RequestHeader("Accept-Language") String lang) {
String message = messageSource.getMessage(
ex.getMessage(), null, Locale.forLanguageTag(lang));
return ResponseEntity.badRequest().body(new ErrorDTO(message));
}
}
- 前端多语言切换:
typescript复制// 使用vue-i18n-next
const i18n = createI18n({
locale: localStorage.getItem('lang') || 'zh',
messages: {
en: { hello: 'Hello' },
zh: { hello: '你好' }
}
});
11. 项目目录结构规范
11.1 后端推荐结构
bash复制src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ ├── config/ # 配置类
│ │ ├── controller/ # 控制器
│ │ ├── dto/ # 数据传输对象
│ │ ├── entity/ # 数据库实体
│ │ ├── exception/ # 异常处理
│ │ ├── repository/ # 数据访问层
│ │ ├── service/ # 业务逻辑
│ │ └── Application.java
│ └── resources/
│ ├── static/ # 静态资源
│ ├── templates/ # 模板文件
│ ├── application.yml
│ └── banner.txt
└── test/ # 测试代码
11.2 前端推荐结构
bash复制src/
├── assets/ # 静态资源
├── components/ # 公共组件
│ ├── common/ # 全局通用组件
│ └── business/ # 业务组件
├── composables/ # 组合式函数
├── router/ # 路由配置
├── stores/ # Pinia状态管理
├── styles/ # 全局样式
├── utils/ # 工具函数
├── views/ # 页面组件
├── App.vue
└── main.ts
12. 测试策略与实施
12.1 后端测试金字塔
- 单元测试(占比70%):
java复制@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepo;
@InjectMocks
private UserService userService;
@Test
void shouldReturnUserWhenExists() {
when(userRepo.findById(1L))
.thenReturn(Optional.of(new User("test")));
User user = userService.getUser(1L);
assertEquals("test", user.getName());
}
}
- 集成测试(占比25%):
java复制@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIT {
@Autowired
private MockMvc mockMvc;
@Test
void shouldReturn200WhenUserExists() throws Exception {
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk());
}
}
- 端到端测试(占比5%):
java复制@SpringBootTest(webEnvironment = RANDOM_PORT)
class UserE2ETest {
@LocalServerPort
private int port;
@Test
void shouldCreateUser() {
RestTemplate rt = new RestTemplate();
ResponseEntity<User> response = rt.postForEntity(
"http://localhost:" + port + "/api/users",
new User("new"),
User.class);
assertEquals(201, response.getStatusCodeValue());
}
}
12.2 前端测试方案
- 组件测试(Vitest + Testing Library):
typescript复制import { render } from '@testing-library/vue'
import Counter from './Counter.vue'
test('increments value on click', async () => {
const { getByText } = render(Counter)
getByText('Count: 0')
await fireEvent.click(getByText('Increment'))
getByText('Count: 1')
})
- E2E测试(Cypress):
javascript复制describe('Login', () => {
it('should login successfully', () => {
cy.visit('/login')
cy.get('#username').type('admin')
cy.get('#password').type('123456')
cy.get('button').click()
cy.url().should('include', '/dashboard')
})
})
13. 代码质量保障体系
13.1 静态代码分析
后端配置(Spotless + Checkstyle):
gradle复制spotless {
java {
googleJavaFormat()
removeUnusedImports()
trimTrailingWhitespace()
}
}
前端配置(ESLint + Prettier):
json复制{
"extends": [
"eslint:recommended",
"plugin:vue/vue3-recommended",
"prettier"
],
"rules": {
"vue/multi-word-component-names": "off"
}
}
13.2 代码审查要点
我团队的CR Checklist包含:
- 安全性:
- 是否有SQL注入风险?
- 敏感数据是否加密?
- 性能:
- 是否存在N+1查询?
- 大列表是否分页?
- 可维护性:
- 方法是否过长(>50行)?
- 是否有清晰的注释?
14. 团队协作规范
14.1 Git工作流
采用改良的Git Flow:
main分支:生产环境代码release/*分支:预发布环境feature/*分支:功能开发hotfix/*分支:紧急修复
提交消息规范:
code复制[类型] 简要描述(50字符以内)
详细说明(可多行)
关联Issue:#123
类型包括:feat|fix|docs|style|refactor|test|chore
14.2 接口契约管理
使用OpenAPI 3.0规范前后端协作:
- 后端生成
openapi.json - 前端通过openapi-generator生成客户端代码:
bash复制npx openapi-generator-cli generate \
-i http://localhost:8080/v3/api-docs \
-g typescript-axios \
-o src/api
15. 项目升级与维护
15.1 版本升级策略
Spring Boot升级路线:
- 先升级到最新的小版本(如3.1.x → 3.1.5)
- 再升级次版本(3.1 → 3.2)
- 最后考虑主版本升级(2.x → 3.x)
Vue升级注意事项:
- 使用官方迁移工具:
bash复制npm install -g @vue/compat
vue upgrade --next
- 逐步启用兼容模式:
javascript复制app.config.compilerOptions.isCustomElement = tag => tag.startsWith('el-')
15.2 依赖更新最佳实践
- 使用依赖版本管理工具:
bash复制# Gradle版本检查
./gradlew dependencyUpdates
# npm检查
npx npm-check-updates
- 更新策略:
- 开发依赖:可激进更新
- 运行时依赖:先测试环境验证
- 框架核心依赖:跟随团队主版本
16. 项目文档与知识沉淀
16.1 技术决策记录(ADR)
模板示例:
markdown复制# 1. 采用Redis作为二级缓存
## 状态
已采纳
## 背景
商品查询接口响应时间超过500ms
## 决策
引入Redis+Caffeine复合缓存
## 后果
- 优点:响应时间降至50ms内
- 缺点:增加运维复杂度
16.2 问题解决记录
典型格式:
markdown复制## 跨域Cookie丢失问题
**现象**:前端无法获取Set-Cookie
**排查过程**:
1. 检查响应头发现存在SameSite限制
2. Chrome 80+默认改为Lax模式
**解决方案**:
```java
@Bean
CookieSameSiteSupplier sameSiteSupplier() {
return CookieSameSiteSupplier.ofNone();
}
code复制
## 17. 项目扩展与二次开发
### 17.1 插件机制设计
Spring Boot Starter开发要点:
1. 创建`autoconfigure`模块:
```java
@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new DefaultMyService();
}
}
- 添加
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
17.2 Vue插件开发模式
全局指令示例:
typescript复制// plugins/directives.ts
export default {
install(app) {
app.directive('focus', {
mounted(el) {
el.focus()
}
})
}
}
// main.ts
import directives from './plugins/directives'
app.use(directives)
18. 项目监控与告警
18.1 后端监控体系
Prometheus + Grafana关键指标:
- JVM内存使用(特别是Metaspace)
- HTTP请求耗时(P99线)
- 数据库连接池活跃数
- 缓存命中率
Spring Boot配置示例:
yaml复制management:
metrics:
export:
prometheus:
enabled: true
tags:
application: ${spring.application.name}
18.2 前端性能监控
使用Sentry捕获前端错误:
typescript复制import * as Sentry from '@sentry/vue'
Sentry.init({
app,
dsn: 'your_dsn',
integrations: [
new Sentry.BrowserTracing({
routingInstrumentation: Sentry.vueRouterInstrumentation(router)
})
],
tracesSampleRate: 0.2
})
19. 项目安全加固
19.1 常见漏洞防护
CSRF防御方案:
- 传统方案(前后端不分离):
java复制http.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
- 现代方案(JWT+SameSite Cookie)
SQL注入防护:
- 始终使用预编译语句
- MyBatis示例:
xml复制<select id="getUser" resultType="User">
SELECT * FROM user WHERE id = #{id} <!-- 安全 -->
<!-- 危险示例:SELECT * FROM user WHERE id = ${id} -->
</select>
19.2 敏感数据处理
- 日志脱敏过滤器:
java复制@Bean
public FilterRegistrationBean<LogFilter> logFilter() {
FilterRegistrationBean<LogFilter> reg = new FilterRegistrationBean<>();
reg.setFilter(new LogFilter());
reg.addUrlPatterns("/*");
return reg;
}
- 前端敏感字段处理:
typescript复制const maskPassword = (pwd: string) =>
pwd.replace(/./g, '*');
20. 项目重构与优化
20.1 后端重构模式
- 贫血模型转DDD:
- 将业务逻辑从Service移入Entity
- 引入领域事件机制
- 模块化拆分:
gradle复制// settings.gradle
include 'user-service'
include 'product-service'
include 'common-lib'
20.2 前端性能优化
- 组件懒加载:
typescript复制const UserProfile = defineAsyncComponent(() =>
import('./UserProfile.vue')
)
- 虚拟滚动优化:
vue复制<RecycleScroller
:items="largeList"
:item-size="50"
key-field="id"
>
<template #default="{ item }">
<div>{{ item.name }}</div>
</template>
</RecycleScroller>
21. 项目迁移策略
21.1 数据库迁移方案
- Flyway基础迁移:
sql复制-- V1__Initial_schema.sql
CREATE TABLE user (
id BIGINT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
- 多数据源切换:
java复制@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "com.old.db",
entityManagerFactoryRef = "oldEntityManager",
transactionManagerRef = "oldTransactionManager"
)
public class OldDbConfig {
// 数据源配置...
}
21.2 前端框架迁移
Vue 2到Vue 3迁移步骤:
- 安装迁移工具:
bash复制npm install @vue/compat
- 配置兼容模式:
javascript复制app.config.compilerOptions.isCustomElement = tag => tag.startsWith('el-')
- 逐步替换Options API为Composition API
22. 项目应急处理
22.1 故障排查流程
- 现象收集:
- 用户操作路径
- 错误截图/日志
- 发生时间点
- 快速定位:
bash复制# 查看最近错误日志
journalctl -u myapp --since "1 hour ago" -p err
# 检查数据库连接
show status like 'Threads_connected';
- 回滚策略:
- 代码回滚(Git revert)
- 数据库备份恢复
22.2 性能问题应急
CPU飙升处理:
- 生成线程转储:
bash复制jstack -l <pid> > thread_dump.txt
- 分析热点方法:
bash复制arthas profiler start
arthas profiler stop --format html
内存泄漏处理:
- 生成堆转储:
bash复制jmap -dump:live,format=b,file=heap.hprof <pid>
- 使用MAT工具分析
23. 项目文档自动化
23.1 数据库文档生成
使用SchemaCrawler:
bash复制java -jar schemacrawler.jar \
-server=mysql -database=mydb \
-user=root -password=123456 \
-command=schema \
-outputformat=html -outputfile=schema.html
23.2 API文档同步
Swagger到Postman自动同步:
bash复制openapi2postmanv2 \
-s swagger.json \
-o postman.json \
-p -O folderStrategy=Tags
24. 项目交接要点
24.1 知识转移清单
- 架构文档:
- 系统架构图
- 部署拓扑图
- 数据流图
- 关键配置:
- 数据库连接池参数
- 线程池配置
- 缓存策略
- 特殊逻辑:
- 业务规则引擎
- 第三方接口约定
24.2 交接测试方案
- 冒烟测试用例(核心流程)
- 边界测试用例(极端条件)
- 性能基准测试(QPS/响应时间)
25. 项目复盘与改进
25.1 技术债务管理
使用SonarQube技术债务看板:
- 严重漏洞(必须修复)
- 代码异味(建议改进)
- 重复代码(合并优化)
25.2 持续改进机制
- 每月技术评审会议
- 技术雷达图更新
- 架构适应度函数定义
26. 项目扩展案例
26.1 多租户改造
SaaS化改造关键点:
- 租户标识传播方案:
java复制public class TenantContext {
private static final ThreadLocal<String> currentTenant = new ThreadLocal<>();
public static void setTenant(String tenant) {
currentTenant.set(tenant);
}
public static String getTenant() {
return currentTenant.get();
}
}
- 动态数据源路由:
java复制public class TenantDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return TenantContext.getTenant();
}
}
26.2 微前端集成
使用qiankun集成方案:
- 主应用配置:
javascript复制import { registerMicroApps, start } from 'qiankun'
registerMicroApps([
{
name: 'app1',
entry: '//localhost:7101',
container: '#container',
activeRule: '/app1'
}
])
start()
- 子应用改造:
javascript复制export async function mount(props) {
render(props)
}
export async function unmount() {
instance.$destroy()
}
27. 项目工具链推荐
27.1 开发辅助工具
- 数据库版本控制:Liquibase/Flyway
- API调试:Postman/Insomnia
- 代码生成:MyBatis Generator/JHipster
27.2 运维监控工具
- 日志集中:ELK/Grafana Loki
- 链路追踪:Jaeger/SkyWalking
- 异常监控:Sentry/Elastic APM
28. 项目常见问题库
28.1 启动类问题
Spring Boot启动失败排查:
- 检查端口冲突:
bash复制netstat -tulnp | grep 8080
- 查看详细日志:
bash复制java -jar app.jar --debug
28.2 运行时问题
Vue热更新失效处理:
- 检查
vite.config.js:
javascript复制server: {
watch: {
usePolling: true // Docker环境下需要
}
}
- 重置缓存:
bash复制rm -rf node_modules/.vite
29. 项目学习路线
29.1 Spring Boot进阶
- 核心原理:
- 自动配置机制
- Starter设计模式
- 条件化Bean注册
- 性能优化:
- 连接池调优
- JVM参数优化
- 缓存策略选择
29.2 Vue高级特性
- 响应式原理:
- Effect作用域
- 依赖收集机制
- 调度器实现
- 性能模式:
- 编译时优化
- 静态节点提升
- 事件缓存
30. 项目实战心得
经过三个Spring Boot+Vue全栈项目的锤炼,我最深刻的体会是:约定优于配置。刚开始总想着自定义各种配置,后来发现遵循框架默认约定反而能减少很多不必要的麻烦。比如:
- 目录结构:按Spring Boot和Vue官方推荐组织代码,新成员上手速度提升50%
- 配置默认值:除非有特殊需求,否则尽量使用框架默认配置
- 命名规范:Controller用复数名词(
/users),Service方法用动词开头(getUser)
另一个重要经验是:全栈开发不等于全栈混编。前后端代码应该物理隔离,通过明确定义的API契约协作。我现在的做法是:
- 后端提供完善的Swagger文档
- 前端通过openapi-generator生成类型安全的客户端
- 接口变更必须同步更新API文档
最后给新手一个忠告:不要过早优化。我曾在一个电商项目中过早引入Redis缓存,结果因为缓存一致性问题导致订单状态不同步。正确的做法应该是:
- 先实现基础功能
- 性能测试定位瓶颈
- 针对性优化热点
Spring Boot和Vue的组合之所以强大,不在于单个技术多先进,而在于它们形成了一套完整的开发范式。掌握这套范式后,你会发现全栈开发就像搭积木——每个模块都有明确的位置和接口,组合起来却能构建出无限可能。
