当前位置: 首页 > news >正文

Flask vs Spring Boot + Vue 对比与核心流程

🔄 技术栈对比

方面 Java Spring Boot Python Flask Vue.js

类型 全功能企业级框架 微型Web框架 前端框架

核心思想 约定大于配置,依赖注入 极简主义,可扩展 组件化,响应式

学习曲线 较陡峭 平缓 中等

项目初始化 Spring Initializr 或 Maven/Gradle pip install + 手动创建 Vue CLI

路由定义 @RestController + @GetMapping @app.route() 装饰器 Vue Router

模板引擎 Thymeleaf(可不用) Jinja2(可不用) 单文件组件

数据库ORM Spring Data JPA (Hibernate) SQLAlchemy 或 原生SQL 无

认证授权 Spring Security Flask-Login/JWT 扩展 前端路由守卫

配置文件 application.properties/yml config.py 或 环境变量 -

🎯 Flask 核心机制(类比 Spring Boot)

  1. 控制反转(IoC)对比

Flask - 显式依赖注入

from flask import Flask
app = Flask(name) # 创建应用实例

Spring Boot - 隐式依赖注入

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

  1. 路由映射对比

Flask 路由

@app.route('/users', methods=['GET'])
def get_users():
return jsonify(users)

@app.route('/users/int:user_id', methods=['GET'])
def get_user(user_id):
return jsonify(user)

Spring Boot 控制器

@RestController
@RequestMapping("/users")
public class UserController {

@GetMapping
public List<User> getUsers() {return userService.findAll();
}@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {return userService.findById(id);
}

}

  1. 请求/响应处理对比

Flask 获取请求数据

from flask import request, jsonify

@app.route('/login', methods=['POST'])
def login():
# 获取JSON数据
data = request.get_json()
username = data.get('username')
password = data.get('password')

# 返回JSON响应
return jsonify({'token': 'jwt_token','user': {'username': username}
})

Spring Boot

@PostMapping("/login")
public ResponseEntity login(@RequestBody LoginRequest request) {
// 处理逻辑
return ResponseEntity.ok(response);
}

🏃♂️ 最简 Flask 前后端分离示例

项目结构

flask-vue-demo/
├── backend/
│ ├── app.py # Flask应用
│ └── requirements.txt
└── frontend/
├── index.html # Vue单页面
└── app.js

第一步:创建最简单的 Flask 后端

backend/app.py

from flask import Flask, jsonify, request
from flask_cors import CORS # 解决跨域问题

1. 创建Flask应用 - 类似Spring Boot的@SpringBootApplication

app = Flask(name)
CORS(app) # 允许所有跨域请求(开发环境)

内存存储(替代数据库)

todos = [
{"id": 1, "title": "学习Flask", "completed": False},
{"id": 2, "title": "写代码", "completed": True}
]

2. 定义路由 - 类似Spring的@RestController

@app.route('/api/todos', methods=['GET'])
def get_todos():
"""获取所有待办事项 - GET /api/todos"""
return jsonify({
'code': 200,
'data': todos,
'message': 'success'
})

@app.route('/api/todos', methods=['POST'])
def create_todo():
"""创建待办事项 - POST /api/todos"""
data = request.get_json() # 获取请求体JSON

# 简单验证
if not data or 'title' not in data:return jsonify({'error': '缺少title字段'}), 400# 创建新todo
new_todo = {'id': len(todos) + 1,'title': data['title'],'completed': data.get('completed', False)
}todos.append(new_todo)return jsonify({'code': 201,'data': new_todo,'message': '创建成功'
}), 201

@app.route('/api/todos/int:todo_id', methods=['PUT'])
def update_todo(todo_id):
"""更新待办事项 - PUT /api/todos/:id"""
data = request.get_json()

# 查找todo
todo = next((t for t in todos if t['id'] == todo_id), None)
if not todo:return jsonify({'error': 'Todo不存在'}), 404# 更新字段
if 'title' in data:todo['title'] = data['title']
if 'completed' in data:todo['completed'] = data['completed']return jsonify({'code': 200,'data': todo,'message': '更新成功'
})

