Whiteship's Note


S1A 첫 날 - 유겐 휄러와 Q&A

Spring/S1A : 2008.12.02 15:54


정말 정말 보고 싶었던 유겐 휄러. 착해보이고 성실해보이고 잘 생겼고 개발도 잘해 여친인지 부인인지 암튼 이쁜 짝도 있고 지금까지 제가 봐왔던 유겐 휄러는 그야말로 짱입니다.

유겐 휄러를 알게 된 건 스프링 소스 코드가 아니라 이슈 트래커를 통해서였습니다. 한 참 스프링 공부를 시작하고 레퍼런스를 요약해가며 그 안에 있는 말과 코드를 이해하려고 엄청 애쓰던 때였죠. 그 때 문서에서 발견한 오타나 코드에서 이상한 점들을 이슈 트래커에 올리면 거의 매번 유겐 휄러가 이슈를 처리해줬습니다. 그리고 한 번은 OSAF 초기 모델을 만들 때 @SessionAttributes에 대해 이슈 트래커로 상당히 길게 얘기를 나누면서 그가 얼마나 자상하고 꼼꼼한지도 알 수 있었습니다.

어쨋든 보고 싶은 사람이 바로 옆에 있었는데 누군가와 매우 오래 얘길하고 있었습니다. 어쩔 수 없이 끼어들었습니다. 한 15분은 옆에서 멀뚱멀뚱 있었던 것 같습니다. 끼어들어서 3.0-m1에 대한 이야기를 나누기 시작하자 영회형, 사부님, kenu님이 함세해 주셨습니다. 캬캬

기선: 얼마전에 이슈 트래커를 봤더니 3.0-m1 이슈가 모두 처리 됐더라. 언제 공개할 생각이냐?

유겐: 이번 내에 공개할 거다. 아마 너가 돌아가기 전에 하지 않을까? ^^

기선: 오호~! 귿. 참. 난 한국에서 왔고 너가 정말 보고 싶었다. 우린 이미 이슈트래커를 통해 얘기를 많이 나눈적이 있다. @SessionAttributes에 관한 것이었는데 그 당시 너무 친절하게 답변을 달아줘서 감동먹었다. 고맙다. 사진 한 장 찍고 싶다.

유겐: 오케

사용자 삽입 이미지

대충 이렇게 시작한 대화는 상당히 길고 재밌게 이어졌습니다.

하루에 몇 시간 정도 코딩을 하는지? 주당 50~60(기억이 가물 가물)
왜 스프링 코어 이슈는 혼자 그렇게 많이 차지하고 있는지? 자기가 배정 해 줌. 배정해 줄 사람 없으면 자기가 함.
로드 존슨과 유겐 휄러의 나이는 몇인지? maybe 38, I'm 33
개발할 때 테스트를 먼저 작성하는지 나중에 작성하는지? After
스프링 3.0에서는 빌드가 어떻게 바뀌었는지? Ant + Ivy
스프링 개발을 통해 행복함을 느끼는지? intent, 신중해야 하기 때문에 압박감을 받기도 한다.
개발자로써 어떤 방법이 학습이나 성장에 도움이 될까? 현장의 문제를 다뤄라.

이 밖에도 질문과 답변 내용이 많고 유겐이 상당히 길고 친절하게 답변해줬지만 제가 지금 좀 피곤해서 짧게 요약하고 넘어갑니다. 양해해 주세요.

처음엔 말을 어떻게 걸어야 하나 고민도 많이 하고 아.. 그냥 지나칠까 말까 하다가 용기내서 말을 걸어봤는데 정말이지 세미나를 하나도 안 들었는데 이대로 집에가도 여한이 없을 정도입니다.

다음엔 싸인 받으러 또 찾아가겠다고 바이 바이 했습니다. 다음 타겟은 뢉 하랍!!
top


Spring 2.5 on the Way to 3.0 - 유겐 휄러



참조 : Spring 2.5 on the Way to 3.0

Spring One 2008에서 유겐 휄러의 발표 동영상을 보여줍니다. 별점은. 3.2/5 정도 됩니다. 지난 번에 봤던 Using Spring Security (별점 4/5)보다 평점이 조금 낮네요.

JDK 6 지원
- JDK 1.4, 1.5 호환(1.3은 안 함)
- JDBC 4.0 지원(native connections, LOB 핸들링)
- JMX MXBenas

AspectJ LTW 지원

Java EE 5 지원

JSR-250 애노테이션 지원
- @PostConstruct, @PreDestroy
- @Resource
- self describing.

Further Java EE 5 Annotations
- @WebServiceRef/@EJB
- @TransactionAttrubute
- @PersistenceContext/@PersistenceUnit

Autowiring Annotation
- specific autowiring by type
- @Qualifier

