1. 의존(Dependency)이란?
- 의존 정의
- 객체 간의 의존을 의미
- 한 클래스가 다른 클래스의 메서드를 실행할 때 이를 '의존'한다라고 표현
- 의존은 변경에 의해 영향을 받는 관계
- 의존 객체를 가져오는 방법
- 객체를 직접 생성 -> 그러나 유지보수 관점에서 문제를 유발할 수 있음
- 1) DI
- 2) 서비스 로케이터
2. DI(Dependency Injection)를 통한 의존 처리
- DI 정의
- 의존 객체를 직접 생성하지 않고 전달받는 방식
- 의존 객체를 굳이 주입하는 이유?
3. DI와 의존 객체 변경의 유연함
- 의존 객체를 직접 생성하는 방식
- new 연산자를 이용해서 객체를 생성
- 사용하는 객체가 변경될 때, new 연산자를 사용한 모든 line을 수정해야함
- DI를 사용하는 방식
- 어셈블러에서 생성하는 객체만 변경
4. 예제 프로젝트 만들기
- 위 github에 작성
5. 객체 조립기
- 조립기(assembler)
- 객체를 생성하고 의존 객체를 주입하는 클래스
- 조립기 클래스의 get 메서드를 이용해서 필요햔 객체를 구하고 사용
- 참고
- 특정 클래스의 메서드를 표시할 때 '#' 사용
- BufferedReader#readLine()
6. 스프링의 DI 설정
- 스프링의 DI
- 스프링은 DI를 지원하는 조립기
- 어셈블러는 특정 타입 클래스만 생성하지만, 스프링은 범용 조립기
- 설정 정보
- 스프링을 사용하려면 다음을 정의한 설정정보를 작성해야함
1) 어떤 객체를 생성하고
2) 의존을 어떻게 주입할지 - @Configuration
스프링 설정 클래스 - @Bean
해당 메서드가 생성한 객체를 스프링 빈으로 설정
- 스프링을 사용하려면 다음을 정의한 설정정보를 작성해야함
- 스프링 컨테이너
- 의존 객체를 주입하는 것은 스프링 컨테이너
- 설정 클래스를 이용해 컨테이너를 생성해야함
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx.class);
// 컨테이너에서 이름이 memberRegSvc인 빈 객체를 구함
// 빈 이름은 메서드 이름
MemberRegisterService regSvc =
ctx.getBean("memberRegSvc", MemberRegisterService.class);
- DI 방식 1 : 생성자 방식
- 생성자를 통해 의존 객체를 주입받아 필드에 할당
- (참고)
return 타입이 Collection<Member> -> 상위 클래스를 사용
- DI 방식 2 : 세터 메서드 방식
- 세터 메서드를 이용해서 객체를 주입
- 생성자 vs 세터 메서드
- 생성자 방식
- 장점
빈 객체를 생성하는 시접에 모든 의존 객체 주입이 완료 - 단점
주입 받는 객체의 어떤 member로 주입되는지 명확하지 않음
- 장점
- 세터 방식
- 장점
세터 메서드 이름을 통해 어떤 member에 주입되는지 명확 - 단점
set되지 않은 member가 있어도 생성될 수 있음 (NullPointerException)
- 장점
- 생성자 방식
7. @Configuration 설정 클래스의 @Bean 설정과 싱글톤
- 아래와 같은 설정 클래스는 매번 새로운 객체를 생성?
@Configuration
public class AppCtx{
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
}
- 스프링 컨테이너는 @Bean이 붙은 메서드에 대해 한 개의 객체만 생성
- memberDao()를 몇 번을 호출해도 항상 같은 객체를 리턴
- 스프링은 설정 클래스를 상속한 새로운 설정클래스를 만들어서 사용
- 이 때 생성되어 있는지 확인
8. 두 개 이상의 설정 파일 사용하기
- @Autowired
- 스프링의 자동 주입 기능을 위한 것
- 설정 클래스에서 사용한 @Autowired에 대해서도 자동 주입
- 설정 클래스를 내부적으로 스프링 빈으로 등록
- @Import
- 설정 파일에서 설정 파일을 가져옴
- 두 개 이상의 설정 클래스를 지정 가능
- AppConfImport를 설정파일로 등록시, AppConf1과 AppConf2 모두 등록
@Configuration
@Import( {AppConf1.class, AppConf2.class} )
public class AppConfImport {}
9. getBean() 메서드 사용
- getBean()
- getBean(이름, 타입) => 이름은 메서드 이름
- VersionPrinter = versionPrinter = ctx.getBean("versionPrinter", VersionPrinter.class);
- Exception
- NoSuchBeanDefinitionException : 빈 이름이 없을 때, 타입으로만 찾는데 이름이 없을 때
- BeanNotOfRequiredTypeException : 빈 타입이 다를 때
- NoUniqueBeanDefinitionException : 타입으로만 구하는데 이름이 2개 이상일 때
10. 주입 대상 객체를 모두 빈 객체로 설정해야 하나?
- 스프링 빈 등록 차이
- 스프링 컨테이너가 객체를 관리하는지 여부
- 등록하지 않으면 스프링 컨테이너에서 객체를 구할 수 없음
'책읽기' 카테고리의 다른 글
[스프링5 프로그래밍 입문][chap05] 컴포넌트 스캔 (0) | 2022.03.10 |
---|---|
[스프링5 프로그래밍 입문][chap04] 의존 자동 주입 (0) | 2022.03.08 |
[스프링5 프로그래밍 입문][chap01/chap02] 들어가며/스프링 시작하기 (0) | 2022.02.04 |
[파이썬 알고리즘 인터뷰] 14장 - 트리 (0) | 2021.09.13 |
[파이썬 알고리즘 인터뷰][그리디] 쿠키 부여 (0) | 2021.09.01 |