Download presentation
Presentation is loading. Please wait.
1
1.4 제어의 역전 (Inversion of Control, IoC)
2
1.4.1 오브젝트 팩토리 (Object Factory)
UserDaoTest에서 “관계설정 기능”의 분리 필요 UserDaoTest는 테스트 본연의 기능으로 한정 팩토리 (Factory) 객체의 생성 방법을 결정하고 생성한 객체를 돌려주는 객체
3
1.4.1 오브젝트 팩토리 (Object Factory)
팩토리를 사용하는 UserDaoTest UserDao가 어떻게 만들어졌는지 신경쓰지 않음 자신의 본래 관심사인 테스트에 집중 가능
4
1.4.1 오브젝트 팩토리 (Object Factory)
설계도로서의 팩토리 어플리케이션을 구성하는 컴포넌트들의 구조와 관계를 정의 어플리케이션의 컴포넌트 역할을 하는 객체들로부터 어플리케이션의 구조를 결정하는 객체를 분리함
5
1.4.1 오브젝트 팩토리 (Object Factory)
소스코드의 배포와 활용 어플리케이션을 구성하는 컴포넌트들의 구조와 관계를 정의 클래스와 api 설명서만 제공 클래스만 제공 하거나 샘플로 소스까지 제공할 수 있음 소스를 필수로 제공
6
↳ 1.4.2 오브젝트 팩토리의 활용 중복 코드 발생 수정 다양한 DAO의 DAO 생성 메소드의 추가로 인해 발생하는 중복
List 1-17 List 1-16 ↳
7
1.4.3 제어권 이전을 통한 제어관계 역전 전통적인 제어권 소유 방법 main() 메소드에서 활용할 객체 결정 및 생성
각 객체들은 주체적으로 자신 또는 다른 객체들의 메소드들을 호출 즉, 각 객체들이 프로그램의 흐름을 결정하거나 사용할 객체를 구성하는 작업에 능동적으로 참여 초난감 UserDao 소스 main() 메소드가 UserDao 객체 생성 UserDao가 능동적으로 자신이 사용할 ConnectionMaker 객체 결정 및 생성
8
1.4.3 제어권 이전을 통한 제어관계 역전 제어의 역전 (Inversion of Control) 제어의 역전 활용 예
임의의 객체는 자신이 사용할 다른 객체를 선택/생성하지 않는다. 객체 스스로가 향후 어떻게 만들어지고 어디서 사용될지 알 수 없다. 모든 제어 권한은 다른 객체에게 위임 제어의 역전 활용 예 서블릿 (JSP) 등의 컨테이너 안에서 동작하는 구조 서블릿을 개발해서 서버에 배포는 가능하지만 그 실행은 컨테이너가 제어함 스프링을 포함한 각종 프레임워크 프레임워크에 올려지는 각종 프로그램들은 프레임워크에서 직접 흐름이 제어된다. 프레임워크라는 이름 자체가 IoC를 사용하고 있다는 뜻
9
1.4.3 제어권 이전을 통한 제어관계 역전 UserDao와 DaoFactory에서의 제어의 역전 IoC의 장점
자신이 활용할 ConnectionMaker도 팩토리에 의해 생성되어 공급됨 DaoFactory는 가장 단순한 IoC 프레임워크 IoC의 장점 프로그램 소스 코드의 유연성 및 확장성 증가 스프링과 IoC IoC는 스프링에서 제공하는 모든 기능의 기초가 되는 기반기술
10
1.5 스프링의 IoC
11
1.5.1 오브젝트 팩토리를 이용한 스프링 IoC 빈 (Bean) 빈 팩토리 (Bean Factory)
스프링이 제어권을 가지고 직접 생성하고 관계를 부여하는 수동적인 제어의 역전이 적용된 객체 빈 팩토리 (Bean Factory) 빈의 생성, 등록, 조회 및 관계설정 제어를 담당하는 IoC 객체 보통은 빈 팩토리를 직접 사용하지 않고 이를 확장한 어플리케이션 컨텍스트 (Application Context)를 이용함 스프링에 o.s.beans.factory.BeanFactory 인터페이스가 존재
12
1.5.1 오브젝트 팩토리를 이용한 스프링 IoC 애플리케이션 컨텍스트 (Application Context)
스프링에 o.s.context.ApplicationContext 인터페이스 존재 o.s.beans.factory.BeanFactory 상속 o.s.context.ApplicationContext
13
1.5.1 오브젝트 팩토리를 이용한 스프링 IoC 설정 정보/설정 메타 정보 (Configuration Metadata)
애플리케이션의 형상 정보 또는 구성 정보 애플리케이션의 전체 그림이 그려진 청사진 (Blueprints) 컨테이너 (Container) 또는 IoC 컨테이너 IoC 방식으로 빈을 관리하는 의미에서 애플리케이션 컨테이너나 빈 팩토리를 일컫는 또 다른 단어 스프링 프레임워크 스프링이 제공하는 모든 기능을 통합하여 말할 때 사용하는 단어 스프링 컨테이너 ≒ IoC 컨테이너 ≒ 컨테이너 ≒ IoC 엔진 ≒ 애플리케이션 컨텍스트 ≒ 빈 팩토리
14
1.5.1 오브젝트 팩토리를 이용한 스프링 IoC 스프링 컨테이너가 사용할 설정정보를 담은 DataFactory 클래스
Java의 annotation 을 활용하여 설정정보를 기술
15
1.5.1 오브젝트 팩토리를 이용한 스프링 IoC @Configuration이 붙은 자바 코드 설정정보를 활용하는 애플리케이션 컨텍스트 생성 및 활용 AnnotationConfigApplicationContext 클래스 활용 userDao 빈 이름 지정 지정된 userDao() 메소드 호출 리턴 타입을 지정. 명시적 캐스팅이 필요없어짐
16
1.5.2 애플리케이션 컨텍스트의 동작방식 ApplicationContext의 역할
애플리케이션에서 IoC를 적용해서 관리할 모든 객체 대한 생성과 관계설정을 담당 하지만, 직접 객체를 생성하고 관계를 맺는 코드는 외부의 이 붙은 DaoFactory)를 통해 얻는다.
17
1.5.2 애플리케이션 컨텍스트의 동작방식 ApplicationContext 활용 장점
클라이언트는 구체적인 팩토리 클래스를 사용할 필요가 없다. 오브젝트 팩토리가 많아져도 문제 없음 이후 DaoFactory를 대체할 XML 방법 활용하면 더욱 편리함 종합적인 IoC 서비스를 제공받을 수 있다. 객체 자동생성, 객체 후처리, 정보 조합, 설정 방식의 다변화, 인터셉팅 등의 기능 활용 빈을 검색하는 다양한 방법을 제공받을 수 있다.
18
1.6 싱글톤 레지스트리와 오브젝트 스콥프
19
1.6.0 싱글톤 레지스트리 DaoFactory 직접사용 vs. 애플리케이션 컨텍스트 사용
애플리케이션 컨텍스트는 각각의 빈에 대해 Singleton으로 저장하고 관리하는 Singleton Registry이다.
20
1.6.1 싱글톤 레지스트리로서의 애플리케이션 컨텍스트
클라이언트/서버 구조에서의 Singleton Registry를 사용하지 않는다면… 상황 가정 요청 한개당 5개의 객체 생성 초당 500번의 요청이 들어옴 결과 초당 2500개의 새로운 객체 생성 한 시간이면 9백만개의 새로운 객체 생성 자바의 Garbage Collection 성능이 아무리 좋아도 서버의 자원 사용량이 매우 높아짐 서버의 동작 방식 (서블릿 동작 방식) 서블릿 클래스당 하나의 객체만 생성 사용자 요청당 스레드를 생성하여 멀티스레드 형태로 해당 객체를 공유하여 활용
21
1.6.1 싱글톤 레지스트리로서의 애플리케이션 컨텍스트
전통적인 자바에서의 Singleton 패턴 클라이언트/서버 환경에서 권장되는 서버 코딩 방법 패턴 전형적인 Singleton 패턴 구현 형태
22
1.6.1 싱글톤 레지스트리로서의 애플리케이션 컨텍스트
Singleton 패턴의 한계 private 생성자를 갖고 있기 때문에 해당 클래스는 상속 불가 객체 지향적 설계의 장점을 활용하기가 어려움 Static 필드와 메소드를 활용하는 것도 객체 지향적 설계에 위배됨 테스트 프레임워크에서의 활용 어려움 오브젝트 주입이 불가 IoC 활용 못함 테스트의 어려움 분산 서버 환경에서는 Signleton 패턴을 활용하더라도 여러 개의 독립된 객체 생성 가능 여러 개의 JVM에 분산 배치된 서버 애플리케이션 Static 필드는 Global State를 자연스럽게 만들기 때문에 멀티스레딩 환경에서 여러 위험에 처할 수 있음
23
1.6.1 싱글톤 레지스트리로서의 애플리케이션 컨텍스트
스프링의 Singleton Registry private 생성자/static 필드 및 메소드가 없는 평범한 클래스 객체에 대해서도 Singleton으로 활용하게 해줌 즉, 고전적인 Singleton 패턴을 대신하여 Singleton 객체를 생성하고 관리해주는 레지스트리 앞에서 언급한 한계점을 대부분 극복
24
1.6.2 싱글톤과 오브젝트의 상태 스프링의 Singleton 빈 (Bean) 객체 활용시 주의점
객체의 인스턴스 필드는 읽기 전용으로만 사용해야 함 잘못된 코딩 방식 대부분의 읽기/쓰기 변수는 메소드 내의 로컬 변수로 정의하거나 파라미터로 주고 받아야 함
25
1.6.3 스프링 빈의 스코프 빈 객체 Scope 스프링 빈 객체의 기본 Scope 스프링 빈 객체의 다른 Scope
빈 객체가 생성되고, 존재하고, 적용되는 시간/공간적인 범위 스프링 빈 객체의 기본 Scope Singleton Scope 컨테이너 내에 한 개의 객체로 생성 강제로 제거하지 않는 한 스프링 컨테이너 내에 계속해서 유지됨 스프링 빈 객체의 다른 Scope Prototype: 빈 요청할 때 마다 새로운 객체 생성 Request: http 요청때 마다 새로운 객체 생성 Session: http 세션과 동일한 Scope 유지 본 교재의 10장에서 자세히 다루게 됨
26
1.7 의존관계 주입 (DI, Dependency Injection)
27
1.7.1 제어의 역전 (IoC)와 의존 관계 주입 (DI)
설계 패턴 (Design Pattern)에서 사용되는 광범위하게 활용되는 용어 스프링이 제공하는 기능적 특징을 명확하게 설명 못함 의존관계 주입 (DI, Dependency Injection) 스프링에서 객체간의 관계설정 의도를 명확히 표현하는 용어 스프링을 다른 프레임워크와 차별화되어서 제공해주는 기능은 DI 라는 용어를 사용할 때 분명하게 드러남
28
1.7.2 런타임 의존관계 설정 의존 관계 (Dependency) 클래스의 의존관계 UML 다이어그램 “A가 B에 의존한다“
B의 기능이 추가 및 변경되거나 메소드 형식이 변경되면 그 영향이 A로 전달됨 의존관계에는 방향성이 있다.
29
1.7.2 런타임 의존관계 설정 UserDao의 의존관계 의존 오브젝트 (Dependent Object)
인터페이스를 통한 느슨한 결합을 갖는 의존관계 ConnectionMaker의 변경사항은 UserDao에 직접적인 영향을 준다. DConnectionMaker의 변경사항은 UserDao에 영향을 주지 않는다 낮은 결합도 의존 오브젝트 (Dependent Object) 런타임시에 의존관계를 맺는 대상 객체 UserDao의 의존 오브젝트는 DConnectionMaker 객체
30
1.7.2 런타임 의존관계 설정 스프링에서의 의존관계 주입 조건
클래스 모델이나 코드에서는 런타임 시점의 의존관계가 잘 드러나지 않는다. 인터페이스 사용 런타임 시점의 의존관계는 스프링 컨테이너 (애플리케이션 컨텍스트)같은 제 3의 객체가 결정한다. 스프링 컨테이너 = DI 컨테이너 의존관계는 사용할 (의존할) 객체에 대한 레퍼런스를 제 3의 객체가 제공 (주입, DI)해줌으로써 만들어진다.
31
1.7.2 런타임 의존관계 설정 UserDao의 의존관계 주입 DI 컨테이너에서 활용할 의존관계 주입을 위한 코드
32
1.7.2 런타임 의존관계 설정 UserDao의 의존관계 주입 런타임 시에 의존관계 주입을 수행하는 주체는 제 3의 존재이다.
예를 들어 DaoFactory가 담당 의존관계 주입을 담당하는 컨테이너, DI 컨네이너라고 부른다. 런타임 시의 의존관계 주입과 사용되는 의존관계
33
1.7.2 런타임 의존관계 설정 의존관계 검색 (vs. 의존관계 주입) 가능하면 의존관계 주입 (DI) 사용
의존관계 검색 (DL, Dependency Lookup)을 이용하는 UserDao 생성자 애플리케이션 컨텍스트에게 getBean() 메소드 활용 의존관계 검색(DL)은 다소 코드가 지저분하다. 가능하면 의존관계 주입 (DI) 사용
34
1.7.2 런타임 의존관계 설정 반드시 의존관계 검색을 활용해야 할 때 main()과 같은 애플리케이션 수행 메소드
애플리케이션을 기동하는 시점에서는 어쩔 수 없이 최소한 한번은 DL을 통해 객체를 가져와야 한다. 스태틱 메소드인 main()에서는 DI를 통해 객체를 주입받을 수 없음 스프링 빈 (의존 오브젝트)을 사용할 객체가 빈이 아닐 때 UserDao는 빈이 아니고 ConnectionMaker만 빈일 때 즉, 의존관계 주입 (DI)을 받기 원하는 객체는 자신도 컨테이너가 관리하는 빈이 되어야 한다. 의존관계 주입은 DI 컨네이터가 수행
35
1.7.4 의존관계 주입의 응용 사례 1. 개발용과 운영용 객체의 교환 개발용 ConnectionMaker 생성 코드
개발 중에는 로컬 DB를 사용 운영용 ConnectionMaker 생성 코드 운영서버에 배포할 시에는 서버가 제공하는 DB를 사용 배포시점에 오른쪽과 같이 한 줄 변경
36
1.7.4 의존관계 주입의 응용 사례 2. 부가기능 추가 연결횟수 카운팅 기능이 있는 DB 연결 객체 반환 클래스
37
1.7.4 의존관계 주입의 응용 사례 2. 부가기능 추가 CountingConnectionMaker 의존관계가 추가된 DI 설정용 클래스 런타임 오브젝트 의존관계
38
1.7.4 의존관계 주입의 응용 사례 2. 부가기능 추가 CountingConnectionMaker에 대한 테스트 클래스
39
1.7.5 메소드를 이용한 의존관계 주입 다양한 의존관계 주입 방법 생성자를 이용한 주입 setter 메소드를 이용한 주입
반드시 setXxx(…) 라는 메소드 이름 형태를 지님 한 개의 파라미터 한번에 하나의 객체만 주입받음 가장 많이 활용되어 왔음
40
1.7.5 메소드를 이용한 의존관계 주입 다양한 의존관계 주입 방법 setter 메소드를 이용한 DI를 사용하는 팩토리 메소드
일반 메소드를 이용한 주입 메소드 이름을 다양하게 정할 수 있음 여러 개의 파라미터 한번에 여러 개의 객체를 주입 받을 수 있음
41
1.8 XML을 이용한 설정
42
1.8.0 XML을 이용한 설정 설정 정보 구성의 다변화 자바 코드를 통한 설정 정보(DaoFactory) 구성의 단점
DI 구성이 변경될 때 마다 재컴파일 과정 필요 그러한 설정 정보 구성은 대부분 틀에 박힌 뻔한 구조 대안 XML 활용 단순 텍스트 파일 컴파일의 별도 과정 요구되지 않음 XML스키마를 이용하여 정해진 포맷대로 작성되었는지 쉽게 확인 가능
43
1.8.1 XML 설정 클래스 설정과 XML 설정의 대응 항목 빈 설정
connectionMaker() 메소드의 <bean> 태그 전환
44
1.8.1 XML 설정 의존 관계 주입 빈 객체에 setter 메소드 존재 userDao 빈 객체 선언 및 의존관계 동시 주입
45
1.8.1 XML 설정 완성된 XML 설정 파트 설명 applicationContext.xml XML 선언
beans 루트 엘리먼트: 설정 파일임을 지정함 beans 루트 엘리먼트 속성으로 XML 스키마 지정 myConnectionMaker 빈 객체 선언 userDao 빈 객체 선언 및 의존 관계 주입 applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" xmlns:xsi=" xsi:schemaLocation=" <bean id="myConnectionMaker" class="springbook.user.dao.DConnectionMaker“ /> <bean id="userDao" class="springbook.user.dao.UserDao"> <property name="connectionMaker" ref="myConnectionMaker" /> </bean> </beans>
46
1.8.1 XML 설정 전략 패턴을 XML 설정에 기술하는 방법
동일한 인터페이스를 구현한 의존 오브젝트들을 여러 개 정의해 두고 그 중에서 원하는 것을 골라서 DI 하는 방법
47
1.8.2 XML 설정을 이용하는 애플리케이션 컨텍스트
애플리케이션 컨텍스트 설정 코드 //ApplicationContext context // = new AnnotationConfigApplicationContext(DaoFactory.class); ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); //daoContext.xml이 springbook.user.dao 패키지 안에 있을 때 = new GenericXmlApplicationContext("springbook/user/dao/daoContext.xml"); //UserDao.class로 부터의 상대위치를 지정할 때 = new ClassPathXmlApplicationContext("daoContext.xml", UserDao.class);
48
1.8.3 DataSource 인터페이스로 변환 DataSource 인터페이스 및 구현 클래스 사용
ConnectionMaker 대신 DB 커넥션 기능을 제공하는 전통적인 자바 및 스프링 라이브러리 사용 권장 DataSource 인터페이스
49
1.8.3 DataSource 인터페이스로 변환 DataSource 인터페이스를 사용하는 UserDao
50
1.8.3 DataSource 인터페이스로 변환 DaoFactory를 통한 설정
org.springframework.jdbc.datasource.SimpleDriverDatasource
51
1.8.3 DataSource 인터페이스로 변환 DaoFactory를 통한 설정
DataSource 빈을 DI 받는 userDao 빈 정의
52
1.8.4 프로퍼티 값의 주입 XML을 통한 설정 객체 주입이 아닌 단순 값 주입 방법
53
1.8.4 프로퍼티 값의 주입 XML을 통한 설정 완성된 설정 파일
Similar presentations