Autodetectable Component
- @Component

@Configurable with AspectJ
- <context:load-time-weaver aspectj-weaving="on" />
- <context:spring-configured />
- @Configurable

@Transactional with AspectJ
- <context:load-time-weaver aspectj-weaving="on" />
- <tx:annotation-driven mode="aspectj" />

Annotated MVC Controllers
- @Controller
- @RequestMapping
- @RequestParam
- @ModelAttribute

Test Context Framework
- @ContextConfiguration
- @TransactionConfiguration
- JUnit 4.4 지원.

Tradeoffs
- 재컴파일(XML 설정 변경은 재컴파일 필요 없다.)
- 설정의 외부화(애노테이션은 클래스를 보면 내용을 알 수 있다.)
- 설정 재정의 가능 여부(애노테이션 설정 바꾸면 컴파일 필요하다.)

Spring 2.5 정리
- Java 5와 Java EE 5 완전 지원
- ApsectJ와 보다 긴밀한 연동
- 애노테이션 설정 강화

The Roadmap for Spring 3.0
- 7월까지 2.5.6
- 8월에 3.0 M1
  - REST 지원
  - 다양한 EL 지원
- Spring 3.0 GA는 4분기 중으로..
=> 흠.. 이미 8월 지난지 오래 됐는데, M1 소식도 못들었네요. 내년 초를 기대해봐야겠네요.

Spring 3: Core Revisions
- Java 5+ 지원
  - 스프링 코어 API에 Generic 적용
- J2EE 1.4+ 호환(웹스피어 6.1, 웹로직 9.2, JBoss 4.2)
- 스프링 EL
- 새로운 커테이너 기능 제공(annotated factory methods)
=> 흠. 제레닉 코드가 코어 API에 들어가면.. 혹시 GenericDAO 같은 거도 스프링이 제공하는건가.. 캬오..

Spring 3 and the Web Space
- 개정된 자바 웹 표준 지원(포틀릿 2.0, 서블릿 3.0)
- REST 지원
- conversation 관리
- 애노테이션 기반 위자드 컨트롤러
=> 스프링 3이 conversation이랑 애노테이션 기반 위자드 마법사를 지원해주면.. 캬오 멋질듯.

Spring 2.5 Mission Continued

Pruning & Deprecation in 3.0
- 가지칠것
  - Commons Attuributes 지원
  - 예전 TopLink API 지원
- deprecation 계획
  - 예전 MVC 컨트롤러 클래스 계층 구조
  - 예전 JUnit 3.8 테스트 클래스 계층 구조
=> 애노테이션 기반 시설 중심으로 가면서 예전 시설은 deprecation.

Spring 3.0 Summary
- REST, EL
- RESTful URI 맵핑, 포틀릿 2.0
- Java 5+, Spring 2.5 환경에서 그대로 호환 가능.

아음.. 발표 시간이 64분인데, 55분동안 2.5 얘기만 하다가 3.0 얘기는 빠르게 지나가 버려서 아쉽습니다. 그래서 별 세개만 줬어요. ㅋㅋ 유겐 횽님 Spring One America에서는 스프링 3.0 얘기 좀 더 해주세요. ㅠ.ㅠ 소스도 배포해 주시구요. 3.0에서 저는 컨버세이션 관리와 위자드 마법사가 제일 궁금해요. 그 다음으로는 코어 API에 추가할 제네릭 클래스들 중에 GenericDao같은 것들도 제공할 것인지도 궁금하구요. 마지막으론 스프링 EL도 궁금한데.. 그건 JSF 확장 기능이겠죠? JSP에서도 사용 가능한건가? 어쨋든 S1A에서 뵙겠습니다. 바이바이
top


유겐 휄러(Juergen Hoeller) 횽아한테 스프링 한 수 배우다.



updated 2008-05-17 유겐의 마무리 멘트와 3.0에 추가될 기능 언급 추가. 캬캬캬 끝까지 친절한 유겐 횽.

스프링 지라에 올린 이슈(개선 사항으로..)

We are using GenericController with Spring 2.5 @Controller APIs. And we are using @SessionAttribute like this.
@SessionAttributes(value="model")
This session attribute name "model" are used by many diffent controllers and many JSPs.

The problem is that diffent session attribute stored with same name(here is "model").
ex, When open pop-up page from parent page, the pop-up page's session attribute will override the parent page's session attribute with same name "model". So, after close the pop-up and if we click save button on parent page, we can meet ClassCastException. ^^;;

We resolve this by modify org.springframework.web.bind.annotation.support.HandlerMethodInvoker class

updateModelAttributes method's

from
this.sessionAttributeStore.storeAttribute(webRequest, attrName, attrValue);

to
this.sessionAttributeStore.storeAttribute(webRequest, attrValue.getClass().getSimpleName() + attrName, attrValue);

