spring
스프링 컨테이너는 스프링 프레임워크에서 가장 핵심적인 부분으로, IoC(Inversion of Control) 개념을 기반으로 만들어진 의존성 관리 및 객체 생성, 설정, 생명주기 관리를 담당하는 중추적인 역할을 합니다. 쉽게 말해 스프링 컨테이너는 객체(빈, Bean)를 생성하고 관리하는 “공장(factory)”라고 볼 수 있습니다.
스프링 컨테이너를 이용하면 결합도가 낮은(loose coupling) 애플리케이션 설계가 가능해집니다. 이는 유지보수성과 확장성에서 큰 이점을 제공합니다.
스프링 프레임워크에서 핵심적으로 제공하는 컨테이너는 크게 BeanFactory와 ApplicationContext로 나누어집니다.
실무에서는 일반적으로 ApplicationContext를 사용합니다. BeanFactory는 무척 간단한 테스트나 커스텀하게 최적화된 상황 이외엔 잘 쓰이지 않습니다.
스프링 컨테이너의 전반적인 동작 흐름은 아래와 같습니다.
스프링 컨테이너에 빈 설정 정보를 주입하는 방법은 크게 XML 설정, 자바 설정, 애노테이션 설정 으로 나눌 수 있습니다. 실무에서는 주로 애노테이션 + 자바 설정 방식을 많이 활용합니다.
과거 스프링 버전에서 가장 많이 사용되던 전통적 방식입니다. 빈의 의존관계를 명시적으로 관리하기 위해 XML 파일(applicationContext.xml 등)을 사용합니다.
<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 빈(Bean) 정의 -->
<bean id="helloService" class="com.example.service.HelloService" />
<bean id="helloController" class="com.example.controller.HelloController">
<!-- helloService 빈을 주입 -->
<property name="helloService" ref="helloService" />
</bean>
</beans>
XMLXML 파일 대신 자바 클래스를 이용하여 설정할 수 있습니다. 스프링 부트가 적극적으로 추천하는 방법이기도 하며, 애노테이션을 통한 빈 등록을 함께 사용하는 것이 일반적입니다.
@Configuration
public class AppConfig {
@Bean
public HelloService helloService() {
return new HelloService();
}
@Bean
public HelloController helloController() {
// 의존성 주입
return new HelloController(helloService());
}
}
JavaAnnotationConfigApplicationContext를 통해 위 설정 클래스를 읽어들여 스프링 컨테이너가 빈을 생성하고 주입합니다.
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
HelloController controller = context.getBean(HelloController.class);
controller.sayHello();
}
Java@Component
public class HelloService {
public String greet(String name) {
return "Hello, " + name;
}
}
@Controller
public class HelloController {
@Autowired
private HelloService helloService;
public void sayHello() {
System.out.println(helloService.greet("Spring"));
}
}
Java@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}
Java스프링 컨테이너에서의 빈 라이프사이클은 다음과 같습니다.
스프링 컨테이너는 빈마다 스코프(scope)를 지정할 수 있습니다. 스코프는 빈의 생존 범위를 뜻합니다.
실무에서 가장 많이 사용하는 스코프는 Singleton이고, 가끔 Prototype 스코프가 필요할 때도 있습니다. 웹 애플리케이션 환경이라면 Request, Session, Application 스코프도 사용할 수 있습니다.
아래 예시는 자바 기반 설정(@Configuration)과 애노테이션(@Component, @Autowired)을 활용하여 스프링 컨테이너에 빈을 등록 및 주입하는 과정을 보여줍니다.
com
└─ example
├─ AppConfig.java
├─ service
│ └─ HelloService.java
└─ controller
└─ HelloController.java
Markdown// com/example/service/HelloService.java
package com.example.service;
import org.springframework.stereotype.Service;
@Service
public class HelloService {
public String sayHello(String name) {
return "Hello, " + name + "!";
}
}
Java// com/example/controller/HelloController.java
package com.example.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.example.service.HelloService;
@Controller
public class HelloController {
private final HelloService helloService;
// 생성자 주입
@Autowired
public HelloController(HelloService helloService) {
this.helloService = helloService;
}
public void processHello() {
String greeting = helloService.sayHello("Spring");
System.out.println(greeting);
}
}
Java// com/example/AppConfig.java
package com.example;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// 필요한 경우 @Bean 정의를 추가로 넣을 수 있습니다.
}
Java// Main.java
package com.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.example.controller.HelloController;
public class Main {
public static void main(String[] args) {
ApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
HelloController controller = context.getBean(HelloController.class);
controller.processHello();
}
}
Java스프링 컨테이너는 스프링 프레임워크의 핵심으로, 객체 생성 및 의존성 관리를 손쉽게 해 주며, 애플리케이션 개발자가 비즈니스 로직에만 집중할 수 있도록 돕습니다. IoC와 DI 개념을 이해하고, BeanFactory와 ApplicationContext의 차이, 각 빈의 스코프(scope)와 라이프사이클 등을 이해하면 스프링을 보다 유연하고 확장성 있게 사용할 수 있습니다.
오늘날 대부분의 스프링 프로젝트는 자바 기반 설정과 애노테이션을 많이 사용하지만, XML 기반 설정도 여전히 사용될 수 있으며, 프로젝트에 따라 적절히 혼합하여 쓰기도 합니다.
스프링 컨테이너를 제대로 이해하면 결합도를 낮춘 애플리케이션 아키텍처 설계가 가능하며, 다양한 부가 기능(AOP, 트랜잭션, 국제화, 테스트 지원 등)을 자유롭게 적용할 수 있다는 점에서 스프링 생태계 전체를 잘 이해하는 발판이 됩니다.
HTTP 상태코드란 무엇인가? HTTP 상태코드(HTTP Status Code)는 서버가 클라이언트의 요청을 처리한 결과를 수치화된 코드로 나타내는…
HTTP란 무엇인가? HTTP(Hypertext Transfer Protocol)는 웹에서 데이터를 주고받기 위해 사용하는 응용 계층 프로토콜입니다. 우리가 브라우저에서…
HTTP란 무엇인가? HTTP(Hypertext Transfer Protocol)는 인터넷에서 웹 브라우저와 웹 서버가 서로 통신하기 위해 사용하는 프로토콜입니다.…
들어가며 우리가 인터넷에서 웹사이트에 접속할 때 가장 먼저 하는 일은 브라우저 주소창에 어떤 문자열을 입력하는…
인터넷 네트워크란? "인터넷(Internet)"이라는 단어는 "인터네트워크(Internetwork)"의 줄임말입니다. 즉, 여러 개의 네트워크가 상호 연결되어 전 세계적으로 하나의…