文档站点
Skip to content

常见问题 FAQ ​

PHP/Laravel 开发者转向 Spring Boot 的高频疑问汇总。按「启动、依赖注入、数据库、并发、部署」分类。

启动与配置 ​

Q:@SpringBootApplication 放在哪个包?为什么报「找不到组件」?

放所有业务包的最外层。它默认扫描「所在包及其子包」,放错位置会导致 @Service、@RestController 全部扫不到,启动后注入就报错。见 目录结构。

Q:Failed to configure a DataSource 是什么?

你引用了需要数据源的 starter(如 JPA/MyBatis),但没配 spring.datasource.* 或没加驱动。要么配连接,要么去掉不需要的依赖。

Q:端口被占用怎么办?

bash
java -jar demo.jar --server.port=8081
# 或 yml: server.port: 8081

Q:Spring Boot 2.x 和 3.x 代码有什么差别?

大部分代码一样。主要差异:包名 javax.* → jakarta.*;Java 版本要求 17+;部分 API 迁移。教程以 3.x 为主,关键处都注明了差异。

依赖注入 ​

Q:@Autowired 报错「required a bean of type 'xxx'」?

三种可能:① 类没加 @Component/@Service 等注解;② 入口类没扫到它(见上面第一个问题);③ 接口有多个实现没指定 @Qualifier。

Q:为什么说构造器注入比 @Autowired 字段注入好?

字段注入无法 final、可能为 null、测试要起容器。构造器注入依赖不可变、创建即完整、测试直接 new。教程示例统一用构造器注入。

Q:@Transactional / @Async 没生效?

同类内部调用不生效(this.method() 不走代理)。必须通过注入的 Bean 调用;只对 public 方法生效;@Async 还需要 @EnableAsync。

数据库 ​

Q:JPA 的 findById 查不到返回什么?

返回 Optional,用 .orElseThrow(...) 或 .orElse(null)。它比 Eloquent 的「查不到返回 null」多一步,但更安全。

Q:LazyInitializationException 是什么?

实体懒加载关联(getPosts()),在事务外访问抛的异常。解决:Service 事务内查全,或 @EntityGraph / JOIN FETCH 预加载。见 JPA 关联关系。

Q:列表查询很慢,N+1 是什么?

查 N 条数据又各查一次关联,共 N+1 次 SQL。用 @EntityGraph 一条 JOIN 解决,等同于 Eloquent 的 with()。见 JPA 查询方法。

Q:ddl-auto 可以设 update 吗?

生产绝对不行。update 让 ORM 自动改表,可能误改生产数据。生产用 none + Flyway 管理表结构。见 JPA 入门。

并发与状态 ​

Q:为什么 Java 容易出「共享变量被改乱」的 bug?

Bean 默认单例,所有请求线程共享。Laravel 的 PHP-FPM 每请求销毁所以不易踩中;Java 长驻进程必须写无状态 Bean。见 Bean 作用域与生命周期。

Q:多实例部署时 Session 登录态丢了?

默认 Session 存内存,每台机器各存各的。用 Redis 存 Session(spring.session.store-type: redis),或改无状态 JWT。见 Session 与 Cookie。

Q:异步任务里拿不到当前登录用户?

SecurityContextHolder 是 ThreadLocal,新线程不会自动带过去。把用户 ID 作为参数传给异步方法。见 Spring Security 深入。

部署 ​

Q:java -jar demo.jar 启动的配置从哪来?

优先级:命令行参数 > 环境变量 > application-{profile}.yml > application.yml > 默认值。生产密钥走环境变量,别写死在 yml。见 配置中心。

Q:打成的 jar 很大(几十 MB)正常吗?

正常。这是 fat jar,内含 Tomcat 和所有依赖,所以能独立运行。体积大是「单文件部署」的代价,换来无需外置服务器。

Q:需要 Nginx 吗?

内置 Tomcat 可直接对外,但生产常在前面加 Nginx(SSL 终结、静态资源、反向代理)。见 构建与部署。

开发习惯 ​

Q:PHP 的空数组 [],Java 里对应什么?

new ArrayList<>() 或 List.of()。注意 Java 的 List 是「不可变/可变」区分的,List.of() 不可增删。

Q:Java 有 isset() / empty() 吗?

没有内置函数,用 Objects.isNull(x)、StringUtils.hasText(s)、Optional。见 常用工具与帮助函数。

Q:怎么写 foreach?

java
for (Post p : posts) { ... }            // foreach
for (int i = 0; i < n; i++) { ... }     // 普通 for
posts.forEach(p -> { ... });            // 流式

Q:字符串拼接用 . 还是 +?

Java 用 +。"id=" + id 自动转字符串。日志用 {} 占位符(见 日志)。

Q:没有全局函数,很多工具从哪来?

Java 用静态方法(Math.max、StringUtils.hasText)和 Stream API。没有全局函数是 Java 的设计 —— 一切都从属于类。见 常用工具与帮助函数。

面向 PHP / Laravel 开发者的 Spring Boot 中文文档