Programming/Spring
[Spring] Spring, Spring Boot
soeun2537
2025. 6. 27. 18:42
우아한테크코스 레벨 2에서 학습한 내용을 정리한 글입니다.
💭 들어가며
Spring이라는 방대한 프레임워크를 공부하면서 공부량이 엄청나게 많아졌다. 처음에는 각 개념을 지엽적으로 공부하다 보니 어떤 기술이 Spring Core에 속하고, 어떤 것이 Spring MVC에 해당하는지 혼란이 생기기 시작했다. Spring 공식 사이트의 Spring Projects를 살펴보며, Spring 생태계가 내가 생각했던 것보다 더 크다는 사실을 알게 되었다. 이 과정에서 Spring과 Spring Boot가 본질적으로 다르다는 것도 인식하게 되었다. 따라서 이번 기회에 관련 글을 작성하며 정리해보고자 한다.
✅ 원시 서블릿 방식
▶ 코드
🔽 디렉토리 구조
src/
└── main/
├── java/
│ └── com/example/HelloServlet.java
└── webapp/
└── WEB-INF/
└── web.xml
🔽 코드
public class HelloServlet extends HttpServlet {
private final HelloService helloService = new HelloService(); // 직접 의존성 생성
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String message = helloService.greet();
resp.setContentType("text/plain");
resp.getWriter().write(message);
}
}
🔽 환경 설정 (IntelliJ 기준)
- web.xml 설정
- 서블릿 버전 선언
- 서블릿 등록 및 URL 매핑 (또는 @WebServlet 어노테이션 사용 가능)
- Project Structure 구성
- Project Structure > Facets에서 Web 설정 추가
- Artifacts에 WAR 빌드 항목 추가
- Tomcat 로컬 서버 직접 설치
- https://tomcat.apache.org 에서 설치
- Run > Edit Configurations에서 Tomcat Server > Local 추가
- 위에서 만든 Artifact를 Deployment에 등록
위 과정을 모두 직접 수행해야 /hello 요청이 정상 작동한다. 자세한 과정은 ChatGPT나 구글링하면 자세히 알려준다. Tomcat 설치부터 WAR 배포, 트러블슈팅하는 데만 이틀이 걸렸다...
▶ 문제점
- 의존성 주입(DI)이 불가능하여 객체를 직접 생성해야 하므로, 생성자 주입이나 테스트용 Mock 객체 주입이 어렵다.
- HTTP 요청과 서블릿을 매핑하려면 web.xml 또는 @WebServlet을 직접 설정해야 하며, 메서드 단위 매핑이 지원되지 않는다.
- 컨트롤러, 서비스, DB 접근 레이어 간 역할 분리가 강제되지 않으며, 설계 원칙(SRP, DIP 등)을 위반하기 쉬운 구조가 된다.
- 무엇보다 Tomcat 설치, WAR 구성, 배포 설정 등 모든 과정을 직접 처리해야 하며, 작은 설정 하나만 누락해도 오류가 발생해 디버깅에 많은 시간이 소모된다.
✅ Spring
▶ 코드
🔽 디렉토리 구조
src/
├── main/
│ ├── java/
│ │ └── com/example/controller/HelloController.java
│ ├── resources/
│ └── webapp/
│ ├── WEB-INF/
│ │ ├── web.xml
│ │ └── spring/
│ │ └── servlet-context.xml
│ └── views/
│ └── hello.jsp
🔽 코드
@Controller
public class HelloController {
private final HelloService helloService;
@Autowired
public HelloController(HelloService helloService) {
this.helloService = helloService; // 의존성 주입(DI)
}
@GetMapping("/hello")
@ResponseBody
public String greet() {
return helloService.greet();
}
}
🔽 환경 설정 (IntelliJ 기준)
- 원시 서블릿 배포 방식과 거의 동일하다.
- JSP와 spring-servlet.xml 정도가 추가된다.
▶ Spring이 해결해 주는 부분
- 객체를 직접 생성하지 않고, Spring의 의존성 주입(DI)을 통해 필요한 객체가 자동으로 주입된다.
- @GetMapping, @PostMapping 등의 어노테이션을 사용해 HTTP 요청을 메서드 단위로 간단하게 매핑할 수 있다.
- @Controller, @Service, @Repository 등의 어노테이션을 통해 계층별 책임이 명확히 분리된다.
▶ 문제점
- Spring은 코드 작성 측면에서 많은 편리함을 제공하지만, 여전히 원시 서블릿처럼 초기 설정이 상당히 복잡하다.
✅ Spring Boot
▶ 코드
🔽 코드
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
🔽 환경 설정
- 실제로 Spring Boot 프로젝트를 생성하면, 기본 설정이 이미 모두 적용되어 있는 것을 확인할 수 있다.
▶ Spring Boot가 해결해 주는 부분
- @SpringBootApplication 하나만으로 Bean 등록, 컴포넌트 스캔 등 기본 설정이 자동으로 적용되어, XML, web.xml, DispatcherServlet 같은 복잡한 설정 없이 애플리케이션을 바로 실행할 수 있다.
- 자동 설정(Auto Configuration)을 통해 주요 설정들이 자동으로 구성된다.
- 내장 Tomcat 서버가 포함되어 있어, 별도 서버 설치 없이 .jar 파일만으로 애플리케이션을 실행할 수 있다.
- Starter 의존성을 통해 필요한 라이브러리를 쉽게 추가할 수 있다.
✅ 결론
원시 서블릿 방식부터 시작해 외부 Tomcat에 Spring 애플리케이션을 배포하며 직접 환경 설정을 해봤는데, 하길 잘한 것 같다. 덕분에 Spring Boot가 개발자에게 환경 설정 부담을 얼마나 줄여주는지 직접 확인해 볼 수 있었다.
Spring은 Java를 더 빠르고, 쉽게 개발할 수 있게 만든 프레임워크라면, Spring Boot는 Spring 프레임워크의 복잡한 설정 과정을 간소화하고 빠르게 애플리케이션을 개발할 수 있도록 하는 프레임워크라고 볼 수 있다.