스프링 컨테이너 생성 및 종료
- ApplicationContext 인터페이스 이용
- 자주 사용하는 구현체
- AnnotationConfigApplicationContext : 어노테이션 이용방식
- GenericXmlApplicationContext : XML 이용방식
- 컨테이너에 두 개 이상의 설정 파일 등록 방법
- 사용하고자 하는 설정 파일들을 매개변수로 전달
- 하나의 설정 파일에 다른 파일들을 @Import 로 가져오기
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main{
public static void main(String[]args) {
// 스프링 컨테이너 생성
// 매개변수로 여러 개의 설정파일을 컨테이너에 등록할 수 있다.
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class,Appconfig2.class);
// 컨테이너 종료
context.close();
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
// 설정파일은 @Configuration 으로 표시
@Configuration
// @Import의 값으로 {} 배열을 전달하면 AppConfig만 등록해도 3,4도 같이 등록된다.
@Import({AppConfig3.class,AppCofig4.class})
public class AppConfig{}
Bean 관련
Bean 호출
- ApplicationContext.getBean(Bean name, Bean type)
- Bean type만으로도 호출가능
- 동일한 타입이 2개 이상일 경우, Exception 발생
- 이름으로 명확하게 호출해주는 것이 좋음
- Bean type만으로도 호출가능
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main{
public static void main(String[]args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Hello hello = context.getBean("hello", Hello.class);
}
}
Bean 등록
- @Bean
- @Configuration 클래스(설정 파일)에서 사용
- 속성값으로 빈 이름을 등록할 수 있다.
- 아무것도 주지않으면 메소드 명이 빈 이름으로 등록된다.
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig{ // 빈 이름이 hi // @Bean 만 사용하면 메소드 명이 빈 이름이 된다. // 메소드명(빈이름)은 보통 클래스명에서 맨 앞글자를 소문자로 바꾼 것을 사용한다. @Bean("hi") public Hello hello() { return new Hello(); } }
- @Component
- Bean으로 등록할 클래스에 어노테이션 추가
- 이 방식을 사용하려면 Component Scan이 필요
- @Controller, @Service, @Repository 등도 같은 역할을 한다.
import org.springframework.stereotype.Component; @Component public class Hello{}
Component Scan
- @Component 방식으로 빈등록을 하기 위한 방법
- 설정 파일에 @ComponentScan 추가
- 스캔 범위 설정
- basePackages 속성
- 해당 패키지와 하위 패키지에 속한 모든 클래스 스캔
- basePackgeClasses 속성
- 해당 클래스가 위치한 패키지 및 하위 패키지에 속한 모든 클래스 스캔
- basePackages 속성
- 스캔 대상 제외하거나 포함하기
- includeFilters 속성
- excludeFilters 속성
- 예시 : excludeFilters = @Filter(type= FilterType.REGEX, pattern = “정규표현식”)
- type 종류
- REGEX
- 정규표현식 사용
- ASPECTJ
- ANNOTATION
- 특정 어노테이션 붙인 클래스 제외
- ASSIGNABLE_TYPE
- 특정 타입이나 하위 타입을 제외
- REGEX
package com.example.spring_study;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages ={"com.example.spring_study"})
public class AppConfig{}
- 빈 수동등록(@Bean) vs 자동등록 (@Component)
- 수동등록이 우선한다.
DI 관련
DI 방식
- 생성자 방식
- 생성자를 통해 객체를 생성할 때 의존성 주입
- 참고로 스프링 개발팀에서는 생성자 주입을 하는 것을 추천한다.
- Setter 방식
- 객체 생성 후, Setter로 의존성 주입
- 필드 주입 방식
- @Autowired로 필드에 바로 의존성 주입
의존 자동 주입
- @Autowired 사용 (스프링 제공, 타입기반 매칭)
- @Resource (자바 제공,이름 기반 매칭) , @Inject (자바EE 제공) 도 같은 역할
- 보통 필드나 메소드에 사용하고 생성자에도 사용 가능
- 메서드에 붙이면 메서드 파라미터 타입에 해당하는 빈 객체를 주입
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class World{ // 필드 주입 방식 @Autowired private Hello hello; void print(){this.hello.print();} }
- 생성자를 통한 자동 주입
- 단일 생성자의 경우, 빈 등록시 생성자의 매개변수인 빈들이 자동으로 주입된다.
- 다중 생성자의 경우, @Autowired를 생성자에 붙여주어야한다.
- 생성자로 의존성 주입하면 final 키워드를 사용할 수 있어서 안전하다.
- 롬복의 @RequiredArgsConstructor를 사용하면 편리하게 생성자로 DI할 수 있다.
@Component @RequiredArgsConstructor public class Hello { private final World world; }
- @Autowired의 빈 조회 전략
- 타입 조회
- 동일한 타입이 여러 개면 이름으로 조회
- 타입도 동일하고 이름도 동일한 빈이 두개 이상일 때
- @Qualifier
- 사용할 빈과 해당 빈을 주입할 곳에 동일한 @Qualifier("beanName”)을 붙인다.
- 이름은 클래스 명의 카멜케이스로 해주는게 좋다.
- @Primary
- 해당 어노테이션이 붙은 빈을 최우선으로 주입한다.
- Set 또는 List 동일한 빈 모두 받기
- 모든 동일한 빈을 Set이나 List 자료구조로 받아 선택해서 사용할 수 있도록 한다.
- 프로퍼티 이름을 빈과 동일하게 하기
- 중복되지 않도록 프로퍼티 이름(메소드명,필드명,매개변수명 등)을 해당 빈과 동일하게 맞춘다.
- 되도록이면 이렇게 사용하자.
- @Qualifier
- @Autowired 필수 여부
- 자동 주입은 매칭되는 빈이 없으면 예외를 발생시킨다.
- 매칭되는 빈이 없더라도 예외 발생없이 처리하고 싶다면 아래와 같은 설정을 해야한다.
- @Autowired(required = false)
- 매칭되는 빈이 없으면 자동 주입 자체를 하지 않아서 익셉션이 발생되지 않음
- 매칭되는 빈이 없으면 메서드 자체를 호출하지 않음. → null 을 주입하지 않는다.
- Optional<빈 타입>
- 자동 주입 대상 타입이 Optional 일 경우, 일치하는 빈이 존재하지 않으면 값이 없는 Optional을 인자로 전달하고 익셉션 발생 X
- 일치하는 빈이 있으면 값이 있는 Optional 전달
- @Nullable
- 해당하는 빈이 없으면 null 전달, 익셉션 발생 X
- 수동 주입 vs 자동 주입(@Autowired)
- 자동 주입이 우선인데 수동,자동 섞이면 에러 발생시 찾기어려우니 일관성있게 하나만 사용하자.
빈 생명주기(Life Cycle)와 범위(Scope)
스프링 컨테이너의 라이프사이클
- 초기화
- 빈 객체 생성 → 의존 주입 → 초기화
- 종료
- 빈 객체 소멸
빈의 생명주기
- 컨테이너가 빈 객체의 라이프사이클을 관리
- 객체 생성 → 의존 설정 → 초기화 → 소멸
- 객체가 초기화 되고 소멸할 때 특정한 메소드를 호출하려면 아래와
- 초기화 시 실행할 메소드 설정
- 빈에 InitialiazingBean 인터페이스 구현
- afterPropertiesSet()
- @Bean(initMethod = “메소드명”)
- 빈 메소드에 @PostConstruct 추가
- Deprecated 되었다.
- 빈에 InitialiazingBean 인터페이스 구현
- 소멸 시 실행할 메소드 설정
- 빈에 DisposableBean 인터페이스 구현
- destroy()
- @Bean(destroyMethod = “메소드명”)
- 빈 메소드에 @PreDestroy 추가
- Deprecated 되었다.
- 빈에 DisposableBean 인터페이스 구현
- 초기화 시 실행할 메소드 설정
빈 범위
- 빈은 기본적으로 Singleton 범위를 가진다.
- 범위를 변경하고 싶으면 @Scope 을 사용
- 범위 종류
- Singleton : 기본 값, 하나의 객체만을 생성해서 관리
- Prototype : 매번 새로운 객체를 생성, 컨테이너 종료 시 같이 소멸되지 않기 때문에 따로 소멸시켜주어야 한다.
- 범위 종류
스프링의 환경 설정
- 특정한 환경에서만 동작하는 Bean을 만들 때 @Profile 사용
- 실행 환경변수를 통해서 특정 환경을 조성할 수 있다.
- 인텔리제이 기준, 실행 환경에서 환경변수에 spring.profiles.active=ProfileName
- 클래스 단위에 적용하거나 메서드 단위에 적용 가능
- 클래스 단위
- @Configuration @Profile(”test”)
- @Component @Profile(”test”)
- 메서드 단위
- @Bean @Profile(”test”)
- 클래스 단위
'Spring Framework > Spring' 카테고리의 다른 글
Spring Validation (0) | 2022.06.07 |
---|---|
Data Binding (0) | 2022.06.07 |
Spring AOP(관점 지향 프로그래밍) (0) | 2022.06.07 |
Spring Framework 소개 (0) | 2022.06.05 |
Spring 등장 배경 (0) | 2022.06.02 |
댓글