@app.route('/api/todos/int:todo_id', methods=['DELETE'])
def delete_todo(todo_id):
"""删除待办事项 - DELETE /api/todos/:id"""
global todos

# 过滤掉要删除的todo
original_count = len(todos)
todos = [t for t in todos if t['id'] != todo_id]if len(todos) == original_count:return jsonify({'error': 'Todo不存在'}), 404return jsonify({'code': 200,'message': '删除成功'
})

3. 启动应用

if name == 'main':
print("✅ Flask后端启动: http://localhost:5000")
print("📋 API接口列表:")
print(" GET /api/todos - 获取所有待办")
print(" POST /api/todos - 创建待办")
print(" PUT /api/todos/ - 更新待办")
print(" DELETE /api/todos/ - 删除待办")

app.run(debug=True, port=5000)

backend/requirements.txt

flask3.0.0
flask-cors
4.0.0

第二步:创建最简单的 Vue 前端

Flask + Vue Todo

📝 Todo 列表

    <!-- 添加表单 --><div class="add-form"><input v-model="newTodo" @keyup.enter="addTodo" placeholder="输入待办事项..."><button @click="addTodo">添加</button></div><!-- 加载状态 --><div v-if="loading">加载中...</div><!-- 待办列表 --><ul class="todo-list" v-else><li v-for="todo in todos" :key="todo.id" class="todo-item":class="{ completed: todo.completed }"><span>{{ todo.title }}</span><div class="todo-actions"><button class="btn-success"@click="toggleTodo(todo.id)">{{ todo.completed ? '未完成' : '完成' }}</button><button class="btn-danger"@click="deleteTodo(todo.id)">删除</button></div></li></ul><!-- 空状态 --><div v-if="todos.length === 0 && !loading">暂无待办事项</div>
</div><script src="app.js"></script>

// frontend/app.js
// Vue 3 应用
const { createApp, ref, onMounted } = Vue;

createApp({
setup() {
// 1. 响应式数据 - 类似Vue 2的data()
const todos = ref([]);
const newTodo = ref('');
const loading = ref(false);
const API_URL = 'http://localhost:5000/api/todos';

    // 2. 方法 - 类似Vue 2的methodsconst fetchTodos = async () => {loading.value = true;try {const response = await fetch(API_URL);const result = await response.json();if (result.code === 200) {todos.value = result.data;}} catch (error) {console.error('获取数据失败:', error);} finally {loading.value = false;}};const addTodo = async () => {if (!newTodo.value.trim()) return;try {const response = await fetch(API_URL, {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ title: newTodo.value })});if (response.ok) {newTodo.value = '';await fetchTodos(); // 重新获取列表}} catch (error) {console.error('添加失败:', error);}};const toggleTodo = async (id) => {const todo = todos.value.find(t => t.id === id);if (!todo) return;try {await fetch(`${API_URL}/${id}`, {method: 'PUT',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ completed: !todo.completed })});await fetchTodos();} catch (error) {console.error('更新失败:', error);}};const deleteTodo = async (id) => {if (!confirm('确定删除吗?')) return;try {await fetch(`${API_URL}/${id}`, { method: 'DELETE' });await fetchTodos();} catch (error) {console.error('删除失败:', error);}};// 3. 生命周期钩子 - 类似Vue 2的mounted()onMounted(() => {console.log('✅ 前端应用已启动');fetchTodos();});// 4. 返回模板中需要使用的数据和方法return {todos,newTodo,loading,addTodo,toggleTodo,deleteTodo};
}

}).mount('#app');

🚀 运行步骤

  1. 启动后端

1. 进入后端目录

cd backend

2. 创建虚拟环境(可选但推荐)

python -m venv venv

Windows: venv\Scripts\activate

Mac/Linux: source venv/bin/activate

3. 安装依赖

pip install -r requirements.txt

