Software Engineer's Blog

FastAPI (Python) vs Spring Core (Java) Perspective Comparison

FastAPI (Python) vs Spring Core (Java) Perspective Comparison

1. DI and Container Existence

Spring Core centers around a massive ApplicationContext container. In contrast, FastAPI uses a dependency resolution engine instead of a fixed container.

ComparisonSpring Core (Java)FastAPI (Python)
Managed byIoC container manages full lifecycle of BeansRequest Resolver resolves dependencies per request
Injection TimingAll injected at application startupInjected for each API request
ConfigurationAnnotations (@Component) or XML/Java configurationFunction argument type hints with Depends()
FlexibilityStrict type safety and structured layersFlexible composition via Duck Typing

2. Singleton and Object Scope

Spring manages most objects as singletons by default, whereas Python leverages the module system for singletons.

Spring: Bean Scope

  • Singleton: Only one instance in the container. Default for @Service, @Repository.
  • Prototype: New instance per request.
  • Management: Framework controls instance counts via internal cache.

FastAPI: Module & Function Scope

  • Singleton: Module-level variable in dependencies.py, leveraging Python module caching.
  • New Instance: Each Depends() call can return a new class instance.
  • Management: Developers explicitly distinguish Heavy vs Light objects in code.

3. Resource Lifecycle and AOP

Java developers are familiar with @Transactional magic. In Python, similar patterns are achieved with yield and decorators.

Resource Teardown

  • Spring: DisposableBean, @PreDestroy, or try-with-resources.
  • FastAPI: yield keyword handles setup and teardown in a single place, keeping code cohesive.

Cross-cutting Concerns

  • Spring AOP: Uses proxies to inject functionality at runtime.
  • Python Decorator: Wraps a function explicitly, making control flow easier to trace.

4. Execution Model: Thread-per-request vs Event Loop

A major architectural difference in performance and concurrency.

  • Spring (Servlet-based): One thread per request (ThreadLocal often used). Blocking operations do not affect other threads, but memory usage is higher.
  • FastAPI (ASGI-based): Single event loop asynchronous model handles many concurrent async requests. I/O does not block the thread, making concurrency highly efficient.
    • Note: While the event loop is single, actual deployments may use Uvicorn workers, thread pools, or background threads.

[!TIP]
Transition mindset for Java developers:****“Don’t wrap everything in classes” → “Favor functions and modules”: Python treats functions and modules as first-class citizens; simple logic often only needs function DI.“Explicitness over magic” → “Keep dependencies visible”: Avoid relying on Spring-like auto-configuration; design dependencies clearly with Depends().“Take control of singletons” → “Define module-level singletons”: Don’t wait for the framework to enforce single instances; use module variables for heavy objects.


Quick Comparison

FeatureSpring CoreFastAPI
Dependency Declaration@AutowiredDepends()
Singleton GuaranteeIoC container cachePython module cache (sys.modules)
Resource Teardownfinally / @PreDestroyyield
Configurationapplication.ymlpydantic-settings (BaseSettings)