검색결과 리스트
Spring에 해당되는 글 27건
- 2010/03/16 들을 만한 스프링 교육 (5)
- 2009/12/11 새로운 자바 기술을 소개하는 글 (1)
- 2009/12/10 Spring Framework vs Java EE (3)
- 2009/08/20 [Spring 기본 다지기 1] Spring과 AOP
- 2009/05/19 SpringSource의 서울 교육(Core Spring 코스) 취소
- 2009/05/16 2009년의 한국 스프링 사용자 모임(KSUG)
- 2009/03/24 바야흐로... 스프링이 대세인가? (5)
- 2009/03/20 오랜만에 서점에서 본 개발 관련 서적(일부 첨언) (7)
- 2009/02/07 SpringSource의 직원 Michael Isvy와 만나실 분
- 2008/11/20 스프링 구 버전(v2.5.4 이하)의 Java > JDBC 타입 변환 오류 (3)
- 2008/09/08 The Essence of Spring (3)
- 2008/09/04 어떤 책으로 스프링 학습을 해야 할까요? (2)
- 2008/07/16 스프링 기반 웹 애플리케이션 모델링 예제 (7)
- 2008/07/02 설계자(Designer)의 고민
- 2008/06/30 KSUG 포럼 개설... 얼렁 모이세요~ (3)
- 2008/03/20 SpringSource Tool Suite 에 대한 소회들이 올라오네요 (2)
- 2007/12/23 여섯 번째 사용자 모임 후기 (2)
- 2007/12/18 Building Spring 2 Enterprise Applications 번역 관련 글 이동 (2)
- 2007/12/14 스프링을 통해 진화하기 (2)
- 2007/10/24 5회 사용자 모임 Acegi 발표 시나리오 사전 공유 (4)
- 2007/09/17 Spring에 대한 10가지 오해 (2)
- 2007/07/06 스프링 친화적인 확장법
- 2007/04/27 다음 스프링 세미나 주제는 Spring Web MVC (4)
- 2007/04/22 스프링 공개 세미나 에피소드 (14)
- 2007/02/15 Spring 기본 지원 Property type
- 2007/02/15 빈(bean) 초기화 옵션:bean 생성 및 초기화를 위한 다양한 방법
- 2007/02/15 Configuration Metadata 이해
글
들을 만한 스프링 교육
시장수요에 따라 국내 교육기관이 개설한 스프링 강좌는 있다.
하지만, EJB의 기술적 제약 극복을 위한 노하우를 쌓아온 교육 기관이 아니라면
하루아침에 높은 수준의 스프링 교육을 만들 수 없을 것이다.
레퍼런스를 통해 익힌 사용법 정도만 익혀도 교육을 만들 수는 있지만
그 정도라면 시중에 나와 있는 책이나 인터넷에서 찾을 수 있는 내용을 참조하여
실습을 하면서 고민과 시행착오를 겪는 일로 대신할 수 있다.
생업이 있어 스프링만 연구할 수는 없고 우리나라에도 쓸만한 스프링 교육이 있었으면 하는 마음에
작년 JCO 컨퍼런스에 맞춰 SpringSource 컨설턴트를 초청해 스프링 공식 교육을 시도했었다.
당시 환율 상황도 안 좋아서 4일에 300만 원(?) 정도였던 교육은 최소 수강인원(6명) 미달로 열리지 못했다.
이제는 개인적으로나 기술 수요측면에서나 때가 되었다는 생각에 스프링 교육을 다시 시도하려고 한다.
단순히 스프링 사용법이 아니라 응용력에 초점을 맞춘 첫 번째 시도를 슬슬 기획하면서
소통을 하고 싶어 글을 올렸더니 의미 있는 댓글이 달려 생각을 더 풀어놓는다.
개발 보다 운영의 일정부분은 책임을 져야 한다는 책임 의식
충분히 공감하지만 당장은 스프링에 대한 응용력 교육이 선행되어야 한다는 생각이다.
4월 첫 번째 스프링 교육을 기획하는 지금 처음 이프릴 세미나를 준비할 때가 떠오른다.
90분 라이브 코딩을 위해 연습할 때 가졌던 긴장감이 필요한 시점이다.
글
새로운 자바 기술을 소개하는 글
| S 서블릿 3.0에서 파일 업로드 (2009년 10월) | |
| 넷빈즈 6.8로 자바 EE 6 시작하기 (2009년 9월) | |
| 3년을 기다렸다 (2009년 6월) |
Toby 형이 쓴 글도 있다. 자바 스펙을 직접 다루지는 않았지만, 자바 진영에서 일어나는 DI(Dependency Injection)의 발전과정을 그대로 담은 스프링의 애노테이션에 대한 글이다.
Spring 3.0 (56) @Bean 사용의 주의사항
요구하는 배경 지식이 많아 쉽지 않은 글이지만 개념을 잡는데 도움을 주는 글이다. 이를테면 다음과 같은 표현은 충분한 경험이 없다면 쉽게 포착할 수 없는 말이다.
이참에 공부를 좀 할까 하는데, 테스트를 위한 시험 문제도 제공했다.
@Component
public class FactoryMethodComponent {
private static int i;
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// use of a custom qualifier and autowiring of method parameters
@Bean @BeanAge(1)
protected TestBean protectedInstance(@Qualifier("public") TestBean spouse,
@Value("#{privateInstance.age}") String country) {
TestBean tb = new TestBean("protectedInstance", 1);
tb.setSpouse(tb);
tb.setCountry(country);
return tb;
}
@Bean @Scope(BeanDefinition.SCOPE_SINGLETON)
private TestBean privateInstance() {
return new TestBean("privateInstance", i++);
}
@Bean @Scope(value = WebApplicationContext.SCOPE_SESSION,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public TestBean requestScopedInstance() {
return new TestBean("requestScopedInstance", 3);
}
}
글
Spring Framework vs Java EE
Java EE 두 번째 항목을 보면 발표자의 수준을 의심할 수 있다.
Non-redundant APIs with specialized roles
꾸러미 성격의 스펙을 만들면서 일부러 중복을 만드는 이가 있을까? 반면 API를 구현한 제품은 어떤가? 하나의 표준(Spec)을 준수하는 다수 제품을 통해 경쟁하던 모습이 자바 커뮤니티의 강점 아니었던가? 'Non-redundant APIs'라는 표현을 쓴 이유는 다음 장표에서 확인할 수 있다. Java EE는 간결하고 Spring은 복잡한 듯 보인다. 저자가 추상화 수준(level of abstraction)이라는 개념을 탑재한 사람이라면 Java EE 를 표현한 박스 위에는 초록색으로 JBoss JSR250 implementation, IBM JSR250 implementation, Oracle JSR250 implementation 이라고 표기해야 옳다. 어떠한 기능을 구현한 제품(iBatis, Hibernate, TopLink)과 기능을 기술한 명세를 비교하는 짓은 한심하지만, 박스 그림 차체는 고쳐서 써먹을 만하다. :) 혹시라도 저자를 만난다면, "선택하는 고통"을 피하고 싶다면 닷넷으로 전향하란 충고를 해줘야겠다.