4. 运行Flask应用

python app.py

看到输出:

✅ Flask后端启动: http://localhost:5000
📋 API接口列表:
GET /api/todos - 获取所有待办
POST /api/todos - 创建待办
PUT /api/todos/ - 更新待办
DELETE /api/todos/ - 删除待办

  1. 启动前端

在前端目录,用任何HTTP服务器都可以

方法1: 用Python

cd frontend
python -m http.server 3000

方法2: 用Node.js的http-server

npx http-server

方法3: 直接用浏览器打开index.html(需要配置CORS或关闭浏览器安全限制)

访问 http://localhost:3000 或直接打开 frontend/index.html

🔧 核心流程解析

  1. 完整的数据流

前端 (Vue) 后端 (Flask)
| |
| 1. 用户点击"添加"按钮 |
| ↓ |
| 2. 调用 addTodo() 函数 |
| ↓ |
| 3. fetch(POST /api/todos) |
|---------------------------------->|
| | 4. @app.route接收请求
| | ↓
| | 5. request.get_json() 解析数据
| | ↓
| | 6. 处理业务逻辑
| | ↓
| | 7. return jsonify() 返回响应
|<----------------------------------|
| 8. 接收响应,处理结果 |
| ↓ |
| 9. fetchTodos() 重新获取最新数据 |
| ↓ |
| 10. 更新UI渲染 |

  1. 关键机制对比

依赖管理

Flask - pip + requirements.txt

类似Java的pom.xml或build.gradle

安装: pip install flask flask-cors

路由处理

Flask - 装饰器模式

@app.route('/path', methods=['GET', 'POST'])
def handler():
return response

Spring Boot - 注解模式

@GetMapping("/path")
public Response handler() {
return response;
}

请求处理

Flask - 全局request对象

data = request.get_json() # 获取JSON
param = request.args.get('q') # 查询参数
form = request.form.get('key') # 表单数据

Spring Boot - 注解参数

@PostMapping
public Response method(@RequestBody Data data,
@RequestParam String q) {
// ...
}

响应返回

Flask - 手动构造Response

return jsonify(data), 200 # JSON响应
return render_template('index.html') # HTML响应
return 'text', 404 # 文本+状态码

Spring Boot - 自动序列化

@ResponseBody // 或 @RestController
public Data method() {
return data; // 自动转为JSON
}

🎯 重点理解

  1. Flask的核心哲学

• 微框架:只提供核心功能,其他通过扩展添加

• 显式优于隐式:你需要明确配置每件事

• 灵活性:可以选择自己喜欢的组件

  1. 与Spring Boot的核心区别

特性 Flask Spring Boot

启动方式 直接运行Python文件 需要Tomcat/内嵌服务器

配置 Python代码配置 注解+配置文件

依赖注入 手动/Flask-Injector 核心功能,自动

AOP 装饰器/中间件 @Aspect注解

约定 几乎没有,自由组织 严格的目录结构

学习成本 低,Python基础即可 需要Java+Spring生态知识

  1. 适合场景

• Flask:快速原型、小型项目、微服务、数据科学API

• Spring Boot:企业级应用、大型系统、需要完整生态支持

📈 下一步扩展

  1. 添加数据库(SQLAlchemy)

from flask_sqlalchemy import SQLAlchemy

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todos.db'
db = SQLAlchemy(app)

class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200))
completed = db.Column(db.Boolean, default=False)

  1. 添加认证(JWT)

from flask_jwt_extended import JWTManager, create_access_token

app.config['JWT_SECRET_KEY'] = 'super-secret'
jwt = JWTManager(app)

@app.route('/login', methods=['POST'])
def login():
# 验证用户
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token)

  1. 使用蓝图(模块化)

类似Spring Boot的@Controller

from flask import Blueprint

todo_bp = Blueprint('todos', name)

@todo_bp.route('/todos')
def get_todos():
pass

app.register_blueprint(todo_bp, url_prefix='/api')

❓ 常见问题

