본문 바로가기
Tip

spring 개념

by "뭉치" 2021. 8. 14.
728x90

출처 : https://ko.wikipedia.org/wiki/%EC%A0%9C%EC%96%B4_%EB%B0%98%EC%A0%84

제어 반전, 제어의 반전, 역제어는 프로그래머가 작성한 프로그램이 재사용 라이브러리의 흐름 제어를 받게 되는 소프트웨어 디자인 패턴을 말한다. 줄여서 Ioc(Inversion of Control)이라고 부른다. 전통적인 프로그래밍에서 흐름은 프로그래머가 작성한 프로그램이 외부 라이브러리의 코드를 호출해 이용한다. 하지만 제어 반전이 적용된 구조에서는 외부 라이브러리의 코드가 프로그래머가 작성한 코드를 호출한다. 설계 목적상 제어 반전의 목적은 다음과 같다:
● 작업을 구현하는 방식과 작업 수행 자체를 분리한다.
●모듈을 제작할 때, 모듈과 외부 프로그램의 결합에 대해 고민할 필요 없이 모듈의 목적에 집중할 수 있다.
●다른 시스템이 어떻게 동작할지에 대해 고민할 필요 없이, 미리 정해진 협약대로만 동작하게 하면 된다.
●모듈을 바꾸어도 다른 시스템에 부작용을 일으키지 않는다.

출처 : http://www.javajigi.net/pages/viewpage.action?pageId=5614

 

安全加密检测

已通过安全加密检测 如果没有自动跳转,请点击下方按钮前往

www.javajigi.net

 

Spring IoC 개념 및 활용방안

Table of Contents

0. 머리말
1. IoC의 개념
2. 사용하는 목적
3. IoC의 종류(세부사항)
4. 설정(의존성부여)방식의 차이
5. 기타궁금증
토론주제
참고문헌

0. 머리말

3차스터디 첫주제인 IoC에 대한 자료를 준비하면서 나름대로 스프링예제도 따라해보고 이것저것 공부를 하긴했는데 
개념적으로 정리가 덜된 부분이 많이 있는관계로 부분적으로 정확하지 않은 내용이 있을수 있음을 양해해주시구요... 
그동안 박재성, 강현수님이 이전 스터디에서 자료를 잘 정리하셔서 좀 다른관점에서 IoC및 관련사항에 대해서 
의문부호를 달고 접근하려 시도했다는 점을 먼저 밝혀두겠습니다. 아울러 넘여유를 가지고 준비하다보니 문서작성이 늦어진점 죄송스럽게 생각합니다..

1. IoC의 개념

IoC(Inversion of Control)를 풀이하면 제어권의 반전 즉 누군가가 제어를 대신해준다는 의미로 생각할수 있을것같다.. 
그럼 뭘 제어하겠다는거며 누가 제어권을 뺏어갔다는 것인가? 궁금하다^^ 자바에서 클래스를 하나 만들고 띄우고 죽이고 하는걸 모두 프로그래머가 담당했는데
그걸 헉스 누군가가 뺏어갔다는것이다. 바로 컨테이너란놈인데 그안에 있는 조립기가 뺏어갔다. 조립기는 스프링의 xml설정파일을 읽어서 알아서 객체를 생성하고 그것을 관계된 객체의 변수에 넣어주는역할을 한다는것이다..

3. IoC의 종류(세부사항)

IoC의 종류로는 DI(Dependency Injection), 와 DL(Dependency Lookup) 이 있다고한다. 자세한화면은 2차스터디 그림 http://wiki.javajigi.net/download/attachments/3664/IoC_type.jpg을 참고하기 바란다.
여기에선 DL을 제외한 DI를 이용하는 3가지 방식을 살펴보겠다.

