把一个最简HelloWorld程序用Spring组织起来,关键步骤很直接:创建项目、添加Spring或Spring Boot依赖、用注解或@Bean声明组件、通过@Autowired注入、写一个Controller或命令行Runner来输出HelloWorld,然后启动并访问。下面按Spring Boot(现代且常用)和经典Spring两条路线,逐步讲清配置、代码片段、运行与调试要点,力求让你不仅能跑通示例,还能理解容器在背后做了什么。


为何要把HelloWorld放进Spring?先讲“为什么”
简单的HelloWorld本身很短,但把它放进Spring里,可以让你理解依赖注入(DI)、控制反转(IoC)、组件扫描和生命周期这些核心概念。把这些概念学会了,后面遇到复杂业务就不会觉得“Spring像黑盒子”。用费曼法来讲:把复杂的事拆成最小的步子,然后把每步都说清楚。
准备工作(环境与工具)
- JDK 11+(或根据Spring版本选择JDK 8/17)
- Maven 或 Gradle(下面示例以Maven为主,同时备注Gradle命令)
- IDE(IntelliJ IDEA / VS Code)—方便创建Spring Boot工程
- curl 或 Postman 用于测试HTTP接口
路线概览:Spring Boot 与 经典 Spring(对比一下)
先列一个简单对比表,让你心里有地图:
| 项 | Spring Boot | 经典 Spring(XML/JavaConfig) |
| 配置量 | 少,自动配置 | 多,显式配置 |
| 启动方式 | SpringApplication.run | Servlet容器或手动创建Context |
| 学习曲线 | 快上手 | 深入底层好处更明显 |
实操一:用Spring Boot快速搭建HelloWorld REST接口
1. 创建项目(Maven)
可以用IDE自带的Spring Initializr,也可以手工写pom.xml。最小依赖通常只有spring-boot-starter-web。
2. 关键pom片段
下面给出最小依赖示例(用于说明,不是整段pom):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3. 应用主类(入口)
用一行启动Spring容器:SpringApplication.run(App.class, args)。这个动作会创建ApplicationContext并启动内嵌的Tomcat(默认)。代码结构通常像这样:
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
4. 编写Controller与Service(分层)
这里体现依赖注入的核心思想:Controller不去new服务,而是由容器把服务交给Controller(这就是IoC)。
@RestController
public class HelloController {
private final HelloService svc;
public HelloController(HelloService svc) { this.svc = svc; }
@GetMapping("/hello")
public String hello() { return svc.greet(); }
}
@Service
public class HelloService {
public String greet() { return "Hello, World!"; }
}
5. 运行与测试
- 运行:mvn spring-boot:run 或 gradle bootRun
- 测试:curl http://localhost:8080/hello 返回 “Hello, World!”
实操二:经典Spring(非Boot)快速演示
经典Spring更接近容器的底层逻辑,适合想理解每一步的读者。方式一:XML配置;方式二:纯JavaConfig(注解)。我更推荐JavaConfig,因为更直观且类型安全。
1. JavaConfig示例
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig { }
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
这里你可以看到,容器、DispatcherServlet、以及ApplicationContext的创建都由我们显式编排,理解这些能帮助读懂Spring Boot背后的自动配置。
关键概念详解(别急着跳过)
IoC 与 DI(控制反转与依赖注入)
把“创建对象”的责任从代码里拿掉,交给容器来做。你告诉容器“需要一个HelloService”,容器负责提供,这样的好处是便于替换实现、便于单元测试(可以注入Mock),以及降低耦合。
组件扫描(Component Scan)
容器会扫包,识别带注解的类(@Component/@Service/@Controller等),并把它们注册为Bean。注意包路径:扫描范围不包含的类不会被托管,这是新手常犯的错误。
Bean作用域与生命周期
- 默认是singleton:容器里只有一个实例
- prototype:每次请求新建(要注意销毁回调不会被容器管理)
- 还有request/session等与Web相关的作用域
调试与常见问题(实用技巧)
- 404错误但Controller存在:确认请求路径与映射是否匹配,确认端点所在包被ComponentScan扫描。
- Bean未注入(NoSuchBeanDefinitionException):检查候选Bean是否为组件,或者是否有多个实现导致需要@Qualifier。
- 端口被占用:看启动日志,或者改变server.port属性。
- 依赖版本冲突:用mvn dependency:tree 或 gradle dependencies 检查冲突。
测试示例(用MockMvc做Controller单元测试)
写测试能快速验证Controller逻辑且不启动真实服务器:
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired MockMvc mvc;
@Test public void hello_returnsText() throws Exception {
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string("Hello, World!"));
}
}
一些进阶点:让HelloWorld“更有表现力”
- 国际化(i18n):给HelloWorld做资源文件,展示如何根据Accept-Language返回不同文本。
- 健康检查与Actuator:引入spring-boot-actuator来监控应用健康。
- 配置分环境:application.properties/application-dev.yml等,学会profiles的使用。
小表格:常用命令速查
| 动作 | 命令/说明 |
| 构建(Maven) | mvn clean package |
| 运行(Maven) | mvn spring-boot:run |
| 运行Jar | java -jar target/app.jar |
| 测试 | mvn test |
实战小贴士(那些我踩过的坑)
嗯,这部分讲得像随手笔记:
- 别把主类放在比@ComponentScan更深的包层次下(包结构要设计好)。
- 如果用Lombok,IDE要安装插件,否则编译或IDE提示会困扰你。
- 日志看起来很乱时,把logging.level.*调到DEBUG,逐步缩小问题范围。
- 不要把业务逻辑写在Controller里,哪怕是HelloWorld,分层能帮你以后扩展。
常见扩展场景简述(想一想就知道怎么变)
当你需要把HelloWorld变成一个实际服务,常见扩展包括:
- 把返回值从String改为JSON(使用@RestController自动序列化)
- 增加数据库访问(Spring Data JPA)并把Greeting存在DB
- 增加缓存(spring-cache)来提升性能
参考资料与继续学习的方向
- 《Spring Framework Reference Documentation》
- 《Spring Boot Reference Guide》
- 《Effective Java》(了解Java惯用法,能写出更健壮的Spring代码)
好像把主要的点都写完了——其实这就是把“做一件事的所有小步骤”都说清楚的思想。你现在已经知道了两条实现线(Spring Boot 与 经典Spring)、关键配置位置、调试思路和常见坑。如果你想,我可以把完整的pom.xml、应用主类、Controller/Service和一个简单的integration test都写成可复制粘贴的代码;或者把示例改成Gradle版本,按你现有的项目结构来定制。(我这里就不全贴了,免得太长,但可以接着给你做下去)