Q1: Flask需要像Spring Boot那样分层吗?

A: 不强制,但推荐。常见分层:
• routes/(控制器层)

• models/(模型层)

• services/(服务层)

• utils/(工具类)

Q2: 如何调试?

1. Flask debug模式(自动重载)

app.run(debug=True)

2. 使用pdb(Python调试器)

import pdb; pdb.set_trace()

3. 日志

import logging
logging.basicConfig(level=logging.DEBUG)

Q3: 生产环境部署?

使用Gunicorn + Nginx

安装: pip install gunicorn

运行: gunicorn -w 4 -b 0.0.0.0:5000 app:app

这个最小示例涵盖了Flask前后端分离的核心流程。从Java+Spring Boot转过来,关键要理解:

  1. Flask更轻量,更手动
  2. Python语法更简洁
  3. 核心思想一样:接收请求 → 处理业务 → 返回响应
http://www.jsqmd.com/news/633676/

相关文章:

  • CrewAI多Agent协作实战:构建自动化AI工作流
  • League Akari:基于LCU API的3大英雄联盟客户端增强方案
  • 漫谈江澄实验室科技(无锡),市场影响力、服务质量与员工满意度如何 - 工业品网
  • 探讨靠谱的锁具技工正规备案培训服务,怎么选择心中有数 - 工业品牌热点
  • 终极指南:如何用Universal x86 Tuning Utility免费释放AMD/Intel硬件全部性能
  • 别再只用Set5了!超分辨率炼丹师必知的7个数据集(含DIV2K、Urban100)下载与使用避坑指南
  • 北京海斯居科技有限公司:丰台区甲醛治理公司 - LYL仔仔
  • ccmusic-database在中小音乐厂牌的应用:低成本流派标注替代人工方案
  • 天猫超市购物卡回收,这样做更划算! - 团团收购物卡回收
  • YOLC:基于高分辨率热图与自适应聚类的航拍小目标检测新范式
  • 探讨口碑好的专业宠物美容培训机构,选哪家比较靠谱 - 工业推荐榜
  • STM32F334双通道ADC+DMA实战:从CubeMX配置到数据采集全流程(附避坑指南)
  • FPGA矩阵转置优化:基于FIFO与ROM的高效地址映射实现
  • Element-Plus用户迁移指南:从el-tree到vxeTree的5个必知差异点(附转换工具)
  • 讲讲靠谱的DNC程序管理与传输系统供应商,怎么收费 - mypinpai
  • Neat Bookmarks:终极浏览器书签管理解决方案,告别混乱找回效率
  • 口碑好的CMA资质评审服务品牌盘点,解析评审时间和服务模式 - 工业品牌热点
  • 20252906 2025-2026-2 《网络攻防实践》第3周作业
  • 引言:从中心化到去中心化——互联网存储的范式革命
  • Phi-3-mini-4k-instruct-gguf部署案例:Airflow中集成Phi-3-mini实现定时摘要任务
  • Python网易云音乐下载终极指南:3步轻松保存高品质音乐库
  • 告别眼瞎!FullEventLogView实战:高效分析海量Windows安全日志(evtx文件)的保姆级技巧
  • 深聊个性化汽车零部件数字化改造方案,费用怎么收费 - myqiye
  • 剖析汽车脚垫知名品牌推荐,优质源头工厂揭秘,哪家口碑更好 - 工业设备
  • 闲置卡片焕发新生:华润万家购物卡回收的合规之路与价值解析 - 京回收小程序
  • 详细的注释和多客户端支持的C++ SOCKET同步阻塞与异步非阻塞通信代码示例
  • M62429音量控制芯片全解析:从数据手册到GD32F330C8T6实战应用
  • 通达信缠论插件终极指南:3步实现专业级K线分析可视化
  • 逆向分析新姿势:用VMOSPro虚拟环境绕过APP证书校验(小黄鸟抓包+XP框架联动教程)
  • 密码学在工程中的应用:非对称加密如何保护数据传输