DI 의존성삽입방식 설정절차 컨테이너
생성자를 이용한 의존성 삽입 (Constructor Injection) 각클래스내의 초기화에 필요한 모든 파라미터를 갖는 생성자를 만든다.
설정코드 또는 설정파일로 각 클래스간의 관계를 묶는다.
pico Container
Setter() 메소드를 이용한 의존성 삽입 (Setter Injection) 각클래스에 setter 구현체를 삽입할 메소드를 만든다.
설정코드 또는 설정파일로 각 클래스간의 관계를 묶는다.
Spring
초기화 인터페이스를 이용한 의존성 삽입 (Interface Injection) 의존성을 전달할때 사용되는 인터페이스를 먼저 만든다.
그 인터페이스를 구현하는 클래스를 만든다.
컨테이너에 있는 삽입기가 의존성인터페이스를 구현하는 모든클래스에 구현체를 묶어준다.
아파치 Avalon

부연설명(발췌한 글) IoC 콘테이너와 디펜던시 인젝션 패턴

1. 생성자방식과 Setter 방식의 비교

생성자에 파라미터를 지정함으로써 유효한 객체를 만들기 위해서 무엇이 필요한지 명확하게 알 수 있게 된다. 
만약 객체를 생성하는 방법이 여러개 존재한다면 그에 해당하는 여러개의 생성자를 작성하면 된다.
생성자 기법의 또 다른 장점은 세터 메소드를 제공하지 않음으로써 간단하게 필드를 불변 값으로 지정할 수 있다는 점이다. 
이것은 매우 중요한 점이다. 만약 세터 메소드를 사용해서 초기화를 한다면, 이후에 세터 메소드가 임의로 호출되는 것 때문에 발생하는 문제를 겪을 수도 있다. 
(필자의 경우는 초기화를 위한 값을 할당할 때에는 보통의 세터 메소드 대신 initFoo 와 같은 초기화를 의미하는 이름의 메소드를 사용하는 것을 선호한다.)
하지만, 생성자 기법을 사용하는 것이 항상 좋은 것은 아니다. 만약 생성자의 파라미터가 많을 경우 복잡해 보일 수가 있다. 생성자가 복잡하고 길다는 것은 종종 그 클래스가 과도하게 사용된다는 것을 의미하며, 
이런 경우 클래스를 여러개로 분리하는 것을 고려해봐야 한다.
유효한 객체를 생성하는 방법이 여러개 존재한다면, 생성자를 통한 방법으로 유요한 객체를 만드는 것을 보여주는 것이 어려울 수도 있다. 왜냐면, 생성자는 오직 파라미터의 개수와 타입으로만 구분할 수 있기 때문이다.
생성자가 String과 같은 단순한 파라미터를 갖는 경우에도 문제가 될 수 있다.
세터 인젝션을 사용하는 경우 세터 메소드의 이름을 통해서 String 파라미터가 무엇을 의미하는 지 알려줄 수 있다. 반면에 생성자를 사용하는 경우 파라미터의 위치에 따라 의미가 파악된다. 
(예를 들어, 파라미터 개수가 많은 생성자를 사용할 때, 각 파라미터에 어떤 값을 넘겨야 하는 지 알기 위해서 API 문서를 매번 참고하기도 한다.)
다수의 생성자와 상속을 갖고 있다면, 문제는 더 복잡해진다. 모든 것을 초기화하기 위해서는 생성자에서 상위 클래스의 생성자로 알맞은 값을 전달해주어야 하며, 
자식 클래스에서 필요로 하는 값 또한 생성자에 파라미터로 추가될 것이다. 이는 생성자를 더욱 복잡하게 만들어버린다.
비록 생성자 방식의 단점을 설명하긴 했지만, 그래도 생성자 방식으로 시작하는 것이 좋다. 이후에 앞서 말했던 문제가 발생하면 그때 세터 방식으로 전환하는 것이 좋다.

2. 생성자방식과 Setter 방식간의 논쟁

의견1 (생성자 지지)

생성자 방식을 권하고 잇는 건 어디까지나 마틴 파울러의 의견인데, 저도 그 의견에 살짝 동의하긴 합니다. 
생성자 방식의 핵심은 객체가 생성되는 시점에 유효하게 만들자는 겁니다. 
세터 방식의 경우 객체를 생성한 시점에서는 객체를 사용할 수 없습니다. 
왜냐면 필요한 값들이 아직 덜 채워졌기 때문이죠. 세터를 통해서 값을 할당해주어야 비로서 유효한 객체가 됩니다. 
반면에 생성자 방식을 사용할 경우 객체가 생성되는 시점에 유효한 객체가 되죠. 
TDD로 유명한 켄트백 역시 이런 이유로 생성자 방식에 대해 좋다고 말했고, 마틴 파울러 역시 이를 받아들인 셈입니다.

