Files
zhuangang/topics/backend/java-spring/01-java-spring-awareness.md

4.9 KiB
Raw Permalink Blame History

id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week, order
id title type domain stack tags level prerequisites est_hours related week order
backend.java-spring.awareness Java / Spring Boot(了解级):读懂项目结构、IoC 与依赖注入、分层、事务注解和与 Go / Python 的对照 lesson backend
java-spring
Java
Spring Boot
IoC
依赖注入
注解
事务
JPA
MyBatis
虚拟线程
basic
backend.go.index
2
backend.java-spring.scenario.call-java-service
backend.java-spring.interview
14
1

Java / Spring Boot(了解级):读懂项目结构、IoC 与依赖注入、分层、事务注解和与 Go / Python 的对照

定位:能读懂、能对接、面试能聊概念,不作为主线。BOSS直聘 2026-10-23 的调研中,有 AI 应用岗位写了“熟悉 Java / Go / Python 其中之一”,或者团队已有 Java 业务系统需要 Agent 去调用。示例只用 JDK,在 JDK 26(JDK 21+ 即可)上实际运行通过;Spring 代码为示意,未编译。以官方文档为准:https://docs.spring.io/spring-boot/ 。

解释说明

与你熟悉的技术对照

概念 Java / Spring Boot Go Python / FastAPI
数据类 record struct dataclass / Pydantic 模型
路由 @RestController + @GetMapping Gin 路由 @app.get
依赖注入 IoC 容器 + 构造器注入 手动在 main 中组装 Depends
参数校验 @Valid + Bean Validation binding 标签 Pydantic
数据访问 Spring Data JPA / MyBatis database/sql、sqlc、GORM SQLAlchemy
事务 @Transactional 手动 tx.Begin/Commit session.begin()
并发 线程池、虚拟线程(JDK 21) goroutine asyncio
构建 Maven / Gradle go build uv / pip

Spring 的核心概念

  • IoC 容器:对象(Bean)由容器创建和管理,你声明依赖,容器注入。推荐构造器注入(依赖不可变、便于测试)。
  • 分层:Controller(接收请求)→ Service(业务逻辑、事务)→ Repository(数据访问)。
  • 自动配置:Spring Boot 根据依赖和配置自动创建常用组件(数据源、Web 服务器),配置在 application.yml。
  • @Transactional 的坑:基于代理实现,同一个类内部方法调用不经过代理,事务不生效;默认只对运行时异常回滚。
  • AI 相关:Spring AI、LangChain4j 等框架让 Java 项目也能接入大模型(版本变化快,以官方文档为准)。

怎么快速读懂一个 Spring Boot 项目

  1. 看 pom.xml / build.gradle:依赖了什么。
  2. 找带 @SpringBootApplication 的启动类。
  3. 看 application.yml:数据库、端口、外部服务地址。
  4. 从 Controller 顺着调用链读到 Service 和 Repository。
  5. 看全局异常处理(@RestControllerAdvice)和拦截器 / 过滤器(鉴权)。

案例

你负责的 Python Agent 需要调用公司的 Java 订单服务:读懂它的接口定义(Controller 和 DTO)、错误码、鉴权方式、分页规则,把它封装成 Agent 的工具。

代码示例

只用 JDK 的对照示例 examples/java-basics/OrderDemo.java(java OrderDemo.java 运行通过):record、接口 + 构造器注入、Optional、Stream 分组汇总、BigDecimal 金额、虚拟线程。

跨租户查询被拒绝: 订单不存在: B001
t1 按状态汇总: {paid=20.00, refunded=5.00}
用 double 计算金额的问题: 0.1 + 0.2 = 0.30000000000000004
1000 个虚拟线程计数结果: 1000

对应的 Spring Boot 写法(示意,未编译):

@RestController
@RequestMapping("/orders")
class OrderController {
    private final OrderService service;
    OrderController(OrderService service) { this.service = service; }   // 构造器注入,无需 @Autowired

    @GetMapping("/{id}")
    OrderDto get(@PathVariable String id, @RequestHeader("X-Tenant-Id") String tenant) {
        return OrderDto.from(service.get(tenant, id));
    }
}

@Service
class OrderService {
    private final OrderRepository repo;
    OrderService(OrderRepository repo) { this.repo = repo; }

    @Transactional
    public void refund(String tenant, String id) { /* 修改订单 + 写退款记录,在一个事务中 */ }
}

@RestControllerAdvice
class GlobalErrors {
    @ExceptionHandler(NotFoundException.class)
    ResponseEntity<Map<String, String>> notFound(NotFoundException e) {
        return ResponseEntity.status(404).body(Map.of("code", "NOT_FOUND", "message", e.getMessage()));
    }
}

易错点

  • 金额用 double。
  • 同类内部调用带 @Transactional 的方法,以为事务生效。
  • 受检异常被捕获后吞掉,事务没有回滚。
  • 在面试中把“了解”说成“精通”:如实说明能读懂并对接,主语言是 Go / Python。

面试常问

  • 什么是 IoC 和依赖注入?
  • @Transactional 什么情况下会失效?
  • 你不会 Java,如何和 Java 团队协作?