08-Java工程师的Python第八课-框架入门

Flask/Django vs Spring:Python Web开发快速上手

摘要:Java有Spring,Python有Flask和Django。本文对比三种框架的设计理念和入门路径。


写在前面

作为一个Java工程师,你一定对Spring Boot的"约定优于配置"印象深刻。Python的Web框架同样遵循这一理念,但实现方式不同。

Spring强调"全功能、企业级",Flask强调"微框架、灵活扩展",Django强调"全功能、敏捷开发"。


一、框架生态对比

1.1 Java的Spring帝国

scss 复制代码
Spring Boot
├── Spring MVC (Web层)
├── Spring Data (数据层)
├── Spring Security (安全)
├── Spring Cloud (微服务)
└── ... (无数子项目)

Spring Boot的核心优势:

  • 自动配置(Auto Configuration)
  • 起步依赖(Starter Dependencies)
  • 嵌入式服务器
  • 生产级特性(Actuator、Metrics)

1.2 Python的框架生态

bash 复制代码
Python Web框架
├── Django       # 全功能框架
│   ├── ORM
│   ├── Admin
│   ├── Templates
│   └── Auth
├── Flask        # 微框架
│   ├── 核心
│   └── 扩展(Flask-SQLAlchemy, Flask-Login等)
├── FastAPI     # 现代异步框架
│   ├── 自动文档
│   ├── 类型提示
│   └── 异步支持
└── Pyramid     # 介于两者之间

二、Flask:微框架的典范

2.1 核心概念对比

Spring Boot Flask
@RestController @app.route()
@RequestMapping app.route()
@PathVariable <variable_name>
@RequestParam request.args.get()
@RequestBody request.get_json()
返回对象/JSON return jsonify(data)

2.2 最小应用

java 复制代码
// Spring Boot
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@RestController
@RequestMapping("/api")
public class UserController {
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
}
python 复制代码
# Flask
from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route("/api/users/<int:id>")
def get_user(id):
    user = user_service.find_by_id(id)
    return jsonify(user)

if __name__ == "__main__":
    app.run(debug=True)

2.3 请求处理对比

java 复制代码
// Spring Boot - 完整示例
@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }

    @PostMapping
    public User createUser(@RequestBody @Valid UserRequest request) {
        return userService.create(request);
    }

    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id,
                          @RequestBody UserRequest request) {
        return userService.update(id, request);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }

    @GetMapping
    public List<User> listUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return userService.findAll(page, size);
    }
}
python 复制代码
# Flask - 完整示例
from flask import Flask, jsonify, request
from flask.views import MethodView

app = Flask(__name__)

class UserView(MethodView):
    def get(self, user_id=None):
        if user_id is None:
            page = request.args.get("page", 0, type=int)
            size = request.args.get("size", 10, type=int)
            return jsonify(user_service.find_all(page, size))
        return jsonify(user_service.find_by_id(user_id))

    def post(self):
        data = request.get_json()
        return jsonify(user_service.create(data)), 201

    def put(self, user_id):
        data = request.get_json()
        return jsonify(user_service.update(user_id, data))

    def delete(self, user_id):
        user_service.delete(user_id)
        return "", 204

# 注册路由
app.add_url_rule("/api/users", view_func=UserView.as_view("users"))
app.add_url_rule("/api/users/<int:user_id>", view_func=UserView.as_view("user"))

三、Django:全功能框架

3.1 Django vs Spring Boot

概念 Django Spring Boot
项目结构 django-admin startproject spring initializr
应用 App Module/Component
ORM Django ORM JPA/Hibernate
路由 urls.py @RequestMapping
视图 FBV / Class-based Controller
模板 Django Template Thymeleaf/Freemarker
Admin 内置Admin站点 Spring Admin
配置 settings.py application.yml

3.2 Django项目结构

bash 复制代码
myproject/
├── manage.py              # Django CLI工具
├── myproject/
│   ├── __init__.py
│   ├── settings.py         # 配置文件
│   ├── urls.py             # 根路由
│   ├── wsgi.py             # WSGI入口
│   └── asgi.py             # ASGI入口
└── myapp/
    ├── __init__.py
    ├── models.py           # 数据模型
    ├── views.py            # 视图
    ├── urls.py             # 应用路由
    ├── admin.py            # Admin配置
    └── migrations/         # 数据库迁移

