2020. 5. 2. 20:05ㆍ인프런/스프링 입문
스프링 IOC
IOC
IOC(Inversion of Control)는 역 제어라는 뜻으로 제어권의 반환을 뜻합니다. 기존의 개발자들이 New 연산자, 인터페이스 호출, 팩토리 호출 방식으로 객체의 인스턴스를 생성함으로 인스턴스 생성 방법에 대한 제어권을 개발자들이 가지고 있었습니다.
여기서 IOC란 인스턴스 생성의 제어를 개발자 본인이 아닌 다른 누군가에게 반환 준다는 개념입니다. 여기서 말하는 다른 누군가란 EJB, Java Servlet 등 bean을 관리해 주는 컨테이너입니다.
즉 IOC 란 인스턴스의 생성부터 소멸까지의 인스턴스의 생명주기 관리를 내가 아닌 컨테이너가 대신해준다는 뜻입니다.
EJB와 Java Servlet에 대해 간략한 설명
- EJB란
엔터프라이즈 자바 빈즈는 기업환경의 시스템을 구현하기 위한 서버 측 컴포넌트 모델입니다. 즉, EJB는 애플리케이션의 업무 로직을 가지고 있는 서버 애플리케이션입니다. - Java Servlet란
자바 서블릿은 자바를 사용하여 웹페이지를 동적으로 생성하는 서버 측 프로그램 혹은 그 사양을 말하며, 흔히 "서블릿"이라 불립니다. 자바 서블릿은 웹 서버의 성능을 향상하기 위해 사용되는 자바 클래스의 일종입니다.
Spring 컨테이너
Spring 컨테이너는 IOC를 지원합니다.
여기서 Spring 컨테이너란 beans를 관리하고 애플리케이션 중요 부분을 형성합니다. 즉 Spring 컨테이너는 메타데이터(xml 설정)를 통해 bean를 인스턴스화 하고 이를 조합하여 관리하는 역할을 합니다. 컨테이너는 관리되는 bean 들을 의존성 삽입(Dependency Injection)을 통해 IOC를 지원합니다.
스프링 컨테이너의 두 종류
1. 빈 팩토리 BeanFactory (org.springframework.beans.factory.BeanFactory)
DI의 기본사항을 제공하는 가장 단순한 컨테이너입니다
팩토리 디자인 패턴을 구현한 것. Bean(이하 빈) 팩토리는 빈을 생성하고 분배하는 책임을 지는 클래스
빈 팩토리가 빈의 정의는 즉시 로딩하는 반면, 빈 자체가 필요하게 되기 전까지는 인스턴스화를 하지 않습니다 (lazy loading, 게으른 호출)
BeanFactory factory = new XmlBeanFactory(new FileInputStream("bean.xml"));
MyBean myBean = (Mybean) factory.getBean("myBean");
getBean()이 호출되면, 팩토리는 의존성 주입을 이용해 빈을 인스턴스 화하고 빈의 특성을 설정하기 시작. 여기서 빈의 일생이 시작됩니다.
2. 애플리케이션 콘텍스트 ApplicationContext (org.springframework.context.factory.BeanFactory)
빈 팩토리와 유사한 기능을 제공하지만 좀 더 많은 기능을 제공하는 애플리케이션 콘텍스트입니다
빈 팩토리보다 추가적으로 제공하는 기능입니다
- 국제화가 지원되는 텍스트 메시지를 관리해 준다.
- 이미지 같은 파일 자원을 로드할 수 있는 포괄적인 방법을 제공해준다.
- 리너스로 등록된 빈에게 이벤트 발생을 알려준다.
따라서 대부분의 애플리케이션에서는 빈 팩토리보다는 애플리케이션 콘텍스트를 사용하는 것이 좋습니다.
가장 많이 사용되는 애플리케이션 콘텍스트 구현체
- ClassPathXmlApplicationContext : 클래스 패스에 위치한 xml 파일에서 콘테스트 정의 내용을 읽어 들인다.
- FileSystemxmlApplicationContext : 파일 경로로 지정된 xml 파일에서 콘테스트 정의 내용을 읽어 들인다.
- XmlWebApplicationContext : 웹 애플리케이션에 포함된 xml 파일에서 콘테스트 정의 내용을 읽어 들인다.
ApplicationContext context = new ClassPathXmlApplicationContext("conf/bean.xml");
MyBean bean = context.getBean("myBean");
빈 팩토리와 애플리케이션콘텍스트의 기능상의 차이점 말고 또 다른 차이점은 다음과 같습니다.
- 빈 팩토리 : 처음으로 getBean()이 호출된 시점에서야 해당 빈을 생성(lazy loading)
- 애플리케이션 콘텍스트 : 콘텍스트 초기화 시점에 모든 싱글톤 빈을 미리 로드한 후 애플리케이션 기동 후에는 빈을 지연 없이 얻을 수 있음(미리 빈을 생성해 놓아 빈이 필요할 때 즉시 사용할 수 있도록 보장)
Spring Bean
Spring Bean이란 Spring에서 POJO(plain, old java object)를 ‘Beans’라고 부릅니다. Beans는 애플리케이션의 핵심을 이루는 객체이며, Spring IoC(Inversion of Control) 컨테이너에 의해 인스턴스화, 관리, 생성됩니다. Beans는 우리가 컨테이너에 공급하는 설정 메타 데이터(XML 파일)에 의해 생성됩니다. 컨테이너는 이 메타 데이터를 통해 Bean의 생성, Bean Life Cycle, Bean Dependency(종속성) 등을 알 수 있다.
애플리케이션의 객체가 지정되면, 해당 객체는 getBean() 메서드를 통해 가져올 수 있다.
Spring Bean정의
일반적으로 XML 파일에 정의합니다.
주요 속성
- class(필수): 정규화된 자바 클래스 이름
- id: bean의 고유 식별자
- scope: 객체의 범위 (sigleton, prototype)
- constructor-arg: 생성 시 생성자에 전달할 인수
- property: 생성 시 bean setter에 전달할 인수
- init method와 destroy method
Spring Bean Scope
스프링은 기본적으로 모든 bean을 Singleton으로 생성하여 관리합니다. 구체적으로 애플리 케이션 구동 시 JVM안에서 스프링이 bean마다 하나의 객체를 생성하는 것을 의미합니다
그래서 우리는 스프링을 통해 bean을 제공받으며 언제나 주입받은 bean은 동일한 객체라는 가정하에 개발합니다
request, session, global session의 Scope는 일반 Spring 애플리케이션이 아닌 Spring MVC Web Application에서만 사용이 됩니다.
Singleton
singleton bean은 Spring 컨테이너에서 한번 생성이 됩니다 그리고 컨테이너가 사라질 때 bean도 제거됩니다.
생성된 하나의 인스턴스는 single beans cache에 저장되고 해당 bean에 대한 요청과 참고가 있으면 캐시 된 객체를 반환합니다 즉 하나만 생성되기 때문에 동일한 것을 참조합니다.
기본적으로 모든 bean은 scope가 명시적으로 지정되지 않으면 Singleton입니다.
Prototype
prototype bean은 모든 요청에서 새로운 객체를 생성하는 것을 의미합니다. 즉, prototype bean은 의존성 관계의 bean에 주입될 때 새로운 객체가 생성되어 주입이 됩니다. 정상적인 방식으로 gc에 의해 bean이 제거된다.
DI (Dependency Injection)
DI(의존성 삽입)은 Spring 컨테이너가 IOC를 지원하는 새로운 형태입니다.
여기서 DI는 클래스 사이의 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동적으로 연결해 주는 것을 의미합니다.
Spring 컨테이너가 지원하는 DI는 두 가지 유형이 있습니다.
첫 번째 방법은 A객체가 B와 C 객체를 New 생성자를 통해서 직접 생성하는 방법이고 두 번째는 외부에서 생성된 객체를 setter()나 생성자를 통해 사용하는 방법입니다.
두 번째 방법의 그림을 보시면 A객체에서 직접 생성하지 않고 외부에서 생성된 객체를 setter() 혹은 생성자를 이용해서 사용합니다 이런 걸 주인 한다고 하며 스프링에서 사용하는 방식(DI)인 것입니다 스프링은 다른 객체들이 사용하고 다른 서비스를 위해 사용할 수 있는 클래스를 컨테이너 형태로 이 기능을 제공해줍니다 A라는 객체에서 B, C 객체를 사용(의존)할 때 A객체에서 직접 생성을 하는 것이 아닌 외부(IOC컨테이너)에서 생성된 B, C 객체를 조립(주입)시켜 setter 혹은 생성자를 통해 사용할 수 있습니다