의견2 (setter 지지)

생성자 방식이 논리적으로는 우수하나..
조립기의 입장에서 보면 상당히 불편합니다..
생성의 순서를 지켜야 하기 때문이죠..
반면 Setter 방식은 일단 모두 생성한 후
의존성을 삽입해주는(DI) 방식을 사용하기 때문에 
구현시에 좀더 유연하게 사용할 수 있는 장점이 있습니다..

3. Interface Injection

인터페이스 방식을 사용하는 프레임워크에는 Avalon을 예로 들 수 있다. 
인터페이스 방식을 사용하려면 먼저 의존성 전도를 수행할 때 사용할 인터페이스를 정의해야 한다.
인터페이스 인젝션의 경우 다수의 인터페이스를 작성해야 하기 때문에 컴포넌트 코드에 직접적인 영향을 미친다.
Avalon 방식의 경우 콘테이너가 요구하는 인터페이스의 개수가 적기 때문에, 그렇게 나쁜 방식은 아니다. 하지만, 
컴포넌트와 의존관계를 조립하기 위해 필요한 작업이 많기 때문에, 최근의 경량 콘테이너들은 인터페이스 방식 보다는 
생성자와 세터 방식을 사용하고 있다.

4. 설정(의존성부여)방식의 차이

설정방식에는 설정코드(자바클래스내), 설정파일(XML) 로 나뉘는데 pico 컨테이너가 설정코드방식을 Spring이 설정파일 방식을 사용한다.
개인적으로 설정파일방식이 여러모로 불편한점이 있는것같았는데 다음에 나오는 어떠한 개발자가 경험상으로 느낀 두방식의 차이를 적어놓은 부분이 
상당히 공감이 가는 내용이라고 생각해서 옮겨왔습니다.

설정 코드 vs 설정 파일 IoC 콘테이너와 디펜던시 인젝션 패턴

별도로 논의되기도 하고 종종 함께 논의되기도 하는 이슈가 서비스의 연결을 설정 파일로 할 것인지 또는 코드에서 할 것인지에 대한 것이다. 다양한 곳에 배포되어 사용되는 어플리케이션의 경우는 설정 파일을 사용하는 것이 좋다. 최근엔 XML을 사용해서 설정 파일을 작성하는 경우가 많다. 하지만, 코드를 사용해서 객체를 연결하는 것이 더 쉬울 때도 있다. 다양한 환경에 배포되지 않는 간단한 어플리케이션이 이에 적합한 예다. 이 경우, 별도의 XML 파일보다 약간의 설정 코드가 더 명확할 수 있다.
대조적인 예로 객체 사이의 관계가 매우 복잡한 경우가 있다. 일단, 여러분이 프로그래밍 언어에 가까워지기 시작하면 XML을 사용하는 것이 점점 약해지기 마련이다. 명확한 프로그램을 하기 위해서는 모든 구문을 갖춘 실제 언어를 사용하는 것이 더 좋기 때문이다. 만약 몇가지 구분되는 빌더 시나리오가 존재한다면, 객체를 조립하는 다양한 빌더 클래스를 만들고, 간단한 설정 파일을 사용해서 빌더 클래스를 선택하도록 하면 된다.
필자는 가끔 사람들이 지나칠 정도로 설정 파일을 사용하고 있다는 생각이 든다. 프로그래밍 언어는 설정 메커니즘을 직관적이고 강력하게 만들어준다. 최신의 언어는 큰 시스템을 위한 플러그인들을 조립하는데 사용되는 작은 어셈블러를 쉽게 컴파일 할 수 있도록 해 준다. 만약 컴파일이 싫다면, 스크립트 언어를 사용해도 잘 동작할 것이다.
종종 설정 파일은 프로그래머가 아닌 사람들이 수정할 필요가 있기 때문에 설정 파일에서 프로그래밍 언어를 사용하면 안 된다고 말하는 사람들이 있다. 하지만, 그런 경우가 실제로 얼마나 많은 지 묻고 싶다. 실제로 프로그래머가 아닌 일반 사용자가 트랜잭션 설정을 변경하는 걸 원하는 경우가 있을까? 비 프로그래밍 언어로 구성된 설정 파일은 그것이 단순한 경우에만 잘 동작한다. 만약 설정 파일의 내용이 복잡해진다면, 알맞은 프로그래밍 언어를 사용해보는 것을 고려해봐야 한다.
필자는 프로그램 방식의 인터페이스를 사용해서 손쉽게 설정할 수 있는 방법을 항상 제공하고 그런 뒤 옵션을 별도의 설정 파일로 처리할 것을 권한다. 프로그램 방식의 인터페이스를 사용하기 위해 설정 파일을 조작하는 방식은 쉽게 구현할 수 있다. 만약 컴포넌트를 프로그래밍 인터페이스를 통해서 설정할 수 있다면, 컴포넌트 사용자는 프로그래밍 인터페이스를 사용하거나, 컴포넌트 개발자가 제공한 설정 파일을 사용하거나, 또는 사용자가 직접 개발한 설정 파일 양식을 사용해서 프로그래밍 인터페이스로 쉽게 연결할 수 있을 것이다.