3.3 Django ORM vs JPA

java 复制代码
// Spring Data JPA
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(unique = true)
    private String email;

    private Integer age;

    @ManyToMany
    @JoinTable(name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;
}

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByAgeGreaterThan(int age);
    Optional<User> findByEmail(String email);
    @Query("SELECT u FROM User u WHERE u.name LIKE %:name%")
    List<User> searchByName(@Param("name") String name);
}
python 复制代码
# Django ORM
from django.db import models

class User(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    age = models.IntegerField(null=True, blank=True)
    roles = models.ManyToManyField("Role", through="UserRole")

    class Meta:
        db_table = "users"

    def __str__(self):
        return self.name

# 查询
User.objects.all()
User.objects.filter(age__gt=18)
User.objects.get(email="alice@example.com")
User.objects.filter(name__contains="Alice")

3.4 Django REST Framework

java 复制代码
// Spring Data REST + Jackson
@Entity
public class User {
    @Id @GeneratedValue
    private Long id;
    private String name;
    private String email;
}

@RestRepositoryResource
public interface UserRepository extends JpaRepository<User, Long> {
}
python 复制代码
# Django REST Framework
from rest_framework import serializers, viewsets

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "name", "email"]

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

# 自动生成CRUD + 列表 + 分页 + 过滤 + 搜索
# API文档:http://localhost:8000/docs/

四、FastAPI:现代异步框架

4.1 概念对比

Spring FastAPI
@RestController @app.get/post/put/delete()
@RequestBody Pydantic Model
CompletableFuture async/await
@Async async def
Spring Doc (OpenAPI) 自动生成
WebFlux 原生异步

4.2 FastAPI示例

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

class User(BaseModel):
    name: str
    email: str
    age: Optional[int] = None

class UserResponse(BaseModel):
    id: int
    name: str
    email: str

users_db = []

@app.post("/users", response_model=UserResponse)
async def create_user(user: User):
    new_user = UserResponse(
        id=len(users_db) + 1,
        name=user.name,
        email=user.email
    )
    users_db.append(new_user)
    return new_user

@app.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int):
    return users_db[user_id - 1]

@app.get("/users")
async def list_users(skip: int = 0, limit: int = 10):
    return users_db[skip:skip+limit]

FastAPI自动:

  • 生成OpenAPI文档:/docs(Swagger UI)或 /redoc
  • 验证请求数据(Pydantic)
  • 生成响应数据
  • 支持异步

五、中间件与拦截器

5.1 Java过滤器/拦截器

java 复制代码
// Spring Boot 过滤器
@Component
@Order(1)
public class LoggingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request,
                        ServletResponse response,
                        FilterChain chain)
            throws IOException, ServletException {
        long start = System.currentTimeMillis();
        chain.doFilter(request, response);
        log.info("耗时: {}ms", System.currentTimeMillis() - start);
    }
}

// 拦截器
@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler) {
        String token = request.getHeader("Authorization");
        if (!isValid(token)) {
            response.setStatus(401);
            return false;
        }
        return true;
    }
}

5.2 Flask中间件

python 复制代码
# Flask 装饰器实现
from functools import wraps
import time

def log_request(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"耗时: {time.time() - start:.2f}ms")
        return result
    return wrapper

@app.route("/api/users")
@log_request
def get_users():
    return jsonify(users)

# Flask 中间件(WSGI级别)
def middleware(app):
    def logMiddleware(environ, start_response):
        # 请求前处理
        response = app(environ, start_response)
        # 响应后处理
        return response
    return logMiddleware

5.3 Django中间件

python 复制代码
# Django 中间件
class LoggingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        start = time.time()
        response = self.get_response(request)
        duration = time.time() - start
        print(f"请求 {request.path} 耗时 {duration:.2f}ms")
        return response

# settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.common.CommonMiddleware',
    'myapp.middleware.LoggingMiddleware',
]

六、依赖注入对比

6.1 Java Spring DI

java 复制代码
@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User findById(Long id) {
        return userRepository.findById(id).orElseThrow();
    }
}

@RestController
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

6.2 Flask依赖注入

python 复制代码
# Flask 手动DI
class UserService:
    def __init__(self, repository):
        self.repository = repository

    def find_by_id(self, user_id):
        return self.repository.find_by_id(user_id)

