August 20, 2021
어떤 객체가 협력하기 위해 다른 객체를 필요로 하는 상태를 의미한다.
의존성은 실행 시점과 구현 시점에 서로 다른 의미를 갖는다.
프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것을 의미한다.
라이브러리를 사용하는 애플리케이션 코드는 애플리케이션 흐름을 직접 제어하지만 프레임워크는 거꾸로 애플리케이션 코드가 프레임워크에 의해 사용된다.
프레임워크가 흐름을 주도하면서 개발자가 만든 애플리케이션 코드를 사용하는 것이다.
개별 객체들의 의존관계 설정이 자동으로 이루어지고 객체들의 생성과 파괴 조합 등을 관장한다.
객체를 생성하고 관리하면서 의존관계를 연결해준다.
-> 스프링에서는 ApplicationContext 라는 인터페이스로 제공한다,
bean : IoC 컨테이너에서 관리되어지는 객체를 말한다.
configuration metadata : 실제 빈 정보를 configuration metadata로부터 받아온다.
ApplicationContext 인터페이스의 구현체
객체 사이의 의존 관계를 스프링 설정 파일에 등록된 정보를 바탕으로 IoC 컨테이너가 자동으로 처리하는 것을 의미한다.
IoC를 다양한 방법으로 만들 수 있다. - 전략패턴, 서비스 로케이터 패턴, 팩토리 패턴, 의존관계 주입패턴 등이 있다.
생성자를 통해서 주입을 받는 패턴을 생성자 주입 패턴이라고 한다
setter기반, 필드 기반(Autowired) 의존관계 주입 방법도 있다.
스프링 IoC 컨테이너에서 빈이 잘못 등록될 수 있다.
Circular dependencies : A -> B 참조 / B -> A 참조할 경우 순환 의존관계가 형성되면서 BeanCurrentlyInCreationException
예외가 발생할 수 있다.
스프링이 직접 클래스를 검색해서 자동으로 빈을 등록한다.
@Configuration 클래스에서 빈을 등록 안해도 된다.
stereotype 어노테이션을 이용하여 찾는다.
스프링에서 여러 개의 stereotype 어노테이션으로 용도에 맞게 분류했다. 빈들을 모두 동일시하게 생각하지 않고 용도에 맞게 분류시킨 것이다.
컴포넌트 스캔은 @Configuration 클래스 파일이 있는 동일한 패키지 내에서 수행된다.
어노테이션은 인터페이스가 아닌 구현클래스에 붙인다.
컴포넌트 스캔 제외 대상을 지정할 수 있다.
excludeFilters @Component.Filter(type = Filter.ASSIGNABLE_TYPE, value = MemoryRepo.class)
@Autowired 어노테이션을 사용하면 IoC 컨테이너가 자동으로 주입한다.
필드에 적용할 수 있고, setter에 적용할 수도 있다.
생성자가 두 개일 경우에는 스프링에 자동으로 주입이 되는 생성자에 @Autowired를 달아주어야 한다.
자동 주입이 가능한 빈이 2개 이상이면 어떤 빈이 주입되어야 하는지 선택해야한다. 스프링은 무슨 객체를 주입해야하는지 모르기 때문에 에러가 발생한다.
-> 우선시 되는 빈에 @Primary 달아준다.
-> 등급이 같지만 다른 용도면 @Qualifier 달아준다. 사용하는 쪽에서 둘 중에 무엇을 쓸지 @Qualifer로 선택한다.
getBean()을 할 경우 Qualifer 전달할 방법이 없다.
BeanFactoryAnnotationUtils를 이용해서 해결한다.
대체로 @Qualifier 보다는 @Primary를 이용한다. 동일한 객체를 만들지 않는다. -> 쓰는 쪽에서 고민하지 않게 하는게 제일 좋다.
@SpringBootApplication : 컴포넌트 스캔을 포함하고 있다.
Bean이 어떤 범위로 만들어지는지를 의미한다. 기본적으로 싱글톤 스코프를 가진다.
Bean definition을 작성하면 스프링에게 어떻게 객체를 만들어야하는지 알려준다. 하나의 Bean definition에 의해 여러 객체가 만들어질 수 있고 단 하나만 만들어질 수 있다. 단 하나만 만들어지는 것을 싱글톤 스코프라고 한다.
싱글톤 스코프의 빈을 조회하면 스프링 컨테이너는 항상 같은 인스턴스의 스프링 빈을 반환한다.
프로토타입 스코프의 빈을 스프링 컨테이너에 조회하면 스프링 컨테이너는 항상 새로운 인스턴스를 생성해서 반환한다.
스프링 컨테이너는 객체 생성과 소멸 - 생명주기를 관리한다.
스프링 컨테이너 조차도 생명주기를 가진다.
ApplicationContext.close() 소멸 : 컨테이너에 등록된 모든 빈이 소멸된다. -> 소멸에 대한 콜백들이 동작한다.
빈 생성 생명주기 콜백
빈 소멸 생명주기 콜백