5. 기타궁금증

객체의 생성및 관계설정이 xml로딩시에 결정이 되는지 아니면 객체가 불려지는 시점인지?
생성자는 객체생성시에 값이 초기화되는데 setter 는 언제 호출이 되는가?
생성후에 xml참조에 따라 set된다면 생성자초기화랑 별차이가 없지않는가?
객체의 라이프사이클이 관리된다는게 꼭 장점만 있는가?
스프링 빈으로 등록하지않고 개발자가 직접 생명주기를 부여하는 방법은 없는가?
실제 개발시에 xml파일은 서로 다르게 가져가야 되지않는가?

토론주제

Spring 프레임워크를 어디다 써야할까?^^
Spring 프레임워크를 기반으로 하는 애플리케이션의 규모는 어느 정도일까?
Spring 프레임워크를 사용시 개발 제안시 Customer을 이해시키기 위한 방법은?
Spring 프레임워크를 사용시 개발자에 대한 교육방안은?
Spring 프레임워크를 사용하여 개발시 선행되어야하는 전제조건은?
Spring 프레임워크의 IoC 기반으로 애플리케이션을 개발할 때의 장점은?
IoC 기반으로 애플리케이션을 개발할 때의 테스트 용이성은 어떠할까?
Spring 프레임워크를 이용할 경우 Interface Oriented Programming이 가능한데 이 방식의 강점은? 굳이 인터페이스를 사용할 필요가 있을가?
Spring 1.x에서 Spring 2.x로 버전업 되면서 Spring Core와 IoC에서 변경된 부분은? 왜 이와 같이 변경되었을까?

참고문헌

1차 오픈 소스 스터디 자료 : Spring Core, IoC에 대한 기본적인 내용
2차 오픈 소스 스터디 자료 : Spring Core, IoC에 대한 기본적인 내용
IoC 콘테이너와 디펜던시 인젝션 패턴 : IoC에 대한 마틴 파울러 문서 번역본
V3_InversionOfControl.pdf : IoC에 대한 개념을 예제와 함께 설명된글
Spring 2.0 Reference 문서

문서에 대하여

최초작성자 : 박재성
최초작성일 : 2006년 7월 22일
버전 : 0.1
문서이력 :
2006년 7월 22일 박재성 문서 최초 생성 : Spring IoC와 관련한 참고 문헌 추가

728x90

'Tip' 카테고리의 다른 글

Cassandra 란  (0) 2021.08.30
hazelcast 란  (0) 2021.08.28
MariaDB 란  (0) 2021.08.14
PostgreSQL 란  (0) 2021.08.14
InnoDB(이노DB) 란  (0) 2021.08.14

댓글