# 手动组装
user_repository = UserRepository()
user_service = UserService(user_repository)
user_controller = UserController(user_service)

# Flask-Injector(可选)
from flask_injector import FlaskInjector

FlaskInjector(app=app, modules=[UserModule])

6.3 FastAPI依赖注入

python 复制代码
# FastAPI 内置依赖注入
from fastapi import Depends

def get_user_repository():
    return UserRepository()

@app.post("/users")
async def create_user(
    user: User,
    repo: UserRepository = Depends(get_user_repository)
):
    return repo.create(user)

# 带缓存的依赖
from functools import lru_cache

@lru_cache()
def get_settings():
    return Settings()

七、错误处理对比

7.1 Spring全局异常

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public Result handleBusiness(BusinessException e) {
        return Result.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValidation(MethodArgumentNotValidException e) {
        String msg = e.getBindingResult().getFieldErrors()
            .stream()
            .map(FieldError::getDefaultMessage)
            .collect(Collectors.joining(", "));
        return Result.error("VALIDATION_ERROR", msg);
    }
}

7.2 Flask错误处理

python 复制代码
from flask import jsonify

@app.errorhandler(BusinessException)
def handle_business(e):
    return jsonify({"code": e.code, "message": e.message}), 400

@app.errorhandler(ValidationError)
def handle_validation(e):
    return jsonify({"code": "VALIDATION_ERROR", "message": str(e)}), 400

@app.errorhandler(404)
def not_found(e):
    return jsonify({"code": "NOT_FOUND", "message": "资源不存在"}), 404

# FastAPI 更简洁
from fastapi import HTTPException

@app.get("/users/{user_id}")
async def get_user(user_id: int):
    user = find_user(user_id)
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    return user

八、测试对比

8.1 Spring Boot测试

java 复制代码
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    public void testGetUser() throws Exception {
        when(userService.findById(1L))
            .thenReturn(new User("Alice", "alice@example.com"));

        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.name").value("Alice"))
            .andExpect(jsonPath("$.email").value("alice@example.com"));
    }
}

8.2 Flask测试

python 复制代码
import pytest
from flask import Flask

@pytest.fixture
def app():
    app = Flask(__name__)
    app.config["TESTING"] = True

    @app.route("/users/<int:user_id>")
    def get_user(user_id):
        user = user_service.find_by_id(user_id)
        return jsonify(user)

    return app

@pytest.fixture
def client(app):
    return app.test_client()

def test_get_user(monkeypatch):
    def mock_find_by_id(user_id):
        return {"id": user_id, "name": "Alice", "email": "alice@example.com"}

    monkeypatch.setattr(user_service, "find_by_id", mock_find_by_id)

    response = client.get("/users/1")
    assert response.status_code == 200
    assert response.json["name"] == "Alice"

九、项目结构最佳实践

9.1 Java vs Python项目结构对比

java 复制代码
// Java Spring Boot 标准结构
my-spring-project/
├── pom.xml                          # Maven配置
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/demo/
│   │   │       ├── DemoApplication.java    # 启动类
│   │   │       ├── controller/             # 控制器
│   │   │       ├── service/                # 服务层
│   │   │       ├── repository/             # 数据访问
│   │   │       ├── entity/                 # 实体类
│   │   │       ├── dto/                    # 数据传输对象
│   │   │       ├── config/                 # 配置类
│   │   │       └── exception/              # 异常处理
│   │   └── resources/
│   │       ├── application.yml             # 配置文件
│   │       └── static/                     # 静态资源
│   └── test/
│       └── java/
└── README.md
python 复制代码
# Python FastAPI 标准结构(推荐)
my-fastapi-project/
├── pyproject.toml                   # 项目配置(现代标准)
├── requirements.txt                 # 依赖列表(兼容)
├── README.md
├── .env.example                     # 环境变量示例
├── .gitignore
├── src/                             # 源代码目录
│   └── myapp/
│       ├── __init__.py
│       ├── main.py                  # 入口文件
│       ├── core/                    # 核心配置
│       │   ├── __init__.py
│       │   ├── config.py            # 配置管理
│       │   ├── security.py          # 安全相关
│       │   └── dependencies.py      # 依赖注入
│       ├── api/                     # API层
│       │   ├── __init__.py
│       │   ├── deps.py              # API依赖
│       │   └── v1/                  # API版本
│       │       ├── __init__.py
│       │       ├── endpoints/
│       │       │   ├── __init__.py
│       │       │   ├── users.py
│       │       │   └── auth.py
│       │       └── router.py
│       ├── models/                  # 数据模型
│       │   ├── __init__.py
│       │   └── user.py
│       ├── schemas/                 # Pydantic模型
│       │   ├── __init__.py
│       │   └── user.py
│       ├── services/                # 业务逻辑
│       │   ├── __init__.py
│       │   └── user_service.py
│       ├── repositories/            # 数据访问
│       │   ├── __init__.py
│       │   └── user_repo.py
│       └── utils/                   # 工具函数
│           ├── __init__.py
│           └── helpers.py
├── tests/                           # 测试目录
│   ├── __init__.py
│   ├── conftest.py                  # pytest配置
│   └── test_users.py
└── alembic/                         # 数据库迁移
    └── versions/