저자가 Spring에 대해 무지하지 않다는 점은 뒤에 나오는 장표가 잘 보여준다. 스펙과 제품 사이의 추상화 수준 차이에서 오는 Gap을 잘 활용하여 Spring에 대한 안 좋은 인상을 심어주려는 노력이 돋보인다. 보수일간지가 마음에 안 드는 인물은 얼굴을 찡그리는 사진만 싣듯이 화면의 반을 XML 스키마 정의에 할당해서 복잡함을 극대화해서 보여준다. 놀랍게도 Spring 설정이 나오는 모든 페이지를 중요치도 않은 XML 스키마로 덮었다.
그야말로 무의미한 일인데, 왜 Spring과 Java EE를 직접 비교할까? 2년도 더 지난 TSS 아티클에서 거론한 현상 탓이다. Spring의 인기가 높아질수록 Java EE는 힘을 잃고 있다. 변화를 깨닫지 못하는 이들의 공통점은 달라진 상황에 대해 남 탓에 무엇을 잃어버렸다고 인식한다는 점이다. Spring은 J2EE 기술에 기초하여 만들어졌고, Java EE 스펙에 대한 의존도가 줄어도 여전히 Java EE 수용에 앞장서고 있다. 심지어 스펙을 앞서 지원하는 일까지 있으니 말이다.
별생각 없이 보면 잘 만든 장표처럼 보일 수 있지만, 결국은 잘못된 전제를 활용한 세련된 FUD이다. 교훈이라면 추상화 수준(Level of Abstraction)을 어기면 어떤 함정에 빠져 시간을 허비하거나 어처구니 없는 사기에 현혹되기 쉬운지 알 수 있는 사례다.
글
[Spring 기본 다지기 1] Spring과 AOP
스프링과 AOP(Aspect-Oriented Programming) 관계는 다음 그림이 잘 설명해준다.

