본 내용은 인프런의 김영한 님의 강의 "스프링 핵심 원리 - 기본편" 내용을 바탕으로 정리한 내용입니다.
스프링 컨테이너
- 스프링 컨테이너는 스프링 프레임워크의 핵심이며, 애플리케이션의 객체를 생성하고 관리한다.
- 스프링 컨테이너는 여러 개의 애플리케이션 Application Context 를 포함할 수 있다.
스프링 빈(Spring Bean)
- 스프링 프레임워크의 핵심 개념 중 하나로, 스프링 컨테이너에 의해 생성, 관리되는 객체를 말한다.
- 스프링 빈은 스프링 컨테이너에 등록되어 애플리케이션에서 필요한 곳에서 사용할 수 있다.
- 스프링에서 상속관계인 부모 타입으로 빈을 조회하면 자식 타입도 함께 조회된다.
ex)
public class Parent {
public void sayHello() {
System.out.println("Hello from Parent");
}
}
public class Child extends Parent {
@Override
public void sayHello() {
System.out.println("Hello from Child");
}
}
public class SpringApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Parent parentBean = context.getBean(Parent.class);
parentBean.sayHello(); // "Hello from Child"
((AnnotationConfigApplicationContext) context).close();
}
}
BeanFactory
- BeanFactory는 스프링의 컨테이너의 최상위 인터페이스이다.
- 빈의 생성과 관리, 의존성 주입(Dependency Injection), 빈의 생명주기 관리 등의 기능을 제공한다.
- 지연된 초기화 방식을 사용하여 필요한 시점에 빈을 생성하고 사용한다.
- BeanFactory 인터페이스는 주로 XML 기반의 설정 파일로부터 빈 정의를 로드하고 관리한다.
ApplicationContext
- 스프링 컨테이너의 하위 인터페이스로, BeanFactory의 기능을 모두 상속 받아서 제공한다.
- 스프링 설정 파일(XML 또는 JavaConfig)을 기반으로 생성되며, 빈의 정의와 빈 간의 의존성 등을 관리한다.
- 스프링 컨테이너는 @Configuration 이 붙은 AppConfig 를 설정 정보로 사용하는데 여기서 @Bean이라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라 한다.
- Bean이름은 보통 메서드 이름을 사용 이름을 직접 부여할 수도 있으나 항상 다른 이름을 부여해야 한다.
- BeanFactory를 직접 사용할 일은 거의 없고, 보통 부가기능이 포함된 ApplicationContext를 사용한다
ex)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public SpringRepository springRepository() {
return new SpringRepository();
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringApp {
public static void main(String[] args) {
// 스프링 컨테이너 생성
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 애플리케이션 컨텍스트로부터 빈(Bean) 가져오기
SpringRepository springRepository = context.getBean(SpringRepository.class);
// 스프링 컨테이너 종료
((AnnotationConfigApplicationContext) context).close();
}
}
ApplicationContext의 부가 기능
애플리케이션 이벤트 관리
애플리케이션 이벤트를 발행하고 처리할 수 있는 기능을 제공한다. 이벤트는 애플리케이션의 상태 변화를 나타내거나 특정 액션에 대한 응답으로 사용되는데 이를 통해 애플리케이션 내부의 컴포넌트 간 느슨한 결합을 유지하면서 이벤트를 처리할 수 있다.
ex) ApplicationEventPublisherAware 인터페이스를 구현하여 애플리케이션 이벤트를 발행할 수 있는ApplicationEventPublisher 객체를 주입는다. 이를 통해 MyService와 같은 빈에서 이벤트를 발행하고, 다른 리스너 빈에서 해당 이벤트를 구독하여 처리할 수 있다.
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig implements ApplicationEventPublisherAware {
private ApplicationEventPublisher eventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
@Bean
public MyService myService() {
return new MyService(eventPublisher);
}
}
메시지 소스를 활용한 국제화 기능
스프링은 메시지 소스(MessageSource)를 사용하여 다국어로 작성된 메시지들을 관리하고 제공하는 역할을 한다.
ex) "messages.properties" 파일에 에 greeting=Hello 로 설정되어 있다고 가정했을 때 시스템의 로케일이 한국어로 설정되어 있다면 출력 결과는 "안녕하세요"가 되고, 로케일이 영어로 설정되어 있다면 출력 결과는 "Hello"가 된다.
public class SpringApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
String message = context.getMessage("greeting", new Object[]{}, Locale.getDefault());
System.out.println(message);
((AnnotationConfigApplicationContext) context).close();
}
}
환경변수를 활용한 환경 구분
환경 변수(Environment)를 활용하여 환경을 구분하여 처리할 수 있다.
ex) Environment의 getActiveProfiles() 메서드로 활성화된 프로파일을 가져오고 이를 통해환경에 따라 애플리케이션의 동작을 분기할 수 있다.
@Configuration
public class AppConfig {
@Autowired
private Environment environment;
@Bean
public MyService myService() {
String activeProfile = environment.getActiveProfiles()[0];
if ("local".equals(activeProfile)) {
// 로컬 환경 처리
} else if ("dev".equals(activeProfile)) {
// 개발 환경 처리
} else if ("prod".equals(activeProfile)) {
// 운영 환경 처리
}
// ...
}
}
리소스 조회
다양한 리소스를 편리하게 조회할 수 있는 기능을 제공한다. 파일 시스템, 클래스 패스, 외부 URL 등 다양한 위치에 있는 리소스를 로딩하고 사용할 수 있다.
ex) getResource() 메서드로 리소스를 로딩하는데 classpath: 접두사를 사용하여 클래스 패스에 위치한 리소스를 로딩할 수 있다. 이를 통해 파일, 프로퍼티, XML 등 다양한 리소스를 편리하게 조회할 수 있다.
public class SpringApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Resource resource = context.getResource("classpath:myFile.txt");
// 리소스 사용...
((AnnotationConfigApplicationContext) context).close();
}
}
'Spring' 카테고리의 다른 글
[스프링] 싱글톤 패턴 (0) | 2023.07.17 |
---|---|
[스프링] BeanDefinition (0) | 2023.07.16 |
[스프링] IoC와 DI (0) | 2023.07.15 |
[스프링] 좋은 객체 지향 프로그래밍이란? (0) | 2023.07.05 |
[스프링] 스프링(Spring)이란? (0) | 2023.07.05 |