Angular2는 컴포넌트 중심의 개발 접근 방식에 대한 내용을 가집니다. 따라서 본 슬라이드도 컴포넌트 중심의 개발 접근 방식으로 Angular2를 바라보았습니다.
대략적인 내용은 다음과 같습니다.
- Angular2 History
- Angular2 핵심구성요소
- 컴포넌트 중심의 개발
- Angular2 주요개념
- Type Script에대한 설명
- 기타
필요하신 분에게 도움이 되었으면 좋겠습니다. 관련 코드는 다음 주소에 공유하였습니다.
https://github.com/DaeguDevGroup/angular2-bootstrap
- 내용이 업데이트되거나, 추가되면 설명에 이력을 남기겠습니다.
- 본 슬라이드에 오류가 있다면 코멘트 바랍니다.
*Change Log*
- 2016-05-14 : 슬라이드 첫 버전을 업로드
“오라클자바몰”이라는 회사를 만들어서 내가 잘 아는 분야인 차를 팔기로 정했다. 차량의 구매는 현대자동차와하고, 현대자동차에 돈을 지불하고 차를 받기로 했다.
STS
New → Project → Spring Legacy Project
Project Name : carmaker
Simple Projects : Simple Spring Maven
프로젝트생성후
- 프로젝트 루트 아래의 pom.xml 파일을 오픈 후 스프링 버전을 4.2.0으로 변경
src/main/java 아래에서 edu.biz.ioc 패키지 생성
스프링 컨테이너는 base-package의 클래스를 검색해서 자동으로 자바빈으로 등록하는데 이에 해당하는것이 @Component, @Repository, @Service, @Contoroller, @RestController 어노테이션이다.
자동스캔을 위해서는 <context:component-scan /> 과 같이 base-package를 기술하며, 패키지가 여럿인 경우, 콤마로 구분하여
기술한다.
Angular 2는 HTML 5 웹 컴포넌트 기술을 포함합니다. 이 기술은 Angular 2 컴포넌트를 존재케한 기반기술입니다. 본 슬라이드는 이와 관련하여 2가지 흐름을 가지고 있습니다.
- 전반부는 웹 컴포넌트가 Angular 2 컴포넌트가 되기까지의 과정을 설명합니다.
- 후반부는 컴포넌트 트리 구조를 기반으로한 컴포넌트 상호작용에 대해 설명합니다.
필요하신 분에게 조금이라도 도움이 되었으면 좋겠습니다. 감사합니다.
CHANGE LOG
2016-06-27 : @input 데코레이터 설명교정
2016-06-26 : 쉐도우 돔 / 쉐도우 호스트관련 보다 정확한 문장으로 수정
2016-06-25 : 업로드
AngularJS 2는 올해 릴리징된 프론트엔드 도구 중 가장 쿨하고 섹시한 도구라고 독자는 믿고있습니다.
AngularJS 2를 실무환경에 적용함으로 얻는 이점.
AngularJS 2와 1의 차이점과 성능.
그리고 ReactJS와 AngularJS 2를 비교하여 퍼포먼스 데이터를 보여줍니다.
마지막으로 AngularJS 2 사용을 위한 번들러(Bundler) 그 중 Webpack, Systemjs, JSPM에 대해서도 안내합니다.
해당 자료는 XECon 2016에 발표되었습니다.
파울러는 2004년의 글에서 제어의 어떤 측면이 역행되는 것인지에 대한 의문을 제기하고 의존하는 객체를 역행적으로 취득하는 것이라는 결론을 내렸다. 그는 그와 같은 정의에 기초하여 제어 역행이라는 용어에 좀 더 참신한 ‘의존성주입(DI,dependency injection)’이라는 이름을 지어줬다.
모든 어플리케이션은 비즈니스 로직을 수행하기 위해 서로 협업하는 둘 또는 그 이상의 클래스들로 이뤄진다. 전통적으로 각 객체는 협업 할 객체의 참조를 취득해야 하는 책임이 있다.
이것이 의존성이다. 이는 결합도가 높으며 테스트하기 어려운 코드를 만들어낸다.
IoC를 적용함으로써 객체들은 시스템 내의 각 객체를 조정하는 어떤 외부의 존재에 의해 생성시점에서 의존성을 부여 받는데, 의존성이 객체로 주입(inject)된다는 말이다. 따라서 IoC는 한 객체가 협업해야 하는 다른 객체의 참조를 취득하는 방법에 대한 제어의 역행이라는 의미를 갖는다.
일반적으로 IoC는 의존성주입(DI), 의존성룩업(DL) 두 개의 하위부류로 나눌 수 있으며, 일반적으로 DI를 이야기 할 때는 IoC를 가리키지만 IoC를 이야기할 때는 DI를 가리키는 것은아니다. DI도 여러 종류 (세터주입,생성자주입,메소드주입)가 있지만 DL의 경우도 의존성 풀과 컨텍스트화된 의존성룩업(CDL) 두 종류가 있다.
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기Kenneth Ceyer
GDG DevFest 2017 Seoul
프론트엔드 모던 프레임워크 낱낱히 파헤치기 세션의 발표자료입니다.
이 발표자료에서는 여러분이 항상 궁금해 하신
프론트엔드 프레임워크의 삼총사
Angular, React, VueJS를 다차원적으로 깊이있게 비교하고 각각의 이점과 특화된 기능을 소개하고 있습니다.
이러한 프레임워크를 경험해보지 못한 분들을 위해 프레임워크 별로 특징부터 쉽게 접근하여 설명하기 때문에 경험 불문하고 가볍게 읽어 보실 수 있습니다.
“오라클자바몰”이라는 회사를 만들어서 내가 잘 아는 분야인 차를 팔기로 정했다. 차량의 구매는 현대자동차와하고, 현대자동차에 돈을 지불하고 차를 받기로 했다.
STS
New → Project → Spring Legacy Project
Project Name : carmaker
Simple Projects : Simple Spring Maven
프로젝트생성후
- 프로젝트 루트 아래의 pom.xml 파일을 오픈 후 스프링 버전을 4.2.0으로 변경
src/main/java 아래에서 edu.biz.ioc 패키지 생성
스프링 컨테이너는 base-package의 클래스를 검색해서 자동으로 자바빈으로 등록하는데 이에 해당하는것이 @Component, @Repository, @Service, @Contoroller, @RestController 어노테이션이다.
자동스캔을 위해서는 <context:component-scan /> 과 같이 base-package를 기술하며, 패키지가 여럿인 경우, 콤마로 구분하여
기술한다.
Angular 2는 HTML 5 웹 컴포넌트 기술을 포함합니다. 이 기술은 Angular 2 컴포넌트를 존재케한 기반기술입니다. 본 슬라이드는 이와 관련하여 2가지 흐름을 가지고 있습니다.
- 전반부는 웹 컴포넌트가 Angular 2 컴포넌트가 되기까지의 과정을 설명합니다.
- 후반부는 컴포넌트 트리 구조를 기반으로한 컴포넌트 상호작용에 대해 설명합니다.
필요하신 분에게 조금이라도 도움이 되었으면 좋겠습니다. 감사합니다.
CHANGE LOG
2016-06-27 : @input 데코레이터 설명교정
2016-06-26 : 쉐도우 돔 / 쉐도우 호스트관련 보다 정확한 문장으로 수정
2016-06-25 : 업로드
AngularJS 2는 올해 릴리징된 프론트엔드 도구 중 가장 쿨하고 섹시한 도구라고 독자는 믿고있습니다.
AngularJS 2를 실무환경에 적용함으로 얻는 이점.
AngularJS 2와 1의 차이점과 성능.
그리고 ReactJS와 AngularJS 2를 비교하여 퍼포먼스 데이터를 보여줍니다.
마지막으로 AngularJS 2 사용을 위한 번들러(Bundler) 그 중 Webpack, Systemjs, JSPM에 대해서도 안내합니다.
해당 자료는 XECon 2016에 발표되었습니다.
파울러는 2004년의 글에서 제어의 어떤 측면이 역행되는 것인지에 대한 의문을 제기하고 의존하는 객체를 역행적으로 취득하는 것이라는 결론을 내렸다. 그는 그와 같은 정의에 기초하여 제어 역행이라는 용어에 좀 더 참신한 ‘의존성주입(DI,dependency injection)’이라는 이름을 지어줬다.
모든 어플리케이션은 비즈니스 로직을 수행하기 위해 서로 협업하는 둘 또는 그 이상의 클래스들로 이뤄진다. 전통적으로 각 객체는 협업 할 객체의 참조를 취득해야 하는 책임이 있다.
이것이 의존성이다. 이는 결합도가 높으며 테스트하기 어려운 코드를 만들어낸다.
IoC를 적용함으로써 객체들은 시스템 내의 각 객체를 조정하는 어떤 외부의 존재에 의해 생성시점에서 의존성을 부여 받는데, 의존성이 객체로 주입(inject)된다는 말이다. 따라서 IoC는 한 객체가 협업해야 하는 다른 객체의 참조를 취득하는 방법에 대한 제어의 역행이라는 의미를 갖는다.
일반적으로 IoC는 의존성주입(DI), 의존성룩업(DL) 두 개의 하위부류로 나눌 수 있으며, 일반적으로 DI를 이야기 할 때는 IoC를 가리키지만 IoC를 이야기할 때는 DI를 가리키는 것은아니다. DI도 여러 종류 (세터주입,생성자주입,메소드주입)가 있지만 DL의 경우도 의존성 풀과 컨텍스트화된 의존성룩업(CDL) 두 종류가 있다.
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기Kenneth Ceyer
GDG DevFest 2017 Seoul
프론트엔드 모던 프레임워크 낱낱히 파헤치기 세션의 발표자료입니다.
이 발표자료에서는 여러분이 항상 궁금해 하신
프론트엔드 프레임워크의 삼총사
Angular, React, VueJS를 다차원적으로 깊이있게 비교하고 각각의 이점과 특화된 기능을 소개하고 있습니다.
이러한 프레임워크를 경험해보지 못한 분들을 위해 프레임워크 별로 특징부터 쉽게 접근하여 설명하기 때문에 경험 불문하고 가볍게 읽어 보실 수 있습니다.
Spring Framework & MyBatis_ 스프링프레임워크 & 마이바티스
☆ 무.료 강의자료 제공 中 ★
♡ 좋아요! 하고 더많은 자료 받아보세요 :) :) :) :) !!!!
[ 제 2장 ] _ Spring IoC & DI
[ 목 차 ]
2.5 Spring DI(Dependency Injection)
2.5.1 세터 주입(Setter Injection) – XML 기반
2.5.2 세터 주입(Setter Injection) – 어노테이션 기반
2.5.3 생성자 주입(Constructor Injection) – XML 기반
2.5.4 생성자 주입(Constructor Injection) – 어노테이션 기반
2.5.5 메소드 주입(Method Injection)
2.5.5.1 Method Injection(Method Replace)
2.5.5.2 Method Injection(Getter Injection)
2.5.6 Simple Value Injection
2.5.7 SpEL을 이용한 Value Injection(XML 방식)
2.5.8 SpEL을 이용한 Value Injection(어노테이션 방식)
2.5.9 ref 태그를 이용한 Value Injection
(ref local, ref bean, id, name의 차이)
2.5.10 스프링에서 XML 설정 파일의 분리
2.5.11 ApplicationContext의 분리(부모, 자식)
2.5.12 컬렉션 주입(Collection Injection), XML 방식
2.5.12 컬렉션 주입(Collection Injection), 어노테이션 방식
[#더많은자료, #꿀강의, #꿀강좌, #구로오라클학원 #탑크리에듀]
http://www.topcredu.co.kr/
The document outlines a six-day training plan on Java, covering topics from basic language features to advanced concepts such as lambda expressions and functional programming. It includes detailed discussions on Java 8's contributions, such as default methods in interfaces, the use of streams, and the implications of invoking methods with method handles. Additionally, it emphasizes the performance comparisons between different invocation methods and the importance of closures in functional programming.
고급 자바 8 교육 (6일 중 5일차)
티맥스소프트 연구소에 연구소장으로 재직 중이던 2013년 10월에 진행한 자바 언어 강의 내용입니다.
JVM에 대한 이해와 Java 8에 대한 소개를 포함하려고 노력하였습니다.
아래 강의 동영상이 있습니다.
http://javadom.blogspot.com/2017/07/8-6.html
The document outlines a Java training schedule at TmaxSoft R&D Center for optimization techniques related to threading, locking, and concurrent utilities in Java. It covers key concepts and implementations such as JVM locking optimizations, atomic operations, the Fork/Join framework, and various concurrent collections. Additionally, it previews topics for future sessions, including generics and object serialization.
고급 자바 8 교육 (6일 중 3일차)
티맥스소프트 연구소에 연구소장으로 재직 중이던 2013년 10월에 진행한 자바 언어 강의 내용입니다.
JVM에 대한 이해와 Java 8에 대한 소개를 포함하려고 노력하였습니다.
아래 강의 동영상이 있습니다.
http://javadom.blogspot.com/2017/07/8-6.html
고급 자바 8 교육 (6일 중 2일차)
티맥스소프트 연구소에 연구소장으로 재직 중이던 2013년 10월에 진행한 자바 언어 강의 내용입니다.
JVM에 대한 이해와 Java 8에 대한 소개를 포함하려고 노력하였습니다.
아래 강의 동영상이 있습니다.
http://javadom.blogspot.com/2017/07/8-6.html
고급 자바 8 교육 (6일 중 1일차)
티맥스소프트 연구소에 연구소장으로 재직 중이던 2013년 10월에 진행한 자바 언어 강의 내용입니다.
JVM에 대한 이해와 Java 8에 대한 소개를 포함하려고 노력하였습니다.
아래 강의 동영상이 있습니다.
http://javadom.blogspot.com/2017/07/8-6.html
Lecture on Java Concurrency Day 3 on Feb 11, 2009.Kyung Koo Yoon
The document discusses various worker thread models and provides examples of using concurrency in Java. It also summarizes the java.util.concurrent package, which provides common high-level concurrency classes like ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue, CountDownLatch and Executor. The package was introduced in Java 5 to make concurrent programming easier and more robust.
Lecture on Java Concurrency Day 2 on Feb 4, 2009.Kyung Koo Yoon
The document discusses concurrency in programming, focusing on performance, correctness, and design concerns such as deadlocks and liveness issues. It highlights concepts like lock-ordering deadlock, memory barriers, and context switching overhead, as well as design steps for managing shared resources and critical sections. Additionally, it touches on the use of worker threads and instance management in environments like Java EE.
Lecture on Java Concurrency Day 4 on Feb 18, 2009.Kyung Koo Yoon
This document discusses practical concurrency in Java, focusing on thread pools, various types of Executors, and synchronization mechanisms such as locks and conditions. It provides insights into thread pool configurations, rejection policies, and atomic variables with compare-and-swap operations. Additionally, it includes references to further resources and examples of questions regarding thread pool capabilities.
Lecture on Java Concurrency Day 1 on Jan 21, 2009.Kyung Koo Yoon
The document discusses the fundamentals of concurrency in Java, covering key concepts such as threads, race conditions, critical sections, and synchronization mechanisms. It explains the use of locks and conditions, including the roles of the java.util.concurrent.locks package and the implications of spurious wakeups in thread management. The content highlights the importance of memory models and the overall architecture for designing concurrent applications.
4. Framework이란?
• 프레임웍은 사용자가 작성한 코드와 합쳐져서 선택적으로 변경 가능한, 고유한
기능을 제공하는 소프트웨어
• 프레임웍의 특징
• 제어의 역전 (Inversion of Control) : 프로그램 제어 흐름을 호출자가 결정하
는 것이 아니라 프레임웍이 결정한다
• 기본 동작 : 확장 없이도 동작하는 기본 동작들이 제공되어야 한다.
• 사용자 코드를 통한 기능 확장 : 특정 기능만 선택적으로 확장할 수 있다.
• 프레임웍 코드는 변경되지 않는다 : 사용자 기능을 확장할 수 있지만, 프레임
웍 코드 자체는 변경될 필요가 없어야 한다.
4
5. 좋은 Framework에 대한 생각
• 역할의 분리 : 시스템과 비즈니스 로직의 분리 (개발자, 아키텍트, 시스템 담당)
• 아키텍처 효율성
• 결과물이 시스템에 부담을 적게 줘야
• 결과물의 수준이 개발자에 의존하지 않고 큰 차이가 없어야
• 생산성
• 간결하고 빠른 개발 / 적은 인적 비용 / 재사용성
• short learning curve : 특히 비즈니스 로직 구현이 직관적이고, 기술적으로 진입 장벽
이 낮아야 함
• Tooling이 용이
• 기술 확산이 쉬워야 (Viral) : 표준의 힘, 새로운 기술에 개발자들이 유인될 수 있음
5
6. Spring의 EJB 모델 비판
• 복잡한 시스템을 비즈니스 개발자에게 노출
• EJB는 컨테이너 환경에 대한 의존이 심해 테스트하기 어렵다.
• 클래스로더 구조가 복잡하여 WAS 구조를 모르면 이해하기 어렵다.
• 설정(deployment descriptor)이 너무 복잡하여 이해하기 어렵다.
• Business 객체를 EJB remote interface(티어 구조)로 설계하면 불필요하게 복잡해질뿐만 아
니라 객체 지향 원칙을 해친다.
• EJB는 간단한 것을 힘들게 구현한다. (Over-Engineering)
• EJB는 환경과 요건에 따른 implementation 방식 중 하나여야 하는 것을 일반적인
Business 객체 모두에 강요한다. (특정한 경우에만 적합하다)
• EJB는 분산 환경에서 복잡한 트랜잭션 관리가 필요한 경우 (declarative transaction
management 장점) 외에는 써야 할 이유가 딱히 없다.
6
7. Spring History
• 1.0 릴리스 (2004년 3월) : EJB를 비판하며 Apache 라이센스로 출시
• IoC container (핵심 코어 기능 모두 구현)
• Web MVC, Hibernate 연동, 트랜잭션 관리 등
• 2.0 릴리스 (2006년)
• AOP 기능 추가
• 2.5 ~ 3.0 릴리스 (2007년 ~ 2009년)
• XML 외에 Java 5의 annotation을 활용한 JavaConfig 설정 기능 (Guice 비판 대응)
• 4.0 릴리스 (2013년) : Java 6 이후 버전만 지원
• Java 8, Groovy, Java EE 7, WebSocket
7
8. Spring Framework
• Spring Core Container : IoC
• AOP
• Data Access
• Transaction Management
• Web MVC
• Remote Access
• Testing
• Convention over Configuration
RAD : Spring Boot & Spring Roo
• Spring Batch
• Spring Integration : EAI
8
10. • Class, Constructor, Field, Method, Package에 붙을 수 있음
• @interface를 통해 일종의 클래스로 선언함 (컴파일하면 실제로 interface가 됨)
• Target : annotation이 붙을 수 있는 위치를 지정
• Retention : annotation의 유효 범위 (SOURCE, CLASS, RUNTIME)
Java annotation
10
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TxMarker {
TxValue value();
}
11. • Class, Constructor, Field, Method, Package에 붙을 수 있음
• @interface를 통해 일종의 클래스로 선언함 (컴파일하면 실제로 interface가 됨)
• Target : annotation이 붙을 수 있는 위치를 지정
• Retention : annotation의 유효 범위 (SOURCE, CLASS, RUNTIME)
public interface TxService {
@TxMarker(TxValue.REQUIRED)
void service();
}
Java annotation
11
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TxMarker {
TxValue value();
}
12. meta-annotation
• meta-annotation : simply an annotation that can be applied to another
annotation (an annotation that is declared on another annotation)
• 아래 예제 annotation에서 정의된 @Service는 @Component로도 취급됨
• 여기에서 @Component가 meta-annotation
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // Spring은 이 선언에 따라 @Service를 @Component처럼 취급
public @interface Service {
// ....
}
12
13. composed annotation
• composed annotation : 여러 개의 meta-annotation을 하나의 커스텀
annotation으로 결합해주는 annotation
• 아래 예에서 @TransactionalService는 meta-annoation인 @Transactional과
@Service를 결합한 composed annotation
@Transactional
@Service
@Target(TYPE)
@Retention(RUNTIME)
@Documented
public @interface TransactionalService {
// ....
}
13
14. BCI : Byte Code Instrumentation
• source 코드가 아닌 컴파일된 bytecode를 직접 수정하여 bytecode를 변경하는
방식
• 두 가지 시점에서 변경이 가능
• ClassLoader의 loadClass에서 defineClass를 호출하기 전에
• JVM agent로 등록하여 클래스가 로드될 때 JVM이 실행시켜주는 callback 메
소드 안에서
14
16. Dynamic Proxy
16
public interface TxService {
void service();
}
Class class = Proxy.getProxyClass(classloader,
TxService.class);
// 만들어지는 Proxy bytecode를 Java code로 표현한다면 …
public class $Proxy0 implements TxService {
private InvocationHandler h;
private static Method m3; // static initializer에서
reflection으로 초기화
public $Proxy0(InvocationHandler h) {
this.h = h;
}
public void service() {
// interface에 선언된 모든 메소드들을 다음 내용으로 채워 구현
h.invoke(this, m3, null);
}
...
}
17. CGLIB (1/2)
• cglib : Byte Code Generation Library
• Dynamic Proxy와 비슷하게 bytecode를 만들
거나 변경하여 Proxy를 제공하는 라이브러리.
• JDK Dynamic Proxy와 달리 interface 뿐만아
니라 이미 존재하는 class를 서브클래싱하여
method interception을 할 수 있다.
• JDK Dynamic Proxy처럼 reflection으로 호출
하는 방식이지만 같은 이름의 Method가 많을
경우 조금 더 빨리 찾기 때문에 성능적으로 조
금 유리하다.
17
Java Bytecode
ASM
CGLIB
18. CGLIB (2/2)
18
public class HelloClass {// interface 아닌 class도 proxy 방식 확장
public String hello(String input) {
return "Hello, " + input + "!!!";
}
}
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(HelloClass.class);
enhancer.setCallback(new Interceptor());
HelloClass helloObj = (HelloClass) enhancer.create();
System.out.println(helloObj.hello("Tmax"));
19. CGLIB (2/2)
19
public class HelloClass {// interface 아닌 class도 proxy 방식 확장
public String hello(String input) {
return "Hello, " + input + "!!!";
}
}
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(HelloClass.class);
enhancer.setCallback(new Interceptor());
HelloClass helloObj = (HelloClass) enhancer.create();
System.out.println(helloObj.hello("Tmax"));
class Interceptor implements MethodInterceptor {
public Object intercept(Object o, Method m, Object[] args,
MethodProxy mproxy) throws Throwable {
return mproxy.invokeSuper(o, args) + " BY CGLIB";
}
}
21. Inversion of Control
• Inversion of Control : 제어의 역전
• 프로그램 중 일반 라이브러리가 사용자가 작성한 코드 부분의 흐름을 제어하는
방식의 설계를 뜻한다.
• IoC에서는 라이브러리 코드가 업무에 특정한 코드를 호출한다.
• IoC 개념은 Dependency Injection 방식이나 Service Locator 패턴, Factory 패
턴, Template Method 패턴, Callback, Event Loop 등의 방식으로 구현 가능.
21
22. Dependency Injection
• Dependency Injection : 의존체 주입. (객체 세계에서 객체의 멤버 필드들이 해당 객체가 의
존하는 의존체이다)
• 컴포넌트들의 의존체를 주입할 수 있고 외부에서 설정할 수 있으면 해당 컴포넌트들을 재사용
할 수 있다.
• 의존체로 추상체(인터페이스나 추상 클래스)를 사용하면 의존체 객체를 생성하는 것은 분리된
곳에서 제어할 수 있으므로, 객체의 구현을 많은 코드 수정없이 변경할 수 있다.
• 의존체는 컴포넌트로 주입할 수 있으므로 의존체를 mock 구현체로 주입하면 테스트를 보다
쉽게 할 수 있다.
• Dependency Injection과 Service Locator의 가장 큰 차이점은 dependency를 찾기 위해 코
드가 시스템을 알 필요가 있느냐의 여부
• Spring은 도메인 로직 코드가 프레임웍 자체에 아무런 의존을 갖지 않도록 설계되었다.
22
23. Injector
Dependency Injection Roles
• Client Object : 다른 객체(서비스)를 사용하는 객체
• Service Object : 사용될 가능성이 있는 모든 객체
• Interfaces : 클라이언트가 서비스를 사용하기 위해 인지하는 인터페이스
• Injector : 서비스를 생성하고 이를 클라이언트에 주입하는 역할을 하는 모듈. 종
종 클라이언트를 만드는 역할도 함.
23
Client ServiceRef1
24. Injector
Dependency Injection Roles
• Client Object : 다른 객체(서비스)를 사용하는 객체
• Service Object : 사용될 가능성이 있는 모든 객체
• Interfaces : 클라이언트가 서비스를 사용하기 위해 인지하는 인터페이스
• Injector : 서비스를 생성하고 이를 클라이언트에 주입하는 역할을 하는 모듈. 종
종 클라이언트를 만드는 역할도 함.
24
Client ServiceRef1 ServiceImpl1 ServiceRef2 ServiceImpl2
25. Client와 Dependency
25
@Component
public class SomeComponentImpl implements SomeComponent {
private Someone someone;
private Something something;
public void saySomething() {
System.out.println("Someone " + someone.getName() + "
uses " + something.getMaterial());
}
}
Client 클래스
Dependencies
26. Dependency Injection Types
• 클라이언트 객체가 서비스 객체 구현체를 받는 방법
• Constructor injection : 클래스의 생성자의 인자 dependency 주입
• Field injection : 클래스 멤버 필드 dependency 주입
• Setter injection : setter 메소드의 인자 dependency 주입
• Method injection : 메소드를 주입
26
27. Constructor Injection
27
@Component
public class HelloComponentImpl implements HelloComponent {
private Someone someone;
@Autowired // Constructor Injection
public HelloComponentImpl(Someone someone) {
this.someone = someone;
}
public void hello() {
System.out.println("Hello, " + someone.getName());
}
}
ApplicationContext ctx = new
AnnotationConfigApplicationContext(HelloComponentImpl.class,
Youknowwho.class);
HelloComponent h = ctx.getBean(HelloComponent.class);
h.hello();
Spring
28. Setter Injection
28
@Component
public class SetterComponentImpl implements SetterComponent {
private Someone someone;
@Autowired // Setter Injection
public void setSomeone(Someone someone) {
this.someone = someone;
}
public void hello() {
System.out.println("Hello, " + someone.getName());
}
}
ApplicationContext ctx = new
AnnotationConfigApplicationContext(SetterComponentImpl.class,
Youknowwho.class);
SetterComponent c = ctx.getBean(SetterComponent.class);
c.hello();
Spring
29. Field Injection
29
@Component
public class FieldComponentImpl implements FieldComponent {
@Autowired // Field Injection
private Someone someone;
public void hello() {
System.out.println("Hello, " + someone.getName());
}
}
ApplicationContext ctx = new
AnnotationConfigApplicationContext(FieldComponentImpl.class,
Youknowwho.class);
FieldComponent c = ctx.getBean(FieldComponent.class);
c.hello();
Spring
30. Method Injection
• 객체 참조나 값을 inject하는 대신에 method를 inject하는 개념
• getter injection이라고도 함 (불필요한 setter method를 없애겠다는 생각)
• 코드에서 IoC 컨테이너에 대한 dependency를 줄이기 위해 사용될 수 있음
30
public abstract class MethodComponentImpl implements
MethodComponent {
public void hello() {
System.out.println("Hello, use " +
getSomething().getMaterial());
}
public abstract Something getSomething(); // 추상 메소드의 구현
체를 injection하게 됨
}
<bean id="methodComponent"
class="com.example.MethodComponentImpl"> <!-- method injection
-->
<lookup-method name="getSomething" bean="something2"/>
</bean>
Spring
32. Spring IoC Container
• BeanFactory interface 구현체가 Spring IoC Container
• ApplicationContext는 BeanFactory의 자식 인터페이스이며 BeanFactory에
AOP 기능, 메시지 리소스 처리 (국제화 관련), 이벤트 처리 등을 추가로 처리하
도록 고안.
• 특별한 이유가 없으면 ApplicationContext를 사용.
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[]
{"services.xml", “daos.xml"}); // XML 방식 configuration
ApplicationContext context =
new AnnotationConfigApplicationContext(MyConfiguration.class); //
java annotation 방식 configuration
32
33. Configuration
• configuration 정보 : Spring Container가 객체들을 생성하고, 설정하고, 결합하
는 방식을 알려주는 메타 정보
• xml 방식과 java 방식
• Spring 3.0부터 JavaConfig (annotation 방식)를 지원 : Google Guice의 비판
에 대한 수용
• 구현에 따라 약간의 차이는 있지만 대부분 호환
• XML은 field injection을 지원하지 않고, JavaConfig는 method injection을
지원 안함
• Spring에서는 XML에서 annotation 설정도 찾도록 element를 지정할 수 있어
혼용도 가능
33
35. XML과 JavaConfig
35
XML JavaConfig 비고
<beans> root element @Configuration
XML : configuration XML 파일의 root element
Java : configuration 자바 클래스
<bean> element @Bean
XML : bean 정의 XML element
Java : bean 정의 메소드 (리턴 값이 bean임을 나타냄)
<import> element @Import
XML : 다른 configuration XML 파일을 import
Java : @Configuration 자바 클래스 간에 import
37. Java Config 예제
37
@Configuration
public class DemoConfiguration {
@Bean
public HelloComponent helloComponent() {
return new HelloComponentImpl(someone(), something());
}
@Bean
public Someone someone() { return new Youknowwho(); }
@Bean
public Something something() { return new Metal(); }
}
Java IoC Configuration은 JavaConfig와 각 빈에 정의된 annotation 두 가지 파트로 구성
38. XML과 JavaConfig 장단점
• 자바 annotation 방식
• 장점 : annotation 위치만으로도 클래스나 해당 요소 등 많은 정보를 갖고 있
으므로 설정이 훨씬 짧고 간결
• 단점 : configuration 정보는 POJO가 아니고, 설정이 코드 안에 들어가서 제어
하기 어렵다. 해당 bean에 들어가는 annotation에 대해서도 호불호가 갈린다.
• XML 방식
• 장점 : 소스 코드에 변경이 없고 설정이 변경되어도 다시 컴파일할 필요가 없
다. 툴화하기 쉽다.
• 단점 : 설정이 복잡함
38
39. Injection 방식과 Spring 구현
•Constructor Injection
•Setter Injection
•Field Injection
•Method Injection
39
Spring은 ApplicationContext를 생성할 때 각 bean들을 eagerly initialize 하면서
해당 bean들의 dependency를 resolve하여 미리 Object Graph를 생성하는 구조
40. Constructor Injection (1/2)
40
@Component // Spring이 관리하는 bean임을 선언
public class HelloComponentImpl implements HelloComponent {
private Someone someone;
@Autowired // Constructor Injection
public HelloComponentImpl(Someone someone) {
this.someone = someone;
}
}
@Component // Spring이 관리하는 bean임을 선언
public class Youknowwho implements Someone {
public String getName() {
return getClass().getName();
}
}
41. Constructor Injection (2/2)
41
new ApplicationContext(HelloComponentImpl.class)
주어진 bean 등록 요청 (HelloComponentImpl.class)
내부적으로 BeanFactory 생성
beanFactory에서 singleton들을 모두 초기화 (각각 getBean)
ConcurrentHashMap에서 bean 이름으로 검색
singleton bean이 없으면 BeanFactory로 bean 생성
Constructor Injection이므로 생성자 인자에 대해서 getBean
인자 bean들이 만들어진 후 생성자 호출
Reflection 사용
Constructor
Injection
BeanContext
초기화
42. Constructor Injection (2/2)
42
new ApplicationContext(HelloComponentImpl.class)
주어진 bean 등록 요청 (HelloComponentImpl.class)
내부적으로 BeanFactory 생성
beanFactory에서 singleton들을 모두 초기화 (각각 getBean)
ConcurrentHashMap에서 bean 이름으로 검색
singleton bean이 없으면 BeanFactory로 bean 생성
Constructor Injection이므로 생성자 인자에 대해서 getBean
인자 bean들이 만들어진 후 생성자 호출
Reflection 사용
Constructor
Injection
BeanContext
초기화
// Constructor Injection의 실질적인 실행 순서
// 1. 생성자 인자 bean를 먼저 찾거나 만듬
Someone someone = new Youknowwho();
// 2. 찾은 인자 bean으로 inject하려는 bean의 생성자 호출
HelloComponent bean = new HelloComponentImpl(someone);
43. Setter Injection (1/2)
43
@Component // Spring이 관리하는 bean임을 선언
public class SetterComponentImpl implements SetterComponent {
private Someone someone;
@Autowired // Setter Injection
public void setSomeone(Someone someone) {
this.someone = someone;
}
}
@Component // Spring이 관리하는 bean임을 선언
public class Youknowwho implements Someone {
public String getName() {
return getClass().getName();
}
}
44. Setter Injection (2/2)
44
ConcurrentHashMap에서 bean 이름으로 검색
singleton bean이 없으면 BeanFactory로 bean 생성
bean 객체에 대해 각 인자 bean으로 setter 호출
Setter Injection이므로 bean 생성자 먼저 호출 객체 생성
Reflection 사용
Setter Injection
BeanContext
초기화 등BeanContext 내에서 해당 컴포넌트 getBean() 호출
생성 후 dependency 검사. 각각에 대해 getBean() 호출
45. Setter Injection (2/2)
45
ConcurrentHashMap에서 bean 이름으로 검색
singleton bean이 없으면 BeanFactory로 bean 생성
bean 객체에 대해 각 인자 bean으로 setter 호출
Setter Injection이므로 bean 생성자 먼저 호출 객체 생성
Reflection 사용
Setter Injection
BeanContext
초기화 등BeanContext 내에서 해당 컴포넌트 getBean() 호출
생성 후 dependency 검사. 각각에 대해 getBean() 호출
// Setter Injection의 실질적인 실행 순서
// 1. inject 하려는 bean의 생성자 호출
SetterComponent bean = new SetterComponentImpl();
// 2. 생성자 인자 bean를 먼저 찾거나 만듬
Someone someone = new Youknowwho();
// 3. bean 객체에 setter를 호출
bean.setSomeone(someone);
46. Field Injection
• Spring에서 Field Injection은 Java annotation 방식만 지원
• XML로 표현하기에 setter와 구분하기 쉽지 않고 별로 큰 차이가 없어서인듯.
• Field Injection 실행 순서는 Setter Injection과 동일하게 먼저 bean을 생성한
후에 dependency를 resolve하는 과정에서 annotate된 Field에 해당하는 bean
을 찾아서 inject.
• 즉, 먼저 bean 생성 후에 field resolve해서 inject
46
@Component
public class FieldComponentImpl implements FieldComponent {
@Autowired // Field Injection
private Someone someone;
}
47. Method Injection (1/2)
• Spring에서 Method Injection은 XML Configuration 방식만 지원
• ApplicationContext 즉, IoC Container 관련 코드 없이 bean lookup 등을 수행
하고자 할 때 주로 사용. 다른 대부분의 경우는 굳이 사용할 이유가 없음.
47
public abstract class MethodComponentImpl implements
MethodComponent {
public abstract Something getSomething();
}
<bean id="methodComp" class="com.example.MethodComponentImpl">
<!-- method injection -->
<lookup-method name="getSomething" bean="something2"/>
</bean>
48. Method Injection (2/2)
48
ConcurrentHashMap에서 bean 이름으로 검색
singleton bean이 없으면 BeanFactory로 bean 생성
Method Injection이므로 CGLIB 사용하여 자식 클래스 정의
Reflection 및 CGLIB
Proxy 사용
Method Injection
BeanContext
초기화 등BeanContext 내에서 해당 컴포넌트 getBean() 호출
CGLIB Proxy로 정의된 자식 클래스로 bean 객체 생성
49. Method Injection (2/2)
49
ConcurrentHashMap에서 bean 이름으로 검색
singleton bean이 없으면 BeanFactory로 bean 생성
Method Injection이므로 CGLIB 사용하여 자식 클래스 정의
Reflection 및 CGLIB
Proxy 사용
Method Injection
BeanContext
초기화 등BeanContext 내에서 해당 컴포넌트 getBean() 호출
CGLIB Proxy로 정의된 자식 클래스로 bean 객체 생성
// Method Injection의 실질적인 실행 순서
// 1. inject 하려는 abstract bean class의 CGLIB 자식 클래스 생성
Enhancer enhancer = new Enhancer();
enhancer.setSuperClass(MethodComponentImpl.class);
…
Class<MethodComponentImpl> clazz = enhancer.createClass();
// 2. bean의 생성자를 호출하여 객체 생성
MethodComponent bean = clazz.newInstance();
50. Constructor or Setter
• Spring에서는 Constructor Injection과 Setter Injection을 섞어 사용하는 것을
허용
• Constructor Injection은 Mandatory Injection에, Setter Injection은 Optional
Injection에 사용하는 것을 권장
• null이 되어서는 안되는 dependency는 Constructor Injection으로
• dependency resolution이 required가 아닌 경우에는 Setter Injection으로
50
51. Scope
• Scope은 IoC 컨테이너가 관리하는 빈 객체의 생애주기(lifecycle)을 정의
• Spring은 기본으로 Singleton과 Prototype 두 가지 Scope을 정의
• Spring에서 빈의 기본 Scope은 Singleton
51
Scope 설명
Singleton IoC 컨테이너 단위로 빈이 하나만 생성
Prototype IoC 컨테이너로 빈 요청이 올 때마다 생성
Request (Spring Web) HTTP request 마다 하나씩 빈 객체 매핑
Session (Spring Web) HTTP Session별로 하나씩 빈 객체 매핑
Global-session (Spring Web) 세션과 비슷하지만 Portlet에서 사용
Application (Spring Web) ServletContext의 lifecycle에 해당하는 Scope
52. 기본 Scope
• Singleton scope
• BeanFactory를 통해 getBean() 요청이 오거나 inject 요청이 오면
ConcurrentHashMap으로 singleton bean 객체들을 관리하여 return
• 결과적으로 하나의 객체가 여러 bean들에게 공유됨
• Prototype scope
• BeanFactory를 통해 getBean() 요청이 오거나 inject 요청이 오면 매번
reflection을 사용하여 새로운 bean 객체를 만들어 return
52
53. Singleton 빈에서 Prototype 빈 참조 (1/3)
• Singleton bean에 Prototype bean을 inject하면 prototype bean은 마치 singleton
scope을 가진 것처럼 동작
• Inject되는 시점에서만 prototype으로 동작하기 때문
• 매번 access할 때마다 prototype처럼 동작하도록 하려면?
• IoC Container 즉, ApplicationContext에서 직접 getBean()을 호출하여
dependency를 resolve는 것이 한 방법
• 이렇게 할 경우 컨테이너에 대한 코드가 비즈니스 로직에 포함되므로 method
injection을 사용하여 회피할 수 있다.
• Spring은 proxyMode를 제공해서 bean이 아닌 scoped proxy bean을 inject할 수
있다.
53
54. Singleton 빈에서 Prototype 빈 참조 (2/3)
54
@Component // 이 bean은 기본값 Scope인 Singleton
public class SomeComponentImpl implements SomeComponent {
@Autowired // Field Injection
private Something something; // Leather 객체가 inject될 것임
}
@Component // Spring이 관리하는 bean임을 선언
@Scope("prototype") // 이 bean은 prototype Scope
public class Leather implements Something {
public String getMaterial() {
return getClass().getName();
}
}
55. Singleton 빈에서 Prototype 빈 참조 (3/3)
55
@Component // 이 bean은 기본값 Scope인 Singleton
public class SomeComponentImpl implements SomeComponent {
@Autowired // Field Injection
private Something something; // prototype scoped proxy 객체
가 inject될 것
}
@Component // Spring이 관리하는 bean임을 선언
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value =
"prototype")
public class Leather implements Something {
public String getMaterial() {
return getClass().getName();
}
}
proxyMode는 기본값인 NO, CGLIB 기반의 TARGET_CLASS,
Dynamic Proxy 기반의 INTERFACES 중 하나를 지정
56. Custom Scope 구현
• singleton이나 prototype이 아닌 scope의 bean을 다른 bean에 inject하려고
하면 bean을 inject하는 게 아니라 AOP scoped proxy 를 inject
• AOP scoped proxy 는 CGLIB 기반의 proxy
• 해당 bean을 access할 때마다 CGLIB proxy 객체가 등록된 커스텀 Scope 객
체에 대해 get을 호출
• 커스텀 Scope 클래스 구현에 따라 get에 의해 객체 return
• 이런 구조적 문제로 http request scope bean을 singleton bean에서 참조하려
고 하면 성능 문제가 발생할 수 있음
56
57. Web Request/Session Scope 구현
• org.springframework.web.context.request.RequestScope/SessionScope 클
래스
• ThreadLocal에 requestAttributes라는 변수를 두고 같은 request인지 scope을
체크
57
58. Autowire
• 관련된 bean 클래스들을 자동으로 찾아 inject 해주는 기능
• 설정이 매우 간소해지며, Java annotation을 사용할 경우 configuration이 거의 필
요가 없어짐
• 적합한 bean 후보가 여럿일 경우, 임의로 선택하거나(기본값), 부가적인
@Qualifier 혹은 @Qualifier 기반의 meta annotation 등의 정보를 고려하여 선택
• wiring 방식
• byName : bean 이름으로 찾기
• byType : bean 클래스명으로 찾기
• constructor : bean의 생성자 파라미터의 클래스명으로 찾기
58
59. Autowire
59
@Component
public class SomeComponentImpl implements SomeComponent {
@Autowired @Qualifier("leather")// Field Injection
private Something something; // Leather 객체를 injection
}
@Component @Qualifier("leather")
public class Leather implements Something {
…
}
@Component @Qualifier("metal")
public class Metal implements Something {
…
}
60. Lazy Instantiation
• Spring은 기본적으로 컨테이너 즉, ApplicationContext가 생성될 때 모든 bean
들을 eagerly initialize (생성)
• 문맥에 따라 필요한 bean들은 처음 사용될 때 initialize할 수 있도록 lazy-init 옵
션을 제공
60
61. Bean Lifecycle Callbacks
• Spring이 bean을 생성하거나 해지하는 lifecycle 특정 시점에서 호출해주는 callback
• initialize callbacks 호출 순서
• @PostConstruct 로 표시된 메소드
• InitializingBean I/F를 implement한 경우 afterPropertiesSet() 메소드
• init() : default init method 혹은 지정한 init method
• destroy callbacks 호출 순서
• @PreDestroy 로 표시된 메소드
• DisposableBean I/F를 implement한 경우 destroy() 메소드
• destroy() : default destroy method 혹은 지정한 destroy method
61
63. JSR 330 (javax.inject)
• JSR 330 (javax.inject) : Dependency Injection for Java, Java EE 6
• JSR 299 (CDI) : Contexts and Dependency Injection for the Java EE, Java EE 6
• CDI(JSR 299)는 Java EE에서 Spring을 대체하는 Java EE 표준으로 추진
• JSR 330을 확장하고 있으며, Autowire 기반의 container로 Java EE 기능들의 결합
방법도 표준으로 정의
• Java DI(JSR 330)은 몇 가지 표준적인 annotation만 정의하고 wiring이나 container에
대해서는 언급하지 않음
• Google Guice 개발자와 RedHat JBoss 등에서 주도적으로 진행
• Spring, Guice 등 대부분의 Java 기반 IoC 컨테이너들이 JSR 330은 지원
• 추후 Java SE에도 포함 예상
63
64. JSR 330 (javax.inject) 내용
• 다섯 개의 annotation과 한 개의 interface로 구성
• @Inject : dependency를 지정. 생성자, 메소드, 필드에 가능
• @Named : 문자열 기반의 qualifier
• @Qualifier : 클래스 type 기반의 qualifier
• @Scope : Scope을 정의할 수 있는 meta annotation
• @Singleton : @Scope 중 유일하게 스펙에서 정의한 annotation. 공유 scope.
• Provider<T> interface
• T get() 메소드 하나를 정의. 일종의 factory 메소드
64
65. Spring annotations vs. JSR 330 annotations
Spring javax.inject.* javax.inject restrictions / comments
@Autowired @Inject Spring에서는 둘 다 사용 가능
표준인 @Inject는 'required' 속성이 없음
@Component @Named Spring에서 관리하는 bean을 뜻하는 @Component는 표준인
@Named와 거의 동일하게 사용 가능
@Scope("singleton") @Singleton JSR-330은 특별하게 명시되지 않으면 Spring의 prototype
scope이 기본값.
Spring은 singleton이 기본값.
javax.inject 도 사용자 정의 Scope을 위해 @Scope
annotation을 정의
@Qualifier @Named Spring은 @Qualifier나 Generic type을 사용하여 auto wiring
시 엄밀한 제어를 할 수 있음. javax.inject도 @Named에 value
값을 지정하면 유사한 의미
65
66. 66
Spring javax.inject.* javax.inject restrictions / comments
@Value - Spring에서는 Bean이 아닌 primitive나 collection 등의 Value
Injection이 가능함.
@Required - Spring에만 있음.
컨테이너 초기 시에 반드시 initialize되어야 하는 dependency에 대
한 지정.
@Lazy - Spring에만 있음.
IoC 컨테이너 생성 시점이 아니라 처음 액세스될 때 initialize하는 빈
에 대한 표기
68. Guice
• Google Guice는 Spring이 XML 기반의 설정으로 구성된 점을 비판하며 Java 5
의 annotation과 Generics 기능을 최대한 활용하여 설정하도록 설계
• Spring과 달리 interface 기반이 아니어서 bean들은 임의의 class가 가능
• Spring이 IoC 컨테이너도 3.0 이후 Guice의 비판에 대응하여 JavaConfig를 설
계하여 포함
• Spring은 Java EE integration 측면에서 타 IoC 컨테이너에 비해 방대한 API, SPI
를 구축해놓았지만 Guice는 Java EE 지원이 없어 상대적으로 라이브러리가 가
벼움.
68
69. Dagger 2
• Spring이나 Google Guice가 runtime에 object graph를 만드는 부분을 비판하며
컴파일 time(annotation processing time)에 코드 생성을 통해 validation과
object graph 생성까지 하는 아이디어
• Runtime Proxy를 사용하지 않으므로 성능이나 메모리 footprint 측면에서 유리하
여 Android와 같은 모바일 환경에서 많이 채택하는 추세
• 상대적으로 기능 구현이 어렵고 런타임 유연성은 약함
• Dagger 1은 Square라는 Financial Startup에서 만들었으며, Dagger 2는 구글에서
개발 중
• Dagger 1은 compile time validation까지 진행, Dagger 2는 object graph까지
compile time에 구성하는 게 목적
69
71. Configuration 복잡도
• Configuration 방법 : XML, Java Configuration Code, Java Annotation,
Autowiring
• Spring 비판
• 설정과 코드를 오가면서 코드를 이해하는 게 어렵다. (주로 XML 설정에 대한
비판)
• xml 방식과 java 방식
• Spring 3.0부터 둘 다 지원
• 기존 코드에 영향을 안 준다는 측면에서 configuration은 XML이 합리적
• bean의 특성은 코드의 일부라고 판단할 수 있으므로 annotation이 합리적
71
72. 과도한 decoupling
• Program to an interface, not an implementation (Design Pattern, GoF)
• decoupling interface from implementation
• 구현체는 대부분 하나인 경우에도 모두 interface를 별도로 선언해야 함
• Too many interfaces
• Cohesive small system과 decoupling을 위한 decoupling
• Spring framework은 후자를 만들게 한다. (fine granularity의 interface 유도)
• Abstract class와 interface (Erich Gamma 인터뷰에서)
• 자바의 interface는 메소드 추가 같은 변경이 어려워 incremental 변경에는 적
합치 않음. Abstract class에서는 구현 자식 class들 변경 없이 메소드 추가 가능.
72
73. 성능 오버헤드
• Reflection + dynamic proxy, CGLIB enhancer 등 reflection을 injection 시에
과도하게 사용
• Map-like API
• bean에 대해 접근할 때 ApplicationContext로부터 getBean(name) 하는 형
태로 성능에 불이익이 있음.
• Bean이 많을수록 Boot-time 성능이 떨어지고, 클래스가 많아짐(interface,
implementation, proxy 등)으로 인해 memory footprint 증가
• 서로 다른 scope을 가진 bean들 간의 injection 시 런타임 성능 이슈
73
74. Compile-time validation 부족
• object dependency graph 검증이 컴파일 시에 충분히 되지 않으므로, 대부분
의 validation은 코드 실행 후 ApplicationContext 생성 시점에서 이루어짐
74
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
‘helloController'
: Injection of autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException
: Could not autowire field: private hello.ConstructorBasedInjection hello.HelloController.cbInj
; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException
: No qualifying bean of type [hello.ConstructorBasedInjection] found for dependency
: expected at least 1 bean which qualifies as autowire candidate for this dependency.
75. IoC 컨테이너 설계 시 추가 고려 사항들
• 표준 준수 여부
• JSR 330 (javax.inject), CDI (Java EE standard), Spring (de facto)
• Spring API 호환 구현 가능성
• 논리적으로는 컴파일 시점에 dependency를 injection하더라도 대부분 가능
•
75
78. Custom Scope 구현
• singleton이나 prototype이 아닌 scope의 bean을 다른 bean에 inject하려고
하면 bean을 inject하는 게 아니라 AOP scoped proxy 를 inject
• AOP scoped proxy 는 CGLIB 기반의 proxy
• 해당 bean을 access할 때마다 CGLIB proxy 객체가 등록된 커스텀 Scope 객
체에 대해 get을 호출
• 커스텀 Scope 클래스 구현에 따라 get에 의해 객체 return
• 이런 구조적 문제로 http request scope bean을 singleton bean에서 참조하려
고 하면 성능 문제가 발생할 수 있음
78
79. Request Scope에서 Request와 연결
• Request 발생 시
• WAS Web Container의 request event를 listen하면서 event 발생 시 thread local에
해당 event와 HttpServletRequest 객체를 사용하여 커스텀 Scope 객체를 생성 저장
• 실제 Request Scope의 Bean이 사용될 때 (Dynamic Proxy 메소드 호출)
• proxy 코드에서 getBean을 호출하면 thread local의 커스텀 Scope 객체를 찾아보고
없으면 에러.
• Scope 객체가 있으면 이 Scope 객체 안에서 (ConcurrentHashMap처럼 동작) bean
name으로 bean을 찾고, 없으면 생성해서 저장.
• 이 코드는 Request, Session, Global_Session(Portlet) 모두 공통
• Session인 경우 실제 getBean을 할 때 lock을 사용한다는 차이만 있음 (multi-thread)
79