AOP는 기괴하다 싶을 용어와 함께 하기로 유명하다. 그래서, 비유적으로 이야기를 끌어가 보자. 위 삼각형을 도원 탁자라고 해보자. 탁자 위에는 사발과 술병이 올려 있을 법하다. 물론 탁자를 앞에 두고 유비, 관우, 장비가 앉아 있다. 스프링의 중추인 IoC는 유비에 비유할만하다. 하지만, 스프링이 EJB를 잠재우는 데에는 관우격인 Portable Service Abstractions의 공이 크다. 이제 하나 남은 AOP는 장비라 하자.
AOP는 장비만큼이나 다루기 어렵다. 보통은 으뜸가는 장수로 일당백을 한다. 하지만, 감정에 휘말려 자칫 실수를 범한다. 비유가 기막히게 들어맞는다. 보통 스프링을 처음 쓸 때는 AOP를 쓰는지도 모르고 사용한다. 레퍼런스를 따라 하다 보면, 필수 기능인 트랜잭션 처리 과정에서 자연스레 쓰이기 때문이다.
이제 비유는 접어두고 스프링 삼각형의 한 축을 이루는 AOP의 역할을 한마디로 정의하면 다음과 같다.
하지만, 스프링은 반드시 AOP를 쓰도록 강제하진 않았다. IoC 컨테이너와 AOP 기능은 소위 말하는 "loosely-coupled" 연결을 맺고 있다. AspectJ와 통합하면서 점차 강력해지긴 했지만, 초창기 Spring은 AOP에 대한 별다른 지식이 없이도 AOP를 활용할 수 있게 했다. 스프링은 AOP 적용에 있어서도 늘 그렇듯 다양한 선택을 준비했다. 그래서, 새로운 기술을 무리하게 도입하기보다는 점진적으로 활용할 수 있는 토대를 제공한다.
![]() |
Professional Java Development With The Spring Framework (Paperback) - ![]() Johnson, Rod/John Wiley & Sons Inc |
어느 조직이나 회사건 모든 업무에 걸쳐 발생하는 일이 있다. 기획, 영업, 구매, 회계, 총무, 경영지원 등 기능과는 다른 영역이 있다. 예를 들어 청소나 기반 제품 납품과 유지보수 같은 일은 어떤가? 최근에는 본질적 기능 외에는 전문 업체에 외주(Out-sourcing)를 줘서 전체 비용(TCO)을 줄인다.
AOP는 이러한 지혜를 순수 기술 차원에 포팅했다. 그 이름도 유명한 제록스(Xerox)가 해냈다. 지금은 다른 엔지니어와 조직에서 계승했다.
하지만, 태생적으로 본질 업무(OOP)와 다른 면이 있어서 오브젝트(object)가 아닌 애스펙트(aspect) 혹은 어드바이스(Advice)로 구분한다.
너무 비유로 흘렀는데 Professional Java Development With The Spring Framework 에 따르면 다음 사항이 AOP 적용을 통해 이익을 볼 수 있는 전형적인 사례다.
- 특정 인터페이스를 구현하는 모든 메소드(혹은 Operation)가 각기 다른 트랜잭션 안에서 수행해야 할 때
- 결과 반환에 자원 소모가 많은 경우에 빠른 응답을 위해 일정 기간 캐시(cache)를 써야 할 때
- 공유하는 DB 필드(field) 값인지라 한 쓰레드에서 변경이 발생하면, DB Lock을 걸고 바로 반영하여 I/O를 발생하기보다는 메모리에서 처리하고 필요할 때 혹은 노는 시간(idle time)에 반영하기
- 한 달간 진행하는 판촉행사를 위한 코드를 현행 코드 여기저기에 끼워 넣고 나중에 빼버리는 실수하기 위한 작업이 아니라 명확하게 구분하여 관리할 수 있게 하기
글
SpringSource의 서울 교육(Core Spring 코스) 취소
I thought I ought to email you officially to let you know our training course in Seoul has been cancelled. Although we got several people signed up, we were unable to contact most of them to sort out payment and other arrangements. In the end we had no choice but to cancel.
I wanted to thank you for the help you have offered us. I regret that I will not get to meet you after all.
Best regards, Paul.
Dr. Paul Champman은 함께 최소된 서울과 도쿄의 Core Spring 과정 강사 예정자입니다.
글
2009년의 한국 스프링 사용자 모임(KSUG)
다시 측면에서 보면 아직 KSUG는 정체성을 갖고 있지 않다. KSUG를 함께 설립한 토비님이 쓴 글, KSUG는 커뮤니티인가에 나타난 고민은 여전히 유효하다. 정체성은 약한데, 존재감은 커진다. 프로그램으로 비유하면 코드는 늘어나고 기능은 커지는데, 아직 응집력 있는 클래스로 명확하게 구분하지 못해 내부적으로는 가칭의 클래스로 진화하는 꼴이다.
한 때, 나는 잘못 생각하여 존재감을 더 키워 무기로 삼고자 했다. 그 중 하나가 포럼 가입자 수에 대한 집착이었다. 후원을 받아 무언가 일을 하려면, 어느 정도의 회원수를 요구했다. 그런데 회원 수가 늘어날수록 오히려 의구심이 들었다. 비전 설정이나 현실 인식 모두가 적절하지 못했다.
이유는 달랐지만 비슷한 시점에 토비님과 나는 포럼을 버리기로 마음 먹었다. 2009년 4월 17일부로 포럼은 읽기 전용으로 묶고 메일링 리스트로 이전했다. 1400 여명의 가입자를 뒤로 하고 물갈이(?)한 결과 딱 한 달이 지난 지금 76명을 찍고 있다.
KSUG를 만들고, 첫 세미나가 2007년 6월이니 아직 채 2년도 지나지 않았다는 사실에 새삼 놀랐다. 꽤 긴 시간동안 정체성 확립조차 하지 못했다고 채근했는데, 생업에 쓰고 남은 자투리 시간을 이용했다는 점을 고려해보면 2년 동안 그래도 한 일이 적지 않았다. 좀체 보기 힘들었던 양질의 세미나를 했고, 활성화라고는 할 수 없지만 포럼도 운영했다. 기술 웹진 실험도 했고, 밀도 있는 스터디도 만들어냈다.
그리고, 새로 시작하는 느낌을 갖는 지금은 좀 더 밀도 있는 논의를 할 수 있는 토대를 쌓고 있다. 근자에 읽은 나는 빠리의 택시운전사에서 마음에 드는 표현을 찾았다. '택시운전사들 사이의 집단 연대감'. 토비님과 KSUG를 만들 때부터 우린 'User Group' 혹은 '사용자 모임'을 표방했다. 스프링 사용자는 영구적인 직업이 아니기 때문에, 스프링 사용자로서의 삶만으로는 연대감을 만들긴 힘들다.
그치만 스프링은 그저 하나의 프로그램에 지나지 않는 것은 아니다. 매년 2차례의 국제적인 컨퍼런스를 열고, 주류로 부상한 프레임워크이기도 하지만, 새로운 프로그래밍 모델, 배포 모델, 운영 모델을 논하는 이들의 위상은 과거 SUN이 J2EE 커뮤니티를 통해 하고자 했던 역할 모델을 실현한 모습이다. 하지만 스프링의 산업에서의 위상은 나에게 그리 큰 의미를 주지는 않는다. 스프링의 성공이 나의 성공은 아니니까. :)
나에게 있어 스프링은
- 한 방을 노리기 보다 끈질기고 치밀한 노력을 통해 만들어낸 결과를 보여주는 스승이고
- 일관성을 지키면서도, 지속적으로 향상하는 것이 가능함을 알려주는 표상이며
- 지금 있는 자리에서 너도 스스로의 솔루션을 찾으라는 지엄한 꾸짖음이며
- 심지어 언제라도 돌아갈 수 있는 편안한 안식처
KSUG에 모인 사람들은 모두 각자의 다른 삶을 살고 있고, 스프링에 대한 이해와 관심도가 모두 다르다. 우리사회의 관성을 반영하여 굳이 이를 획일화 할 필요는 없다. 오히려 차츰 서로 생각을 나누고, 각자의 '스프링'을 둘러싼 삶의 단편을 공유하다 보면 연대를 만들 수 있을 것이다.
이야기를 하다보니 감상적이 되었는데, 거창한 뜻을 가지고 메일링을 만든 것은 아니다. 그저 일상이 모여 내려진 자연스런 판단을 따랐을 뿐이다.
연대를 꿈꾸는 스프링 사용자들은 메일링을 함께 하길 바란다:
http://groups.google.com/group/ksug
아마 다음 달에 처음으로 KSUG 이름으로 스프링 교육을 할 예정이다. 계획 안은 2, 3가지가 있지만 현재 그 중 하나가 실현 단계에 있다. 유명 교육 기관에서 수행하는 스프링 교육이 만족스럽지 못하다는 이야기를 많이 들어 양질의 교육을 내놓고 싶은 욕심이 있었다. 하지만, 강사료가 적어서 고민했는데 박찬욱군이 나서서 결국은 개설하기로 했다. 강사료가 적어도 스프링 교육에선 국내 최고가 아닐까 싶다. 교육 과정은 찬욱군과 함께 내가 직접 만들었다. 노동부 지원을 통해 중소기업 재직자 대상으로 무료로 교육할 예정인데, 주말 시간에 진행할 듯하다.
6월 20일 개설하는 이번 교육을 필두로 KSUG는 여력이 되는 한 부끄럽지 않은 스프링 교육을 내놓을 예정이다. 교육을 하려는 마음은 직작부터 있었는데, 생업 탓에 여력이 없어 덮어 두었는데 '스프링 유행에 편승하여 만들어진 엉터리 스프링 교육에 피해를 본 여친'과 '내 이름과 KSUG 이름을 팔아먹는 교육이 있다는 첩보'가 결정적인 계기가 되었다.
참! 그리고 조만간 번개가 있을 예정입니다.
글
바야흐로... 스프링이 대세인가?
글
오랜만에 서점에서 본 개발 관련 서적(일부 첨언)
하나는 ray님 추천도서 목록에서 봤던 이클립스 프로젝트 필수 유틸리티 : subversion, Ant, JUnit, Trac 이다. 필요할 때 딱 맞춰서 나온 좋은 책이다. 말 그대로 필수 유틸리티를 잘 정리했다. 책을 훑어보니 초심자가 반드시 알아야 할 내용을 적절한 수준으로 정리했다.
![]() |
이클립스 프로젝트 필수 유틸리티 : subversion, Ant, JUnit, Trac - ![]() 민진우 외 지음/한빛미디어 |
책에 대한 아쉬움은 아니지만, 좀 더 깊이 있는 내용을 원하거나 실무에서 문제 해결을 위해 참조하려는 독자를 위한 내용으로는 다른 책이 필요할 듯하다. 과연 그런 책이 나온다고 해도 얼마나 팔릴 수 있을지 의문이지만...
(아래 책은 저작권 침해 논란에 휘말린 책임을 알려 드립니다.)
두 번째 눈에 띈 책은 SPRING 2.5 실무 프로그래밍이다. 스프링 2.5 책이라곤 하나밖에 없는 줄 알았는데 처음 보는 책이다. 전체적으로 초보자가 접근하기 좋은 흐름으로 구성했다. 저자 약력을 보니 강의 경험이 많은 베테랑인 듯하다. 예제도 어렵지 않아 처음 따라 해보기엔 좋을 듯하다. 내가 못 찾았는지 모르지만, 2.5 고유한 기능에 대한 설명은 없고, 설정은 모두 xml을 이용했다. 출판 시점에 맞춰서 판매 촉진을 위한 2.5를 붙여둔 듯하다.
![]() |
SPRING 2.5 실무 프로그래밍 - ![]() 성윤정 지음/삼양미디어 |
서점을 나서면서 막연히 생각해봤다. 이런 책을 통해 천천히 예제를 따라 해보는 방법이 효과적인지. 배우는 이의 성향 문제가 중요하겠지만, 영어 읽기가 가능하다면 스프링 배포 파일에 들어 있는 예제를 돌려보면서 분석하는 방법을 권하고 싶다. 아마 그 정도를 해보면 위 책의 내용과 비슷한 수준의 지식을 얻을 수 있다. 물론, 영어 읽기, 스프링 레퍼런스 찾아보기, 왜 이렇게 만들었을까 고민해보는 인내의 시간을 감당해야 한다.
지인의 블로그를 보니 내가 위 책을 폄하하는 듯이 느낄 수도 있을 듯 하여 사족을 단다. 나는 이 책을 스프링을 공부하는 가까운 지인에게 추천한 바 있다. 하나의 시스템이 여러 개의 인터페이스를 갔듯 사람마다 다른 책을 원할 수 있다. 나는 스프링을 학습하는 방법으로 책과는 다른 방식을 조언했다. 위 책에서 불편하게 느껴지는 부분은 단 하나다. 스프링 2.5 고유의 내용을 살펴보기 힘든데, 2.5 라고 붙어 있어서 잠재적인 독자/스프링 사용자의 오해를 조금이나마 막고 싶었다.
글
SpringSource의 직원 Michael Isvy와 만나실 분
글
스프링 구 버전(v2.5.4 이하)의 Java > JDBC 타입 변환 오류
DTO 객체에서 Long으로 정의한 필드 값이 insert나 update할 때 integer 처럼 들어간다는 것이었다.
확인해보니 integer 처럼이 아니라 Integer로 들어가게 되어 있었다. 동료가 문제를 찾았는데 내가 그 코드를 확인해보니 문제가 없었다. :) 로컬에 서로 첨부한 소스 버전이 달랐다. 구글링을 해보니 쉽게 버그 리포팅을 찾을 수 있었다: SPR-4840
javaTypeToSqlTypeMap.put(long.class, new Integer(Types.INTEGER));
javaTypeToSqlTypeMap.put(Long.class, new Integer(Types.INTEGER));
2.5.3 버전에서 버그를 찾은 Pavel Marinchev은 수정할 코드까지 제시했다:
javaTypeToSqlTypeMap.put(long.class, new Integer(Types.BIGINT));
javaTypeToSqlTypeMap.put(Long.class, new Integer(Types.BIGINT));
StatementCreatorUtils 클래스 소스를 보면 정적 블럭으로 초기화하는 코드 중에 이를 볼 수 있다. 아쉽게도 해당 버그에 대한 테스트 코드1는 찾을 수 없었지만, 2.5.5 ChangeLog에서 변경사항을 찾을 수 있었다:
* BeanPropertySqlParameterSource uses specific integer/decimal SQL types by default now (e.g. TINYINT, BIGINT, DOUBLE)
spring.jar 라는 jar 파일만 보면 버전을 알 수 없다. Manifest를 열어보니 2.5.4 임을 확인할 수 있었다. 이럴 때는 번거롭더라도 Maven을 사용하여 라이브러리를 명시적으로 관리하는 것이 이점이 있어 보인다. 일민형이랑 채팅하다가 'jar 버전 테스트를 해야 한다'는 말에 바로 테스트를 추가하기로 했다. 권남님한테 배운 것인데 SpringVersion 클래스를 이용하면 매우 쉽게 테스트 작성이 가능했다.
참고로 2.5.6 과 2.5.4 버전에서 위에 언급한 코드 차이를 보여주는 부분을 첨부한다.
- 스프링은 종종 이슈/버그에 대해 별도의 테스트 메소드를 만들어두기도 한다. 매우 훌륭한 프랙티스인데 조만간 관련 글을 쓸 것이다. [본문으로]
글
The Essence of Spring
"왜 new를 쓰지 않고, IoC를 하는가?"
질문의 요지는 맹목적으로 기술을 추종하지 말고, 장단점을 알고 적절히 활용할 수 있어야 한다는 메시지였다. 그러던 차에 작년쯤 올라온 The Essence of Spring, 또 댓글을 통해 2006년에 쓰인 The Essence of Spring을 봤다. 스프링에 관심 있는 다른 분들도 한 번쯤 왜 스프링을 공부하거나 사용해야 하는지 반추해보는 기회가 될 수 있다 생각해 글을 소개한다.
먼저 Rossen Stoyanchev는 'Spring is about dependency injection of plain objects'라고 짧게 정의하고 부연 설명과 사연을 달았다. IoC나 DI는 혼용해서 쓰이는 경우가 있는데, 정확하게는 IoC하는 과정에서 객체를 구성하기 위해 DI를 하는 것이다. 여튼 최초의 질문으로 돌아가서 new를 안하고, IoC를 하는 이유는 뭐라고 답할 수 있을까?
그 날은 답을 하지는 못했지만, 이미 오래 전에 답을 알았다. OOAD를 현장에 보급하던 당시 EJB로는 거의 불가능했던 OOD를 가능하게 하는 솔루션이 스프링이었다. OOD 솔루션을 찾던 때, 먼저 발견한 것은 TSS에 올라온 The J2EE Architect's Handbook 이었다. 이를 적용하려던 차에 스프링을 발견했고, 성공적으로 적용했다. 여기서 성공이라는 의미는 분석 모델과 설계 모델, 그리고 코드 사이의 유기적인 전환이 개발자들을 통해 실현했다는 것을 의미했다. EJB를 쓰던 시절에는 정말 어렵고도 어려웠던 일을 너무나도 쉽게 성공했다.
위 글에서 굵은 글로 표현한 것처럼 new 대신 IoC/DI를 활용하는 이유는 업무 외적인 것들 즉, 기술적인 내용을 업무를 표현한 코드와 섞이지 않게 하려는 의도이다. 이것은 EJB가 최초에 등장했을 때 Sun에서 하던 이야기와 다르지 않다. 단지 EJB와 스프링이 공언한 바를 얼마나 실현하는가에 차이가 있을 뿐이다.
인용한 글과 같은 맥락이지만, 좀 더 친근한(게다가 한글로 된) 표현은 얼마전 올린 토비형의 글에서 찾을 수 있다. 가서 읽어 보시길... 짧다. ^^
그리고, 키스 도날드의 글은 스프링의 효용성을 간명하게 말하고 있다.
글
어떤 책으로 스프링 학습을 해야 할까요?
![]() | Spring 프레임워크 워크북 박재성 지음/한빛미디어 |
스프링은 역서도 꽤 있다. 가장 두꺼운 책으로 기억하는데 Spring in action 역서도 있다. 최근에 2판이 나왔는데 회사 동료가 공동역자로 참여해 현재 리뷰중이다. Spring in action 역시 레퍼런스 스타일이라 실무 적용과는 괴리가 좀 있다. 개인적으로 Spring in action을 통해 가장 큰 도움을 받았던 부분은 Acegi 개념을 이해할 때 였다. Spring in action은 스프링 레퍼런스보다는 개념 설명이 좋다. 그림도 많고, 설명이 간결하다. 반면 실무 적용에 참고할 용도로는 Pro Spring이 좋다. 이 책은 개념 설명보다는 활용법 측면이 강하다.
2.5를 다루고 있지는 않지만, 스프링을 이해하는데는 여전히 로드 존슨의 빨간책 세 권이 최고라는 점은 많은 사람이 동의할 것이다. 아쉽게도 역서는 없거나 부실하다. 1권만 역서가 있는데, 번역 시점 상 책 내용을 이해할만한 사람이 드물 시점에서 무리하게 번역을 시도한 것이 아닌가 하는 짐작이 간다. 특정 페이지만 읽었던 기억이 있는데 역자가 내용을 이해하지 못했다는 인상을 받았다. 로드 존슨의 세 권은 마지막 서적은 주로 사용법 관점이고, 첫 책은 설계 철학을 이야기하고 있다. 세 권 중에 가장 마음에 드는 2권 without EJB는 양자를 적절히 다뤘다. 하지만, 이 세 권은 꽤나 어렵다.
현실은 이러한데, 토비형이 나름 심혈을 기울여서 스프링 책을 쓰고 있다. Agile Spring이라고, 전에 소개한 바 있는 Agile Java 에서 이름을 따왔다고 한다. 기획안을 들어보니 3부로 구성했는데, 1부는 점차 진화하는 형태로 코드를 따라가면서 스프링 설계 철학을 다룬다고 한다. 2부는 전반적인 스프링 기능 소개를 하고, 마지막 3부는 아키텍처에 대한 이야기를 담고 싶다고 한다. 흥행을 떠나 스프링 사용자라면 흥미를 가질 수 밖에 없는 구성이다. 수십권의 책은 물론이고, 오랜 ACM 논문까지 뒤척이며 집필 삼매경에 빠졌다고 한다. 즐거운 마음으로 책을 쓰고 있다는 점이 출간하는 서적에 기대를 갖게 만든다. 오는 9월말을 목표로 기획하고 있는 세미나에서 책 내용을 일부 공개하자고 제안을 했다. 토비형도 흥미로워했는데, 세미나에 대한 구체적인 계획이 나오지 않아서 자세히 언급은 못하겠다.
글
스프링 기반 웹 애플리케이션 모델링 예제
급하게 그려서 오류가 많았는데 수정한 것 다시 올립니다.
먼저 유스케이스를 작업 단위로 하는 경우(혹은 Usecase Driven Development라거나)라면... 이렇게..
사용하는 클래스와 이들의 관계, 역할을 묘사한 그림. 역할 명은 변수 명과 일치시킬 수도 있지만, 꼭 그래야 할 필요는 없다. 모델링은 의사소통을 위한 점이란 사실을 잊지말라.
그리고 필요한 시나리오. EA를 쓰는 경우 별칭(Alias) 기능이 있기 때문에 잘 사용하면 하나의 그림을 다른 용도로 쓸 수 있다. 일타이피인데, 먼저 아래와 같이 표시하면 메소드 호출 관계를 보기에 좋다. 고로 구현에 도움이 될테고...
한글로 별칭을 주고 다이어그램 옵션을 조정하면 아래와 같이 볼 수 있다. 개발자가 아닌 사람 혹은 자바나 스프링 기술을 잘 모르는 이와 화면 흐름, 객체 관계를 이야기 하기에 도움이 된다.
클래스 다이어그램도 마찬가지
글
설계자(Designer)의 고민
무슨 소린고 하니 아래 글은 OSGi 사양(Spec) 수립 과정에서 고민이다. 기존 코드를 OSGi가 포용하기 위해서 '격자의 질서'를 버릴 것이냐? 즉, 기존 유산 그대로 활용하기 위해 OSGi가 추구하던 단순함을 포기할 것냐? 아니면, 단순함을 고수하기 위해서 기존 유산을 포기할 것이냐? 그것도 아니면 사양에서는 건너 뛰어서 프레임워크 구현에 맡길 것이냐?
격자의 질서란 본문을 임의로 요약한 표현이다. ㅡㅡ;