and resolveModelAttribute method's

from
Object sessionAttr = this.sessionAttributeStore.retrieveAttribute(webRequest, attrName);

to
Object sessionAttr = this.sessionAttributeStore.retrieveAttribute(webRequest, paramType.getSimpleName() + attrName);

This modification don't need any change or modification existing Controllers and JSPs. They now use there own session with same name.

How about apply this modification?
And could you remove final keywords from HandlerMethodInvoker to extend that class?

Now we just copy and paste original source and modify this above code, and AnnotationMethodHandlerAdapter too. AnnotationMethodHandlerAdapter class using inner class thar extends HandlerMethodInvoker(ServletHandlerMethodInvoker). So we change the HandlerMethodInvoker import statement in AnnotationMethodHandlerAdapter to our modified version. kk.. Please think about it.

유겐 횽아 1차 답변 및 대안

We actually envisioned such use cases and designed the SessionAttributeStore strategy accordingly... You should be able to implement your custom attribute prefix strategy through decorating the SessionAttributeStore, configuring your custom decorator through the "sessionAttributeStore" property on AnnotationMethodHandlerAdapter.

Juergen

2차 질문

I saw SessionAttributeStore class but in this case that class cann't help us.

Bacause, the session attribute's (internal) name sould be change according to the command object's class's name(or each controllers).
Yes, we could do this by add @SessionAttribute(name="foobar") on every controllers. but, we made and use custom tags that expects only one session attribute name "model". So we set @SessionAttribute(name="model") this on GenericController and we don't set any @SessinoAttribute on sub-clsss of GenericController.(If you want to see this class code, I can show you.)

With SessionAttributeStrore extending, we can only set a static prefix(this is not what i want.). Even if we can modify storing name by overriding storeAttribute(WebRequest request, String attributeName, Object attributeValue) method with attribute.getClass().getSimpleName()(ex. "Foomodel"), but how can we pick up that session object by that name(ex. "Foomodel") by overring retrieveAttribute(WebRequest request, String attributeName) method. We can't. There is not enough information about runtime command object type or name.

We want to use only one static session attribute name (not prefix) that can be stored and can be retrived according to there runtime object type.(ex. FooController(extends GenericController) reference Foo command object in session by "model"(internally "Foomodel"). And BarController(extends GenericController) also can reference Bar command object in session by "model"(internally "Barmodel".)

So we just do that in here(above modified HandlerMethodInvoker class).
At least we want to extend HandlerMethodInvoker class and set to AnnotationMethodHandlerAdapter.

Is there another way to do this?

유겐 횽아 2차 답변 및 질문 그리고 대안

Good point - you can't include the param type name in the session attribute name that way.

However, I would argue that including the param type is a half-baked solution to begin with: That way you'll isolate per param type, which will work when different windows operate on model attributes of different type. However, what if multiple windows operate on the same type of attribute? What if the same controller gets opened multiple times, e.g. to concurrently edit business accounts of different customers in multiple windows?

The idea behing the SessionAttributeStore strategy is that it may use a custom conversation mechanism: either storing attributes in a managed conversation object instead of in the plain session, or prefixing attribute names with a conversation identifier and still storing them in the session directly. The latter is what I would recommend for your purposes: Determine a conversation identifier for each request (from the given WebRequest object, e.g. from the URL or from a parameter) and use it as a prefix for each attribute name. This will work for storage as well as for retrieval, and will even work for multiple windows that operate on the same type of attribute.

Juergen

감사의 말

Thanks. I missed that situation (multiple windows on same type) and misunderstanded SessionAttributeStore.
I'll try to use SessionAttributeStore. I really appreciate your recommendation. ^^

문제 해결 알려주기.

Good!! We resolve this issue with you advice.

We made an interceptor that can capture URI, and made a custom SesstionAttributeStore that make session attribute session attribute using captured URI by WebRequest. Finally we configure it to AnnotationMethodHandlerAdapter

We are so impressed to Spring Framework's extensibility and your kind advice. Thanks a lot : )

유겐 횽아 마무리 멘트

Juergen Hoeller resolved SPR-4818.
------------------------------
----

      Resolution: Won't Fix
   Fix Version/s:     (was: 2.5.5)

OK, good to hear that it works for you! I'm closing this issue then, since the existing SessionAttributeStore strategy seems to be capable of handling this use case.

In Spring 3.0, we intend to provide general conversation support out of the box, also isolating concurrently active browser windows per conversation. This will essentially be a more extensive variant of what you're achieving through your custom SessionAttributeStore - then to be available out of the box in the context of general conversation management.

Juergen

ps : 유겐 횽아 최고!!
참조: http://jira.springframework.org/browse/SPR-4818
top