스프링 컨테이너 & 빈
스프링 빈이란?
스프링 빈은 스프링 컨테이너에 의해 관리되는 자바 객체(POJO)를 의미한다.
스프링 컨테이너
스프링 컨테이너는 스프링 빈의 생명 주기를 관리하며, 생성된 스프링 빈들에게 추가적인 기능을 제공
하는 역할을 한다. IoC와 DI의 원리가 스프링 컨테이너에 적용된다.
개발자는 new 연산자, 인터페이스 호출, 팩토리 호출 방식으로 객체를 생성하고 소멸하지만, 스프링 컨테이너를 사용하면 해당 역할을 대신해 준다. 즉, 제어 흐름을 외부에서 관리하게 된다. 또한, 객체들 간의 의존 관계를 스프링 컨테이너가 런타임 과정에서 알아서 만들어 준다.
스프링 컨테이너 생성
- ApplicationContext 인터페이스를 이용한다.
- 자주 사용하는 구현체
AnnotationConfigApplicationContext
: 어노테이션 이용방식
GenericXmlApplicationContext
: XML 이용방식
- 컨테이너에 두 개 이상의 설정 파일 등록방법
- 사용하고자 하는 설정 파일들을 매개변수로 전달
public class Main{
public static void main(String[]args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
new AnnotationConfigApplicationContext(AppConfig.class, Appconfig2.class);
context.close();
}
}
스프링 빈 등록
@Bean
- @Configuration 클래스(설정 파일)에서 사용한다.
- 속성값으로 빈 이름을 등록할 수 있다.
- 별다른 설정을 하지 않으면 메소드명이 빈 이름으로 등록된다.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
@Component
- Bean으로 등록할 클래스에 어노테이션 추가
- 이 방식을 사용하려면 Component Scan이 필요하다.
- @Controller, @Service, @Repository 어노테이션도 이에 포함된다.
@Component Scan
- 빈으로 등록 될 준비를 마친 클래스들을 스캔하여, 빈으로 등록한다.
- 기본적으로 @Component 어노테이션을 빈 등록 대상으로 포함한다.
- 설정 파일에 @ComponentScan 추가
- 스캔 범위 설정
- basePackages 속성
- 해당 패키지와 하위 패키지에 속한 모든 클래스 스캔
- basePackgeClasses 속성
- 해당 클래스가 위치한 패키지 및 하위 패키지에 속한 모든 클래스 스캔
- 스캔 대상 제외하거나 포함하기
- includeFilters 속성
- excludeFilters 속성
- 예) excludeFilters = @Filter(type= FilterType.REGEX, pattern = “정규표현식”)
- type 종류
- REGEX: 정규표현식 사용
- ASPECTJ
- ANNOTATION: 특정 어노테이션 붙인 클래스 제외
- ASSIGNABLE_TYPE: 특정 타입이나 하위 타입을 제외
- 컴포넌트 스캔 대상
- @Component: 컴포넌트 스캔에서 사용
- @Controller: 스프링 MVC 컨트롤러에서 사용
- @Service: 스프링 비즈니스로직 에서 사용(가시성, 명시성)
- @Repository: 스프링 데이터 접근 계층에서 사용
- @Configuration:
@Configuration
@ComponentScan(basePackages ={"com.example.spring_framework"})
public class AppConfig{ }
빈 생명주기(Life Cycle)와 범위(Scope)
스프링 컨테이너의 라이프사이클
스프링 빈의 라이프사이클
- 컨테이너가 빈 객체의 라이프사이클을 관리
- 객체 생성 -> 의존 설정 -> 초기화 -> 소멸
- 객체가 초기화되고 소멸할 때 특정한 메소드를 호출하려면
- 초기화 시 실행할 메소드 설정
- 빈에 InitialiazingBean 인터페이스 구현
- @Bean(initMethod = “메소드명”)
- 빈 메소드에 @PostConstruct추가
- 소멸시 실행할 메소드 설정
빈에 DisposableBean 인터페이스 구현
destroy()
@Bean(destroyMethod = “메소드명”)
빈 메소드에 @PreDestroy 추가
* Deprecated
빈 스코프(scope)
- 빈은 기본적으로
Singleton
범위를 가진다.
- 범위를 변경하고 싶으면
@Scope
를 사용한다.
- 범위 종류
- Singleton: 기본 값, 하나의 객체만을 생성해서 관리
- Prototype: 매번 새로운 객체를 생성, 컨테이너 종료시 같이 소멸되지 않기 때문에 따로 소멸시켜주어야 한다.
Request: 요청에 따라 계속 재활용
Session: 세션 마다 계속 새로 만듦
* WebSocket
다양한 빈 관련 설정
빈의 구현체가 여러개인 경우 주입 받는 방법
@Primary
: 해당 빈을 최우선으로 주입
@Qualifier("beanName")
: beanName으로 지정된 빈을 주입
Set
또는 List
로 모두 받기
- 프로퍼티 이름을 빈과 동일하게 하기: 가장 흔하게 사용하는 방법
스프링의 환경설정
- 특정한 환경에서만 동작하는 Bean을 만들 때 @Profile사용
- 실행 환경변수를 통해서 특정 환경을 조성할 수 있다.
- 인텔리제이 기준, 실행 환경에서 환경변수에
spring.profiles.active=profileName
- 클래스 단위에 적용하거나 메소드 단위에 적용 가능
- 클래스 단위
- @Configuration @Profile("test")
- @Component @Profile("test")
- 메소드 단위
* @Bean @Profile("test")
📚참고
[Spring]Spring Bean 총 정리
DI정리