흥미로운 사실은 마치 Spring 설계 원칙을 이야기 하는 것 같다. 게다가 아주 친숙한 표현까지... :)
simple but not simplistic, providing maximum bang for the buck
글
KSUG 포럼 개설... 얼렁 모이세요~
일민형이 고대하던 포럼이 만들어졌다. 오픈시드때 지쳐 나가떨어진 물개형을 지켜주지(?) 못해 아쉬웠는데 초반부터 댓글이 장난 아니다. 일민형이 스프링 전문자로써 할 일을 해주는 이때, 별로 아는 것도 없는 나는 정안수 떠 놓고 기도하는 심정으로 과거에 세미나에 참석했던 분들 명단을 가지고, 일일이 메일을 보내고 있다. 대충 200통은 보낸 것 같은데 장난 아니다. 일방적으로 정보 전달하는 형태를 벗어나기 위해 나부터 참가자 분들에게 관심을 보이기로 한 것이다. 대 여섯번은 '그만 둘까?'했는데, 이제는 익숙해졌다. 극기 훈련하는 기분이긴하다. 낼 일하려면 여기 까지 하고, 점심때나 퇴근 후에 계속해야겠다.
글
SpringSource Tool Suite 에 대한 소회들이 올라오네요
SpringSource Tool Suite을 살펴보고 싶으나 우선 KSUG 동료들이 올린 포스팅에 대한 링크부터 소개해드리죠.
SpringSource Tool Suite에 이런 기능이?!
SpringSource Tool Suite preview
[SpringSource Tool Suite review] Mylyn을 사용한 튜토리얼 제공
글
여섯 번째 사용자 모임 후기
Toby님 발표는 역시 시간이 모자랐습니다. 토비님 발표는 언제나 차분하게 방대한 내용을 다룹니다. 단순히 지식 전달에 머무는 것이 아닌지라 많은 영감을 줍니다. 이번에는 발표를 맡지 않아서 저 역시 차분하게 앉아서 경청할 수 있어 좋았습니다. 좋은 발표는 듣는 사람 머릿속에서 화학작용을 일어나게 합니다. 무슨 말인고 하니, 토비님을 통해 알게 된 사실을 기반으로 새로운 생각의 확장이 일어나고, 그것을 어떻게 활용할 수 있겠구나 하는 영감을 생겨납니다. 그러니 이는 단순한 지식 전달 그 이상이죠.
발표 내용은 요약해서 전해드리기도 힘들 지경입니다. 주요 내용은 100 여 장의 PT가 매우 꼼꼼하게 만들어졌으니까 이를 참조하실 수 있을 것 같습니다. 조만간 KSUG 홈페이지와 Toby님 블로그에 올리겠죠. 아마 KSUG 참여하는 친구들이 주요 내용을 포스팅 하려고 벼르고 있는 것 같으니 해설판(?)도 만나 보실 수 있을지 모릅니다.
아쉬운 것은 토비님이 준비한 것 모두를 보여주기엔 3시간이 너무 부족했다는 사실입니다. 또 한가지는 토비님으로서는 QCon이나 TSE2007에서 자신이 받은 경이로움을 이 곳에 전해주고 싶었을텐데, 반응만 봐서는 전혀 알 수 없었다는 점입니다. 문화적 차이일까요? 스프링에 대한 기술적 수준 차이일까요? 아마 둘 다 관계한 것이겠죠. 그렇지만, 이번 모임에서는 매우 실무적인 질문이 오고 가기도 해서 고무적이었습니다.
내년 2월말에 JCO 컨퍼런스가 있는데 KSUG에서도 세션을 준비합니다. 토비님은 Spring OSGi 발표를 염두하고 있어서 토비님이 못다한 이야기를 제가 전해드리도록 하죠. JCO 컨퍼런스는 1시간 단위인데 이를 늘려달라고 요청하고 있습니다.
두 번째 발표 이야기를 안하면 찬욱군이 서운해 하겠네요. 첫 솔로 데뷔(?)인데 발표를 잘 했습니다. 쉽게 따라하기를 표방했는데 국내에서 JPA 활용이 아직 높지 않다는 점을 고려해보면, 모두가 쉽게 따라할 만한 내용은 아니었습니다. 그래도 애초 목적인 Spring IDE 활용을 보여주고, 평소 KSUG 발표에서 당연스럽게 사용하던 이클립스 활용법을 정리해본 것이면 충분했습니다.
7번째 모임은 JCO 컨퍼런스 때문에 Spring에 해야 할 것 같습니다. 좀 더 장시간 세미나를 해보았으면 하는 마음도 있고, 준비할 수 있는 기간도 길어서 스스로 기대하게 만듭니다.
이미지 출처: 제6회 KSUG ~ 스프링 2.5의 어노테이션과 로드존슨에 빠지다
글
Building Spring 2 Enterprise Applications 번역 관련 글 이동
글
스프링을 통해 진화하기
| 스프링을 통해 진화하기 |
|
|
스프링 소스코드가 아름다운 이유 |
|
스프링의 아버지인 로드 존슨(Rod Johnson)은 최근 올린 글 Our approach to the JCP에서 Spring Source(Interface21의 새로운 회사 이름)가 자바 표준을 만드는 단체인 JCP에 임하는 자세를 기록했습니다. 굵은 글자로 쓰인 Honesty가 유독 눈에 띄었습니다. 예전에 스프링 웹 프레임워크(Spring Web MVC)를 살펴보다가 이해가 안되어서 소스코드를 찾아본 일이 있습니다. 그때 느낀 것이 정직하게 진심을 다해 코드를 작성하면 스프링과 같아지겠구나 싶었습니다. |
|
그림 1. Strategy 패턴을 적용한 스프링 소스코드 일부 | |||||
|
| |||||
스프링을 대규모 사이트에 적용하며 | |||||
|
한창 스프링의 매력에 빠져 있을 때 실전에서 사용할 수 있는 기회가 왔습니다. 수백 억대 시스템 구축 프로젝트에서 스프링 도입을 허락한 것입니다. 프로젝트 수행업체는 그때 필자가 소속해있던 컨설팅 회사를 전적으로 신뢰했습니다. 그래서, 필자는 많은 부분을 직접 결정할 수 있었습니다. 스프링의 매력에 더하여 고객의 신뢰는 필자에게 엄청난 힘을 주었습니다. 누군가에게 전폭적인 신뢰를 받는다는 것이 어떤 것인지 독자 분들도 잘 아시리라 믿습니다. 그런 신뢰를 받지 못했다면 감히 스프링 적용을 시도하지 못했을지 모릅니다. 물론, 제가 단지 스프링을 좋아해서 결정한 것은 아니었습니다. 기술적인 면에서 보자면, 스프링 채택은 EJB 프로그래밍 모델을 대치하기 위한 것이었습니다. 대규모 사이트에서는 대부분 CBD 방법론을 적용하여 설계를 합니다. 분석까지는 객체 지향 기반으로 잘 끌고 와도 EJB 프로그래밍 모델에 적용시키려고 하면 설계 모델이 너무나도 복잡해지는 것이었습니다. EJB 컴포넌트는 다수의 클래스나 인터페이스로 구성되기 때문이죠. 그 무렵 필자는 TSS(TheServerSide.com)라는 J2EE 커뮤니티에 배포된 ‘The J2EE Architect’s Handbook’에서 소개한 방법을 채용하여 EJB 배포 모델과 애플리케이션 사이 종속성을 제거하는 기법을 사용하여 설계하도록 설계자들을 가이드 했습니다. EJB는 필수라고 여겼던 필자가 스프링에 관심을 가진 것은 스프링 1.2 버전이 준비될 즈음이었습니다.
그림 3. 스프링 배경 철학이 닮긴 로드 존슨의 서적들 |
글
5회 사용자 모임 Acegi 발표 시나리오 사전 공유
1. 보호할 페이지는 로그인 하게!
2. 패스워드 등을 확인하여 인증Authenticate!
3. 권한이 없는 사용자는 접근 거부 페이지Access Denied page로!
4. 인증authenticated과 권한 확인authorized에 성공하면 해당 페이지로!
5. 인증을 수행한 클라이언트는 쿠키를 통해 향후에는 로그인이 필요 없게!
6. 인증정보를 세션에 보관하여 뒤이은 요청에서 사용하게!
7. 캐시를 사용하여 성능 향상!
8. 사용자가 로그아웃하면 세션에 보관하던 객체 제거!
해야 할 일에 대해서.. 그림을 그릴 수 있는 것들은 옮겨본다.
1. Servlet Filter 대신 Bean을 쓰기
web.xml 이 아니라 스프링으로 설정하기 위해서 FilterChainProxy 활용
그림만 쭉 이어봐도 대략의 스토리가 나온다.
주요 필터들
Manager와 Provider 관계
계층적으로 보기
실제 클래스 배열해보기
Security Interceptor 종류
Security Interceptor 의 collaborator
참고
- Securing Java applications with Acegi, Part 1: Architectural overview and security filters: http://www.ibm.com/developerworks/java/library/j-acegi1/
- Spring in Action, 2nd edition, Craig Walls, Ryan Breidenbach, Manning 7장
글
Spring에 대한 10가지 오해
• 6 of the 10 largest banks in the world use Spring in financial applications, among them is JPMorganChase.
• Voca – implementation of a payment engine used in the United Kingdom.
• European Patent Organisation (EPO)
• European Commission
• French Tax Authority – implementation of public facing tax application
• DekaBank – German domestic bank
• Ilse Media – Holland’s biggest internet portal (ilse.nl, vindex.nl and more)
• BEA WebLogic – as underpinning technology in the WebLogic EJB3 server
• Oracle – Oracle's next generation SOA solution "Service Fabric" is based on Spring
· Java Management Extensions (JMX)
· Java Transaction API
· JEE Connector Architecture (JCA)
· Java API for XML-based Remote Procedure Calls (JAX-RPC)
· JavaMail
· Java Naming and Directory Interface (JNDI)
· and Enterprise JavaBeans (EJB) including version 3.
글
스프링 친화적인 확장법
1. Allow configuration to be managed by Spring
프레임워크인 스프링이 확장을 관장하도록 하라. 다시 말해서 IoC 원칙을 지키라.
2. Use the Spring abstractions and design idioms in your API
GigaSpacesTemplate과 같이... 스프링 사용자들이 인지하기 쉽도록
3. Support unit and integration testing
4. Integrate with the infrastructure services abstractions used by Spring
이미 스프링에 있는 기능은 중복해서 개발하지 말라
글
다음 스프링 세미나 주제는 Spring Web MVC
엠파스 블로그를 사용하던 시절에 Spring MVC컨트롤러 탐험기 안내 라는 이름으로 정리를 했었다. 벌써 1년도 훨씬 지났다. 스스로 다시 한번 정리를 할겸 세미나 주제로 정했다. 게다가 지난 세미나에서 가장 많은 분들(57명)이 다음에 다뤄졌으면 하는 내용으로 꼽았다.
아직 발표를 구상할 단계는 아니지만 주로 다음과 같은 내용이 다뤄질 것이다.
- 스프링 웹 MVC가 제공하는 컨트롤러 클래스 각각의 특징
- PropertyEditor의 활용
- Validation
- referenceData() 활용
- DispatcherServlet 작동 및 다른 웹 MVC와의 연동 원리
토비님이 발표할 내용은 아직 확정되지 않았지만, 아마도 irene이라는 이름의 프로젝트 스타트킷이 될 것이다. appfuse보다 간결하고, 이클립스에 최적환 된 녀석으로 고안되었다. 오픈시드에서 처음으로 내놓는 오픈소스 프로젝트가 될 것이다. 토비님 블로그에 가보면 irene의 기반으로 사용되는 Maven에 대한 공부가 한창인 것을 확인할 수 있다.
어제 기묘 대표님이 얼핏 사용이 가능한 다른 세미나 장소를 얘기한 것 같은데, 다음에는 화면이 좀 큰 곳에서 할 수 있으면 좋겠다.
글
스프링 공개 세미나 에피소드
하지만, 더 치밀하게 했어야 할 부분들을 놓쳐서 몇 가지 실수를 범했다. 즉흥적으로 라이브 코딩을 하다 실수한 것도 있고, 참석자 명단을 출력해놓고 가져 오지 않은 것도 그렇고... 이런 정도는 스스로도 봐줄만 하다..ㅡㅡ;
세미나를 마치고 나서는 옆에서 지켜봐준 보스, 토비형이 가장 먼저 고마웠다. 그리고 사진에 다 담지는 못했지만 궂은 일을 밝은 표정으로 해준 이 친구들(사진에 나온 이+찍은이, 용가리, 멀리서 와주신 멀리서 와주신 영근님, 계옥님, 용우님)에게 고맙다. 촬영기사로 봉사해준 한수 사이트엔 벌써 갤러리 스타일의 포스트가 올라왔다.
그리고 장소 제공에 힘써주신 JCO 양수열님, 진흥원의 이재경 선임님. 양수열님도 그렇고, 다른 일로 못오신 김태완님, 송희정님은 마치 본인의 일인양 열심히 도와주셨다.
에이콘에서 지원해주신 풍성한 다과 덕에 세미나에 윤기가 흘렀다. 그간 초컬릿이 넘쳐나는 세미나는 흔히 볼 수 없었다. 일반 종이컵 사이즈가 아닌 별다방 숏 크기의 에이콘 종이컵은 명품이었습니다. 에이콘과 함께 월간 마이크로소프트에서 풍성한 경품을 주셔서 즐거운 시간을 보낼 수 있었습니다.
그리고, 돌아가는 차안에서 만담으로 즐겁게해주신 물개선생님과 파란매직님, kenu님께도 감사를...
마지막으로 소중한 주말 오후 찾아와주신 많은 분들...
급하게 회사에 일이 생겼다고 못오신다는 분들이 스무명쯤 되었는데... 그래도 90분 정도가 참석하셨다. 이분들의 열정이 사그러들지 않는다면 머지않아 KSUG(한국 스프링 사용자 그룹)에서 세미나를 주최하게 될 것이다.
글
Spring 기본 지원 Property type
class="spring.ioc.propertyeditor.MultiTypePropertiesHandler"
p:byteArray="abc" p:character="a" p:charArray="가나다"
p:classArray="java.lang.Object, java.lang.String, java.lang.Integer"
p:clazz="java.lang.String" p:bool="true" p:intNumber="1"
p:longNumber="1" p:floatNumber="1.0" p:doubleNumber="1.0"
p:file="classpath:spring/ioc/propertyeditor/propertyeditor.xml"
p:inputStream="classpath:spring/ioc/propertyeditor/propertyeditor.xml"
p:locale="ko_kr" p:stringArray="1,2,3" p:string="string "
p:url="http://younghoe.info" p:pattern="a*b" />
설정 예는 위와 같고, 테스트 코드는 다음과 같다. 유의할 점은 PatternEditor의 경우는 Spring 2.0.1에 추가되어 2.0 버전에서는 찾을 수 없다는 점이다.
more..
private MultiTypePropertiesHandler handler;
@Override
protected void setUp() throws Exception {
final String path = "spring/ioc/propertyeditor/propertyeditor.xml";
Resource resource = new ClassPathResource(path);
BeanFactory factory = new XmlBeanFactory(resource);
handler = (MultiTypePropertiesHandler) factory.getBean("handler");
}
public void testByteArray(){
assertEquals(3, handler.getByteArray().length);
assertEquals((byte) 'a', handler.getByteArray()[0]);
assertEquals((byte) 'b', handler.getByteArray()[1]);
assertEquals((byte) 'c', handler.getByteArray()[2]);
}
public void testChar(){
assertEquals('a', handler.getCharacter());
}
public void testCharArray(){
assertEquals(3, handler.getCharArray().length);
assertEquals('가', handler.getCharArray()[0]);
assertEquals('나', handler.getCharArray()[1]);
assertEquals('다', handler.getCharArray()[2]);
}
public void testClassArray(){
assertEquals(3, handler.getClassArray().length);
assertEquals(Object.class, handler.getClassArray()[0]);
assertEquals(String.class, handler.getClassArray()[1]);
assertEquals(Integer.class, handler.getClassArray()[2]);
}
public void testStringArray(){
assertEquals(3, handler.getStringArray().length);
assertEquals("1", handler.getStringArray()[0]);
assertEquals("2", handler.getStringArray()[1]);
assertEquals("3", handler.getStringArray()[2]);
}
public void testClass(){
assertEquals(String.class, handler.getClazz());
}
public void testBoolean(){
assertEquals(true, handler.isBool());
}
public void testNumber(){
assertEquals(1, handler.getIntNumber());
assertEquals(1, handler.getLongNumber());
assertEquals(1.0f, handler.getFloatNumber());
assertEquals(1.0, handler.getDoubleNumber());
}
public void testFile(){
assertTrue(handler.getFile().exists());
}
public void testInputStream() throws IOException{
assertTrue(handler.getInputStream().available() > 0);
}
public void testLocale(){
assertEquals("ko", handler.getLocale().getLanguage());
assertEquals("KR", handler.getLocale().getCountry());
}
public void testNeedToTrim(){
assertNotSame("string", handler.getString());
assertEquals("string ", handler.getString());
}
public void testUrl() throws MalformedURLException{
assertEquals(new URL("http://younghoe.info"), handler.getUrl());
assertEquals("http", handler.getUrl().getProtocol());
assertEquals("younghoe.info", handler.getUrl().getHost());
}
public void testPattern(){
assertTrue(handler.getPattern().matcher("aaab").matches());
assertFalse(handler.getPattern().matcher("bbb").matches());
}
Collection 타입과 Map, Properties의 설정은 다음과 같다.
class="spring.ioc.propertyeditor.CollectionPropertiesHandler">
<property name="set">
<set>
<value>1st</value>
<value>2nd</value>
<value>3rd</value>
</set>
</property>
<property name="list">
<list>
<value>1st</value>
<value>2nd</value>
<value>3rd</value>
</list>
</property>
<property name="map">
<map>
<entry key="1" value="1st" />
<entry key="2" value="2nd" />
<entry key="3" value="3rd" />
</map>
</property>
<property name="props">
<value>
1=1st
2=2nd
3=3rd
</value>
</property>
</bean>
테스트 코드
public void testSet(){
assertTrue(handler.getSet().contains("1st"));
assertTrue(handler.getSet().contains("2nd"));
assertTrue(handler.getSet().contains("3rd"));
}
public void testList(){
assertEquals("1st", handler.getList().get(0));
assertEquals("2nd", handler.getList().get(1));
assertEquals("3rd", handler.getList().get(2));
}
public void testMap(){
assertEquals("1st", handler.getMap().get("1"));
assertEquals("2nd", handler.getMap().get("2"));
assertEquals("3rd", handler.getMap().get("3"));
}
public void testMap(){
assertEquals("1st", handler.getMap().get("1"));
assertEquals("2nd", handler.getMap().get("2"));
assertEquals("3rd", handler.getMap().get("3"));
}
Date 타입의 경우는 다음과 같이 설정할 수 있다.
p:date="2006-12-05" />
테스트 코드
private AbstractBeanFactory factory ;
@Override
protected void setUp() throws Exception {
final String path = "spring/ioc/propertyeditor/propertyeditor.xml";
Resource resource = new ClassPathResource(path);
factory = new XmlBeanFactory(resource);
factory.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd"), false));
}
public void testDate() {
DateHandler handler = (DateHandler) factory.getBean("dateHandler");
assertEquals(new GregorianCalendar(2006, Calendar.DECEMBER, 5)
.getTime(), handler.getDate());
}
}
class DateHandler {
private Date date;
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return this.date;
}
}
문자열 공백을 없애기 위해서 StringTrimmerEditor를 등록하여 사용할 수 있다.
<bean id="trimmedStringOwner" class="spring.ioc.propertyeditor.TrimmedStringOwner"
p:strings=" ,abc " />
// 등록 및 테스트 코드
public void testTrimmer() {
factory.registerCustomEditor(String.class, new StringTrimmerEditor(true));
TrimmedStringOwner handler = (TrimmedStringOwner) factory.getBean("trimmedStringOwner");
assertNull(handler.getStrings()[0]);
assertEquals("abc", handler.getStrings()[1]);
factory.destroySingletons(); // need to reset
handler = (TrimmedStringOwner) factory.getBean("trimmedStringOwner");
assertNotNull(handler.getStrings()[0]);
assertEquals("abc", handler.getStrings()[1]);
}
StringTrimmerEditor 생성자 인자는 공백 문자만 입력된 경우 null로 취급할 것인지 여부를 설정한다. 즉, true이면 공백은 null로 인식된다.
메시지를 properties 파일로 관리하기 위해서 ResourceBundleEditor를 사용할 수 있다. 이때 properties 파일은 classpath내에 있어야 한다.
<bean id="resourceBundleOwner" class="spring.ioc.propertyeditor.ResourceBundleOwner"
p:messages="spring/ioc/propertyeditor/messages" />
// 등록 및 테스트 코드
factory.registerCustomEditor(ResourceBundle.class, new ResourceBundleEditor());
ResourceBundleOwner handler = (ResourceBundleOwner) factory
.getBean("resourceBundleOwner");
assertEquals("hello", handler.getMessages().getObject("greeting"));
글
빈(bean) 초기화 옵션:bean 생성 및 초기화를 위한 다양한 방법
빈(bean)을 초기화 하는데는 다양한 방법이 존재한다.
가장 흔한 것이 생성자를 이용한 방법인데, 객체에 디폴트 생성자가 있어야 한다는 제약이 있다.
<bean name="bar" class="java.lang.Object" />
Factory 패턴을 활용할 수도 있다.
factory-method="getBean" />
이 경우는 Factory 패턴을 구현한 클래스가 필요하다.
public static Object getBean() {
return new Object();
}
}
위의 경우는 정적 팩토리 메소드를 활용한 것이다. 경우에 따라서는 팩토리 메소드를 갖는 객체마저도 Spring 컨테이너에서 관리하고자 할 수 있다. 이러한 경우는 인스턴스 팩토리 메소드를 활용할 수 있다.
<bean id="bat" factory-bean="bop" factory-method="getBean" />
인스턴스 팩토리를 활용할 경우 코드는 다음과 같다:
public Object getBean(){
return new Object();
}
}
이상을 정리하면 다음과 같은 표를 만들 수 있다.
글
Configuration Metadata 이해
OOD의 어휘: Spring의 어휘
객체(object):bean
관계(relationship):dependency
2. XML 기본 구조
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here... -->
</beans>
3. 복수의 XML 파일 이용하기
- 두가지 방법
1) BeanFactory 생성시 복수의 Resource 제공: 보편적
2) <import /> 활용: 포함하는 파일의 위치를 기준으로 상대 경로로 인식
4. BeanDefinition
컨테이너 내부에서 빈의 정의(bean definition)를 표현: 이하 요소들이 BeanDeifinition의 Properties를 이룸
- package-qualified class name
- behavioral configuration: scope, autowiring mode, dependency checking mode, initialization and destruction methods
- constructor arguments/property values
- collaborators(dependencies)
* Bean Definition의 Overview
- Bean Definition의 종류