9.2 三种框架的项目结构对比

Flask 项目结构
python 复制代码
# Flask 小型项目
flask-app/
├── app.py                    # 单文件应用(适合小型项目)
├── requirements.txt
└── templates/
    └── index.html

# Flask 中大型项目(推荐)
flask-app/
├── wsgi.py                   # WSGI入口
├── app/
│   ├── __init__.py           # 创建Flask应用
│   ├── extensions.py         # 扩展初始化
│   ├── config.py             # 配置
│   ├── models/
│   │   ├── __init__.py
│   │   └── user.py
│   ├── routes/
│   │   ├── __init__.py
│   │   └── user_routes.py
│   ├── services/
│   │   └── user_service.py
│   ├── templates/
│   └── static/
├── migrations/
├── tests/
└── requirements.txt
Django 项目结构
python 复制代码
# Django 项目结构
django-project/
├── manage.py
├── config/                   # 项目配置
│   ├── __init__.py
│   ├── settings/
│   │   ├── __init__.py
│   │   ├── base.py          # 基础配置
│   │   ├── development.py   # 开发环境
│   │   └── production.py    # 生产环境
│   ├── urls.py
│   ├── wsgi.py
│   └── asgi.py
├── apps/                     # 应用目录
│   ├── users/               # 用户应用
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── views.py
│   │   ├── urls.py
│   │   ├── serializers.py   # DRF序列化器
│   │   ├── services.py      # 业务逻辑
│   │   └── migrations/
│   └── orders/              # 订单应用
│       └── ...
├── templates/
├── static/
├── media/
├── tests/
└── requirements.txt
FastAPI 项目结构
python 复制代码
# FastAPI 项目结构(推荐)
fastapi-project/
├── pyproject.toml            # 项目配置
├── src/
│   └── app/
│       ├── __init__.py
│       ├── main.py           # FastAPI应用入口
│       ├── api/
│       │   ├── __init__.py
│       │   ├── deps.py       # 公共依赖
│       │   └── v1/
│       │       ├── __init__.py
│       │       ├── router.py # 汇总路由
│       │       └── endpoints/
│       │           ├── users.py
│       │           └── items.py
│       ├── core/
│       │   ├── __init__.py
│       │   ├── config.py     # 配置
│       │   └── security.py   # JWT等
│       ├── models/           # SQLAlchemy模型
│       │   ├── __init__.py
│       │   └── user.py
│       ├── schemas/          # Pydantic模型
│       │   ├── __init__.py
│       │   └── user.py
│       ├── crud/             # CRUD操作
│       │   ├── __init__.py
│       │   └── user.py
│       └── db/
│           ├── __init__.py
│           ├── base.py       # Base类
│           └── session.py    # 数据库会话
├── tests/
├── alembic/
└── docker-compose.yml

9.3 目录规范详解

命名规范对比
类型 Java Python
包名/模块名 com.example.userService user_service
类名 UserService UserService
函数名 getUserById get_user_by_id
变量名 userName user_name
常量 MAX_SIZE MAX_SIZE
文件名 UserService.java user_service.py
__init__.py 的作用
python 复制代码
# Python的__init__.py文件
# 1. 标识目录为Python包
# 2. 可以导出公共接口
# 3. 可以执行初始化代码

