Written by
Poogle
on
on
2021.08.17 TIL
새롭게 배운 것 Done
운동
- 오전 러닝 - 2.5km
독서
알고리즘
코딩
IoC(Inversion of Control) - 제어의 역전
- 일반적인 제어권: 내가 사용할 의존성은 내가 만들기
class VoucherController {
private VoucherRepository repository = new VoucherRepository();
}
- IoC: 내가 사용할 의존성을 다른 누군가 알아서 주도록 하기
class VoucherController {
private VoucherRepository repository;
public VoucherController(VoucherRepository repository) {
this.repository = repository;
}
///
}
class VoucherControllerTest {
@Test
public void create() {
VoucherRepository repository = new VoucherRepository();
VoucherController voucherController = new VoucherController(repository)
}
}
Spring IoC Container
- 빈(Bean) 객체의 생성, 초기화, 보관, 제거 등을 관리하고 있음 => 컨테이너
- 스프링의 핵심 기능: 객체를 생성하고 초기화하는 것
- -> Application Context라는 인터페이스에 정의
- -> AnnotationConfigApplicationContext: 이 인터페이스를 알맞게 구현한 클래스 중 하나, 자바 클래스에서 정보를 읽어와 객체 생성과 초기화를 수행
- 싱글톤 객체
- 별도의 설정을 하지 않을 경우 스프링은 한 개의 빈 객체만을 생성
- 이 때 빈 객체는 싱글톤(단일 객체) 범위를 갖는다고 표현
- 스프링은 기본적으로 한 개의
@Bean
어노테이션에 대해 한 개의 빈 객체를 생성
Bean이란?
- 스프링 IoC 컨테이너가 관리하는 객체
@Bean
어노테이션을 메서드에 붙이면 해당 메서드가 생성한 객체를 스프링이 관리하는 객체로 등록
- 오로지 Bean들만 의존성 주입을 해줄 수 있음
- 등록하려면?
- Component Scan: 어디서부터 찾을 것인지 알려줌
@Component
@Repository
@Service
@Controller
@Configuration
- XML이나 자바 설정 파일에 일일히 등록(
@Bean
으로)
- Component Scan: 어디서부터 찾을 것인지 알려줌
- 꺼내쓰려면?
@Autowired
또는@Injection
getBean()
의존성 주입(Dependecy Injection)
- 의존: 변경에 의해 영향을 받는 관계
- 어떤 한 클래스가 다른 클래스의 메서드를 실행할 때 이를
의존
한다고 표현 - 의존하는 대상이 있으면 그 대상을 구하는 방법이 필요 -> 가장 쉬운 방법: 의존 대상 객체를 직접 생성
public class MemberRegisterService { //의존 객체를 직접 생성 private MemberDao memberDao = new MemberDao(); } //의존하는 MemberDao의 객체도 함께 생성 MemberRegisterService service = new MemberRegisterService();
- 클래스 내부에서 직접 의존 객체를 생성하는 것이 쉽긴 하지만 유지보수 관점에서 문제점을 유발할 수 있음
- 어떤 한 클래스가 다른 클래스의 메서드를 실행할 때 이를
- DI를 통한 의존 처리
- 의존하는 객체를 직접 생성하는 대신 의존 객체를 전달받는 방식을 사용
public class MemberRegisterService {
private MemberDao memberDao;
public MemberRegisterService(MemberDao memberDao) {
this.memberDao = memberDao;
}
}
//의존객체를 생성자를 통해 주입
MemberDao dao = new MemberDao();
MemberRegisterService service = new MemberRegisterService(dao);
- 의존 객체를 직접 생성 X -> 생성자를 통해 MemberRegisterService가 의존하고 있는 MemberDao 객체를 주입 받음
- 왜? 이렇게 복잡하게 하는가?
- 변경의 유연함
@Autowired
/ @Injection
를 어디에 붙일까? - DI 방식
- 생성자 - 가장 권장
- 빈 객체를 생성하는 시점에 모든 의존 객체가 주입됨
- 필수적으로 필요한 객체 만들수 있도록 강제하기 위해
- 테스트 쉽게 (mock)
- 불변성 확보 -> 불변객체 -> thread safety
public class MemberRegisterService {
private final MemberDao memberDao;
public MemberRegisterService(MemberDao memberDao) {
this.memberDao = memberDao;
}
}
- 필드
@Autowired
private MemberDao memberDao;
- setter
- 세터 메서드 이름을 통해 어떤 의존 객체가 주입되는지 알 수 있음
- 필요한 의존 객체를 전달하지 않아도 빈 객체가 생성되기 때문에 객체를 사용하는 시점에 NullPointerException이 발생할 수 있음
public class MemberRegisterService {
private MemberDao memberDao;
@Autowired
public void setMemberRegisterService(MemberDao memberDao) {
this.memberDao = memberDao;
}
}
참고: 책 - 스프링5 프로그래밍 입문 - 최범균 강의 - 예제로 배우는 스프링 입문 - 백기선
깨달은 점 FEELING
- 면접 질문으로 자주 등장한다고 하는 내용이라 정리를 제대로 해놔야겠다는 생각이 들었다.