제어의 역전(IoC: Inversion of Control)
。개발자가 아닌Spring Framework( =Spring Context)가자바객체의 전반적인생명주기를 대신 관리하는 특성을 의미
。IoC를 통해객체들이약한 결합이 되고,재사용성과테스트 용이성이 향상
Spring의IoC:
。개발자가new를 통해자바객체를 직접 생성하는게 아닌Spring Context에 의해Spring Bean을 생성 및 관리를 수행하는 특성
。어플리케이션 Runtime시Spring Context에 의해Spring Bean을 자동으로 생성하여 필요한 곳으로Auto-Wiring하여DI를 통해주입하여 공급 후폐기하는Runtime System구축
Spring Container( =IoC Container,Spring Context)
。등록된Spring Bean의 전체Life Cycle과Dependency의 관리를 수행
▶Spring Bean의생성, 초기화, 구성, 파괴를 수행
。Spring Context는 기본으로 제공하는 전역의Spring Context와 직접SpringContext 구현체를 생성하여 활용하는 방식이 존재
▶ 보통 전역의Spring Context를 활용
。Spring Bean의 제어권이개발자가 아닌Spring Context에 위임되어 전반적인생명주기가 관리되므로IoC의 특징을 가진다
。Spring Context내Spring Bean생성 시카멜케이스로 생성됨
ex )helloWorld
。Spring Context로 등록된A 클래스의Spring Bean을 생성 시new없이A a = A()를 선언
▶Spring Context의Bean Registry에서 가져와서Auto-Wiring을 거쳐DI를 통해Spring Bean을 주입A a = A() // Spring Context의 Bean Registry에서 주입 A b = new A() // HEAP에서 POJO로 생성
。Spring Bean은GC대신Spring Context에 의해파괴가 수행
▶new를 통해HEAP 영역에서 생성되는POJO가 제때GC되지않아메모리에서 누적되어 발생하는OOM문제를 해결가능.
Bean Registry
。Spring Context의 내부에서Spring Bean이 저장되어생명주기를 관리하는 저장소
Spring Context에Spring Bean등록 시Map<String,Class>로 저장
。key : Spring Bean 클래스명의카멜케이스명칭
。Value:Spring Bean 클래스명.class
▶클래스 리터럴
Spring Context에 의한Spring Bean의Life Cycle
。어플리케이션 Runtime시Spring Context에 의해Spring Bean을 자동으로 생성하여 필요한 곳으로Auto-Wiring하여DI를 통해주입하여 공급 후폐기하는Runtime System구축
1.Spring Context시작
。어플리케이션 런타임시전역으로 시작됨
2.Spring Bean으로 등록된클래스를 조회하여 정의 및 설정
。Spring Context내Bean Registry에 해당클래스 정보를Spring Bean정보로서 등록
3.Spring Bean생성
。Bean Registry에서 등록된클래스 정보를 기반으로Spring Bean을 생성 혹은 관리
▶new를 통한POJO로 생성되는게 아님을 인지
4.의존성 주입(DI) 수행
。Spring Context가Bean Registry내 저장된Spring Bean을 필요로 하는의존객체에의존성을 정의하여Auto-Wiring하여Spring Bean을주입
5. 초기화
。init method,@PostConstruct
6. 사용
7. 소멸
。destroy method,@ PreDestroy
。사용이 끝난 경우 자동으로Sprint Context에 의해폐기
▶GC가 아닌Spring Context에 의해 폐기
Spring Context구현체종류
Bean FactoryInterface :
。기본적인 형식의Spring Context
。현재는 거의 사용하지 않는다.
ApplicationContextInterface :
。Enterprise 기능이 존재하는 발전된 형식의Spring Context 인터페이스
▶BeanFactory의하위 인터페이스
。현재 가장 많이 사용되는 유형의Spring Context
▶Web Application,REST API,Spring AOP등에서 주로 사용.
ApplicationContext 구현체생성
。전역의ApplicationContext가 아닌구현체를 생성
▶Spring Bean을전역 Spring Context와 별개로 독립적으로 저장되어수명주기의 관리가 수행됨
GenericApplicationContext
new GenericApplicationContext()
。기본적인Spring Bean저장기능 +수명주기를 관리하는 역할만 수행하는Context 구현체
▶객체.refresh()를 호출해야 등록된Spring Bean이 초기화되어 호출가능
AnnotationConfigApplicationContext
new AnnotationConfigApplicationContext(Configuration클래스.class)
。GenericApplicationContext를 상속한Context 구현체로서 추가 기능을 정의
▶ 내부에@Bean이 정의된Configuration Class를 생성자에 전달하여Context 구현체 생성과 동시에Spring Bean을 등록할 수 있다.
▶객체.refresh()를 호출하지 않아도 자동으로Spring Bean의 초기화가 수행됨
。해당Context 구현체를 포함하는Class에@ComponentScan("패키지경로")선언 시 해당패키지경로하위Spring Bean들을Context 구현체로 전부 식별 및 등록.@ComponentScan("com.ktcloud.springpractice") public class AAAA { public static void main(String[] args) { try( var springContext = new AnnotationConfigApplicationContext(AAAA.class)){ Arrays.stream(springContext.getBeanDefinitionNames()).forEach(System.out::println); } } }。
com.ktcloud.springpractice하위Spring Bean들이 전부springContext 구현체로 등록
。SpringContext 구현체에 등록된Spring Bean의 이름 출력
▶camelCase임을 확인가능
SpringContext구현체 관련 메소드
SpringContext객체.registerBean(POJO.class)
。해당SpringContext 구현체에POJO를Spring Bean으로서 등록
▶ 일반자바객체를Spring Bean으로서 등록하는 역할을 수행
SpringContext객체.getBean("SpringBean이름" or SpringBeanClass명.class)
。해당Spring Context에 포함된 특정Spring Bean을 호출
Class Type으로Spring Bean을 가져올 경우
SpringContext객체.getBean(클래스타입.class)
。동일한Interface를 구현하는Spring Bean을 반환하는@Bean method가 복수 존재 시@Primary로 설정된@Bean Method의Spring Bean을 우선시하여 가져온다.
Spring Bean에게 할당된 이름으로Spring Bean을 가져오는 경우
SpringContext객체.getBean("스프링빈이름", 클래스타입)
。Spring Bean의명칭으로 참조 시클래스타입을 추가정의
▶클래스타입을 정의하지 않으면Object Type의Spring Bean으로 반환
。Spring Bean 이름은Spring Context에 의해카멜케이스로 작성됨을 유의
▶@Bean method의Spring Bean인 경우@Bean(name="이름")을 통해 개발자가 임의로 부여가능
SpringContext객체.getBeanDefinitionNames())
。특정SpringContext객체에서 정의된 모든Spring Bean의 이름이 정의된 문자열 벡터(string[])를 반환.
Arrays.stream(SpringContext객체.getBeanDefinitionNames()).forEach(System.out::println);
。 특정SpringContext객체의 Spring Bean의 이름을 나열.