# myapp/__init__.py
from .main import create_app
from .models import User
from .services import UserService

__all__ = ["create_app", "User", "UserService"]

# 使用时可以直接导入
from myapp import User, UserService
配置管理对比
java 复制代码
// Java - application.yml
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydb
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
  jpa:
    hibernate:
      ddl-auto: validate
python 复制代码
# Python - 使用pydantic-settings(推荐)
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    app_name: str = "My API"
    database_url: str
    secret_key: str
    debug: bool = False

    class Config:
        env_file = ".env"

settings = Settings()

# 使用
from app.core.config import settings
print(settings.database_url)

9.4 分层架构对比

java 复制代码
// Java Spring Boot 分层
Controller → Service → Repository → Entity

// 典型调用链
UserController
    ↓
UserService (业务逻辑)
    ↓
UserRepository (数据访问)
    ↓
User (实体)
python 复制代码
# Python FastAPI 分层(推荐)
Router → Service → Repository → Model

# 典型调用链
users.py (endpoints)
    ↓
user_service.py (业务逻辑)
    ↓
user_repo.py (数据访问)
    ↓
user.py (SQLAlchemy Model)

# schemas/ 用于请求/响应的数据验证

9.5 项目配置文件对比

java 复制代码
// Java - pom.xml
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
python 复制代码
# Python - pyproject.toml(现代标准)
[project]
name = "my-api"
version = "1.0.0"
description = "My FastAPI Project"
requires-python = ">=3.10"
dependencies = [
    "fastapi>=0.100.0",
    "uvicorn>=0.23.0",
    "sqlalchemy>=2.0.0",
    "pydantic>=2.0.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
    "black>=23.0.0",
    "mypy>=1.0.0",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

9.6 最佳实践建议

实践 Java Python
配置管理 application.yml + @Value pydantic-settings + .env
依赖注入 Spring IoC容器 FastAPI Depends()
数据验证 @Valid + Bean Validation Pydantic自动验证
日志 SLF4J + Logback logging模块
测试 JUnit + Mockito pytest + pytest-asyncio
代码风格 Checkstyle/Spotless Black + Ruff
类型检查 编译时检查 mypy静态检查

十、总结与选择建议

场景 推荐框架 理由
微服务/API Spring Boot + FastAPI Spring生态 + 异步性能
快速原型 Django 全功能、内置Admin
小型API Flask 轻量、灵活
高性能异步 FastAPI async/await、自动文档
学习Web开发 Flask 概念简单、代码少

Java工程师的选择建议

  • 如果你做企业级开发 → Django(类Spring的全功能框架)
  • 如果你要快速构建REST API → FastAPI(现代、类型安全)
  • 如果你做微服务 → Spring Cloud + FastAPI混合

Python Web框架的设计理念是"选择优于约定"。Django给你全部功能,Flask给你基础让你选择,FastAPI给你类型安全。三者各有优势,根据项目需求选择。

相关推荐
是真的小外套2 小时前
第十一章:Flask入门之从零构建Python Web应用
前端·python·flask
Westward-sun.2 小时前
NLP 词向量实战:PyTorch 从零实现 CBOW(Word2Vec)全流程拆解
人工智能·pytorch·python·深度学习·自然语言处理·word2vec
青瓷程序设计2 小时前
基于YOLO的安全帽佩戴检测系统~Python+模型训练+2026原创+YOLO算法
python·算法·yolo
badhope2 小时前
2025年3月AI领域纪录:从模型开源到智能体价值重估——风云变幻DLC
人工智能·python·深度学习·计算机视觉·数据挖掘
小陈工2 小时前
Python Web开发入门(一):虚拟环境与依赖管理,从零搭建纯净开发环境
开发语言·前端·数据库·git·python·docker·开源
七夜zippoe3 小时前
联邦学习实战:隐私保护的分布式机器学习——联邦平均与差分隐私
分布式·python·机器学习·差分隐私·联邦平均
不懒不懒3 小时前
【OpenCV 计算机视觉四大核心实战:从背景建模到目标跟踪】
人工智能·python·opencv·机器学习·计算机视觉
coderlin_3 小时前
Django DRF开发
python·django·sqlite
zhangzeyuaaa3 小时前
# Python 抽象类(Abstract Class)
开发语言·python