IoC컨테이너와 빈
IoC (Inversion of Control) : 의존관계 주입(Dependency Injection)이라고도 하며, 어떤 객체가 사용하는 의존 객체를 직접 만들어 사용하는 것이 아니라, 주입 받아 사용하는 방법
스프링 IoC 컨테이너
- BeanFactory
- Application Component의 중앙 저장소
- 빈 설정 소스로부터 빈 정의를 읽어들이고, 빈을 구성하고 제공
- BeanFactory가 가장 핵심
빈
- 스프링 IoC컨테이너가 관리하는 객체
- 장점
- 의존성 관리
- 스코프
- 싱글톤 : 하나
- 프로토타입 : 매번 다른 객체
- 라이프사이클 인터페이스
DI는 외부에서 두 객체간의 관계를 결정해주는 디자인 패턴
인터페이스를 사이에 둬서 클래스 레벨에서는 의존관계가 고정되지 않도록 하고 런타임 시에 관계를 동적으로 주입해 유연성을 확보하고 결합도를 낮춘다.
- DI를 사용하지 않으면 두 클래스가 강하게 결합
- DI를 사용하지 않으면 객체들의 관계가 아니라 클래스간의 관계가 맺어짐
ApplicationContext
ApplicationContext가 제공하는 기능
- BeanFactory
- 메시지 소스 처리 기능 (i18n)
- 이벤트 발행 기능
- 리소스 로딩 기능
빈으로 관리되는 객체는 하나만 존재하면 된다. (싱글톤 패턴)
다양한 의존성 주입 방법이 있는데 SpringBoot를 사용할 경우엔
@SpringBootApplication
안에 아래와 같이 @ComponentScan
이 들어있어 어노테이션 기반 컴포넌트 스캔이 이루어진다.
@Component가 아니라 @Repository, @Service 사용하는 이유
-> @Repository가 붙어있는 어노테이션에 특정한 기능을 실행시킬 수 있고, AOP사용에 좋음
의존성 주입은 3가지 가능
생성자가 가장 좋다. (어플리케이션 실행 전 에러가 있을 경우 표시)
Environment
ApplicationFactory는 빈팩토리 기능만 하는 것이 아니다.
프로파일을 줘서 각각의 환경마다 다른 빈을 설정할 수 있다.
프로퍼티를 줘서 환경마다 값을 줄 수도 있다.
MessageSource
메시지를 다국어화 하는 방법
스프링부트를 사용하면 별다른 설정 없이 messages.properties 사용 가능
- messages.properties
- messages_ko_kr.properties
MessageSource라는 빈이 messages ~ 번들을 읽고있다.
ApplicationEventPublisher
스프링 4.2부터는 이 클래스를 상속받지 않아도 이벤트 사용이 가능하다.
이벤트 발생 방법
ApplicationEventPublisher.publishEvent();
이벤트 처리 방법
@EventListener
를 사용해서 빈의 메소드에 사용 가능- 기본적으로 synchronized
- 순서를 정하고 싶으면
@Order
와 함께 사용 - 비동기적으로 실행하고 싶으면
@Async
와 함께 사용
ResourceLoader
ApplicationContext의 마지막 기능
리소스를 읽어오는 기능을 제공하는 인터페이스
리소스 읽어오기
- 파일 시스템에서 읽어오기
- 클래스 패스에서 읽어오기
- URL로 읽어오기
- 상대, 절대 경로로 읽어오기
Resource / Validation
- java.net.URL을 추상화 한 것
- 추상화 한 이유
- 클래스패스 기준으로 리소스 읽어오는 기능 부재
- ServletContext기준으로 상대경로 읽어오는 기능 부재
구현체
- UrlResource: java.net.URL 참고, 기본으로 지원하는 프로토콜 http, https, ftp, file, jar.
- ServletContextResource: 웹 애플리케이션 루트에서 상대 경로로 리소스 찾는다.
- resourceLoader.getResource(“test.txt”); 로 적을 경우 ServletContextResource로 리소스를 찾는다.
- ApplicationContext의 타입에 상관없이 리소스 타입을 강제하려면 java.net.URL 접두어(+ classpath:)중 하나를 사용할 수 있다.
- classpath:me/whiteship/config.xml -> ClassPathResource
- file:///some/resource/path/config.xml -> FileSystemResource
org.springframework.validation.Validator
애플리케이션에서 사용하는 객체 검증용 인터페이스.
인터페이스
- boolean supports(Class clazz): 어떤 타입의 객체를 검증할 때 사용할 것인지 결정함
- void validate(Object obj, Errors e): 실제 검증 로직을 이 안에서 구현
- 구현할 때 ValidationUtils 사용하며 편리 함.
@Min, @NotEmpty, @Email 등 어노테이션으로 간단하게 값 검증 가능
데이터 바인딩
Converter
- S 타입을 T 타입으로 변환할 수 있는 매우 일반적인 변환기.
public class StringToEventConverter implements Converter<String, Event> {
@Override
public Event convert(String source) {
Event event = new Event();
event.setId(Integer.parseInt(source));
return event;
}
}
Formatter
- PropertyEditor 대체제
- Object와 String 간의 변환을 담당한다.
- 문자열을 Locale에 따라 다국화하는 기능도 제공한다. (optional)
public class EventFormatter implements Formatter<Event> {
@Override
public Event parse(String text, Locale locale) throws ParseException {
Event event = new Event();
int id = Integer.parseInt(text);
event.setId(id);
return event;
}
@Override
public String print(Event object, Locale locale) {
return object.getId().toString();
}
}
ConversionService
- 실제 변환 작업은 이 인터페이스를 통해서 쓰레드-세이프하게 사용할 수 있음.
- 스프링 MVC, 빈 (value) 설정, SpEL에서 사용한다.
스프링 부트같은 경우 웹 애플리케이션인 경우에 DefaultFormattingConversionSerivce를 상속하여 만든 WebConversionService를 빈으로 등록해 준다.
Formatter와 Converter 빈을 찾아 자동으로 등록해 준다.
SpEL
스프링 EL이란?
- 객체 그래프를 조회하고 조작하는 기능을 제공한다.
- Unified EL과 비슷하지만, 메소드 호출을 지원하며, 문자열 템플릿 기능도 제공한다.
문법
- #{“표현식”}
- ${“프로퍼티”}
실제로 어디서 쓰나?
- Value 애노테이션
- @ConditionalOnExpression 애노테이션
- 스프링 시큐리티
- 메소드 시큐리티, @PreAuthorize, @PostAuthorize, @PreFilter, @PostFilter
- XML 인터셉터 URL 설정
- 스프링 데이터
- @Query 애노테이션
- Thymeleaf
ex
@Value("#{1 + 1}")
// application.properties
my.value = 100
@Value("${my.value}")
@Value("#{${my.value} eq 100}")
Null-safety
스프링 프레임워크 5에 추가된 Null 관련 애노테이션
- @NonNull
- @Nullable
- @NonNullApi (패키지 레벨 설정)
- @NonNullFields (패키지 레벨 설정)
목적
- (툴의 지원을 받아) 컴파일 시점에 최대한 NullPointerException을 방지하는 것
Reference
스프링 프레임워크 핵심 기술 - 백기선
[Spring] 의존성 주입(Dependency Injection, DI)이란? 및 Spring이 의존성 주입을 지원하는 이유