[Spring 레퍼런스] 3장 Spring 3.1의 새로운 기능과 개선된 점


레퍼런스의 3장은 3.1을 소개하는 장인데 문서에도 나와있듯이 3.1 RC1이 나올 시기정도에 문서가 업데이트된 것 같습니다. 현재는 3.1 GA가 릴리즈 되어 있지만 일단 문서상태 그대로 옮깁니다. 3.1에 대한 자세한 내용을 살펴보시려면 다른 글을 더 찾아봐야 할 겁니다. 이 포스팅은 다음의 스프링소스 라이센스를 따릅니다. 

이 문서는 개인적인 목적이나 배포하기 위해서 복사할 수 있다. 출력물이든 디지털 문서든 각 복사본에 어떤 비용도 청구할 수 없고 모든 복사본에는 이 카피라이트 문구가 있어야 한다.




3. Spring 3.1의 새로운 기능과 개선된 점

스프링 3.0에서 도입된 기능 위에서 스프링 3.1은 현재 개발중에 있다. 이 글을 쓰는 시점에 스프링 3.1 RC1를 릴리즈할 준비를 하고 있다.

3.1 새로운 기능

다음은 스프링 3.1의 새로운 기능들이다. 대부분의 기능은 아직 레퍼런스 문서에 적용되지 않았지만 Javadoc에는 적용되었다. Javadoc에는 완전히 검증된 클래스명이 나와있다.

3.1.1 캐시(Cache) 추상화

  • Chapter 28, Cache Abstraction
  • 캐시 추상화  (스프링소스 팀 블로그)
3.1.2 빈(Bean) 선언 프로파일


  • XML 프로파일  (스프링소스 팀 블로그)
    @Profile 소개  (스프링소스 팀 블로그)
    org.springframework.context.annotation.Configuration의 JavaDoc 참고
    org.springframework.context.annotation.Profile의 JavaDoc 참고
3.1.3 환경(Environment) 추상화

  • 환경 추상화  (스프링소스 팀 블로그)
  • org.springframework.core.env.Environment Javadoc의 JavaDoc 참고
3.1.4 PropertySource 추상화

  • 통인된 Property 관리  (스프링소스 팀 블로그)
  • org.springframework.core.env.Environment Javadoc의 JavaDoc 참고
  • org.springframework.core.env.PropertySource Javadoc의 JavaDoc 참고
  • org.springframework.context.annotation.PropertySource의 JavaDoc 참고
3.1.5 스프링의 XML 네임스페이스와 동일한 코드

자주 사용하는 <context:component-scan/>, <tx:annotation-driven/>, <mvc:annotation-driven>의 스프링 XML 네임스페이스 엘리먼트와 동일한 기능을 대부분 @Enable 어노테이션의 형식으로 사용할 수 있다. 이 기능은 스프링 3.0에서 도입된 @Configuration 클래스와 결합해서 사용하도록 설계했다.

  • org.springframework.context.annotation.Configuration 의 JavaDoc 참고
  • org.springframework.context.annotation.ComponentScan 의 JavaDoc 참고
  • org.springframework.transaction.annotation.EnableTransactionManagement 의 JavaDoc 참고
  • org.springframework.cache.annotation.EnableCaching의 JavaDoc 참고
  • org.springframework.web.servlet.config.annotation.EnableWebMvc 의 JavaDoc 참고
  • org.springframework.scheduling.annotation.EnableScheduling 의 JavaDoc 참고
  • org.springframework.scheduling.annotation.EnableAsync 의 JavaDoc 참고
  • org.springframework.context.annotation.EnableAspectJAutoProxy 의 JavaDoc 참고
  • org.springframework.context.annotation.EnableLoadTimeWeaving 의 JavaDoc 참고
  • org.springframework.beans.factory.aspectj.EnableSpringConfigured 의 JavaDoc 참고
3.1.6 Hibernate 4.x 지원

  • 새로 추가된 org.springframework.orm.hibernate4 패키지의 클래스에 대한 Javadoc을 참고해라
3.1.7 @Configuration 클래스와 빈 선언 프로파일을 지원하는 TestContext 프레임워크

@ContextConfiguration 어노테이션은 이제 스프링 TestContext를 설정하는 @Configuration 클래스를 제공한다. 새로 추가된 @ActiveProfiles 어노테이션은 ApplicationContext 통합테스트에서 엑티브 빈 선언 프로파일을 선언적으로 설정을 지원한다.

  • Spring 3.1 M2: Testing with @Configuration Classes and Profiles  (SpringSource Team Blog)
  • Spring 3.1 M2: @Configuration 클래스와 Profile을 이용한 테스트  (스프링 소스 팀 블로그)
  • Section 10.3.5, “Spring TestContext Framework” 참고
  • the section called “Context configuration with @Configuration classes”와 org.springframework.test.context.ContextConfiguration 의 Javadoc 참고
  • org.springframework.test.context.ActiveProfiles 의 Javadoc 참고
  • org.springframework.test.context.SmartContextLoader 의 Javadoc 참고
  • org.springframework.test.context.support.DelegatingSmartContextLoader 의 Javadoc 참고
  • org.springframework.test.context.support.AnnotationConfigContextLoader 의 Javadoc 참고
3.1.8 c: 더 간단한 생성자 주입을 위한 네임스페이스

  • Section 4.4.2.7, “XML shortcut with the c-namespace”
3.1.9 비표준 JavaBean의 setter에 대한 주입 지원

Spring 3.1이전에는 프로퍼티 메서드에 주입을 하기 위해 JavaBean 프로퍼티 시그니쳐 규칙을 엄격하게 따라야 했다. 즉, 모든 'setter'는 반드시 리턴값이 없어야 한다.(void) 이제 스프링 XML에서 setter가 어떤 객체타입을 리턴하도록 명시하는 것이 가능하다. 이는 메서드 체이닝(method-chaining)으로 API를 디자인할 때 setter 메서드가 'this'에 대한 참조를 리턴하도록 하는데 유용하다.

3.1.10 서블릿 컨테이너의 서블릿 3 코드기반 설정 지원

전통적인 web.xml을 프로그래밍적으로 대체하는 서블릿 3.0의 ServletContainerInitializer에 기반을 둔 WebApplicationInitializer를 새로 추가했다.

3.1.11 Servlet 3 MultipartResolver에 대한 지원

  • org.springframework.web.multipart.support.StandardServletMultipartResolver 의 Javadoc 참고
3.1.12 persistence.xml 없이 JPA EntityManagerFactory 부트스트랩하기

표준 JPA에서 퍼시스턴트 유닛은 지정된 jar파일의 META-INF/persistence.xml파일에 정의되고 @Entity 클래스를 찾는다. 많은 경우에 persistence.xml은 유닛의 이름과 의존하는 기본설정이나 필요한 외부설정(사용하려는 DataSource같은) 이외의 정보는 담고 있지 않다.그래서 스프링 3.1은 대안을 제공한다. LocalContainerEntityManagerFactoryBean는 @Entity클래스를 찾을 패키지를 지정하는 'packagesToScan' 속성을 지원한다. 이는 네이티브 Hibernate 설정에서 AnnotationSessionFactoryBean의 같은 이름의 속성이나 스프링의 정규 스프링 빈을 찾는 컴포넌트 스캔 기능과 유사하다. 사실 엔티티 스캔을 하는 패키지명시하는 JPA설정은 XML없이도 가능하다. 특히 스프링 빈의 컴포넌트 스캔에 기반한 어플리케이션과 잘 매치되고 코드기반의 서블릿 3.0 초기화를 사용해서 부트스트랩하는 것도 가능하다.

3.1.13 어노테이션이 붙은 컨트롤러의 처리를 위해 새롭게 추가된 HandlerMethod 기반의 지원 클래스

Spring 3.1은 어노테이션이 붙은 컨트트롤러가 요청을 처리하도록 지원하는 클래스의 새로운 셋을 추가했다.

  • RequestMappingHandlerMapping
  • RequestMappingHandlerAdapter
  • ExceptionHandlerExceptionResolver
이러한 클래스들은 이미 존재하는 클래스들은 대체한다.

  • DefaultAnnotationHandlerMapping
  • AnnotationMethodHandlerAdapter
  • AnnotationMethodHandlerExceptionResolver
어노테이션이 붙은 컨트롤러의 지원 클래스들이 더 커스터마이징할 수 있고 쉽게 확장할 수 있도록 해야 한다는 많은 요청을 수용해서 새로운 클래스들을 개발했다. 전에는 커스텀 어노테이션이 붙은 컨트롤러 메서드의 아규먼트 리졸버를 설정할 수 있었지만 새로운 지원 클래스를 사용하면 모든 지원메서드의 아규먼트와 리턴값의 타입에 대한 처리를 커스터마이징할 수 있다.

  • org.springframework.web.method.support.HandlerMethodArgumentResolver 의 Javadoc 참고
  • org.springframework.web.method.support.HandlerMethodReturnValueHandler 의 Javadoc 참고
다음으로 주목할 만한 차이점은 @RequestMapping 메서드를 나타내는 HandlerMethod 추상화의 도입이다. HandlerMethod 추상화는 handler 인스턴스로 새로 추가된 클래스에 의해 언제든지 사용된다. 예를 들어 HandlerInterceptor는 handler를 Object에서 HandlerMethod로 캐스팅 할 수 있고 타겟 컨트롤러 메서드나 타겟 컨트롤러 메서드의 어노테이션 등에 접근할 수 있다.

MVC 네임스페이스의 기본설정이나 @EnableWebMvc를 사용한 자바기반의 설정으로 새로운 클래스를 사용하도록 할 수 있다. 기존의 클래스들은 계속해서 사용할 수 있지만 새로운 클래스를 사용하기를 더욱 권장한다.

3.1.14 @RequestMapping의 "consume"과 "produce" 상태

'Accept'헤더로 지정된 타입을 만드는 것(produce)과 마찬가지로 'Content-Type'헤더로 지정된 미디어타입을 메서드로 소비(consume)하는 것에 대한 지원이 개선되었다. Section 16.3.2.4, “Consumable Media Types”와 Section 16.3.2.5, “Producible Media Types”를 참고해라.

3.1.15 Flash 속성과 RedirectAttributes

flash 속성은 이제 FlashMap에 저장할 수 있고 리다이렉트했을 때도 유지되도록 HTTP 세션에 저장할 수 있다. 스프링 MVC에서 flash 속성에 대한 일반적인 지원을 살펴보려면 Section 16.6, “Using flash attributes”를 참고해라.

어노테이션이 붙은 컨트롤러에서 @RequestMapping 메서드는 RedirectAttributes타입의 메서드 아규먼트를 선언함으로써 flash 속성을 추가할 수 있다. RedirectAttributes타입의 메서드 아규먼트는 리다이렉트 시나리오에서 사용된 속성을 정확하게 가져오기 위해 사용할 수도 있다. 더 자세한 내용은 Section 16.3.3.10, “Specifying redirect and flash attributes”를 봐라.

3.1.16 향상된 URI 템플릿 변수

현재 요청의 URI 템플릿 변수를 더 다양한 곳에서 사용한다.

  • 요청을 @ModelAttribute 메서드 아규먼트에 바인딩할 때 요청 파리미터에 추가로 URI 템플릿 변수를 사용한다.
  • @PathVariable 메서드 아규먼트의 값은 렌더링하기 전에 모델에 합쳐진다. 단 JSON 직렬화나 XML 마샬랑처럼 자동화된 방법으로 생성하는 컨텐츠의 뷰는 제외다.
  • 리다이렉트 문자열은 URI 변수를 위한 플레이스홀더를 포함할 수 있다. (예를 들어 "redirect:/blog/{year}/{month}") 플레이스홀더를 확장했을 때 현재 요청의 URI 템플릿 변수를 자동으로 고려한다.
  • @ModelAttribute 메서드 아규먼트는 문자열에서 타겟 객체타임으로 변환하기 위해서 등록한 Converter나 PropertyEditor에서 제공받은 URI 템플릿 변수로 초기화 될 수 있다.
3.1.17 @RequestBody 컨트롤러 메서드 아규먼트상의 @Valid

@RequestBody 메서드 아규먼트는 @ModelAttribute 메서드 아규먼트와 유사하게 자동화된 유효성 확인은 호출하는 @Valid 어노테이션을 붙일 수 있다. MethodArgumentNotValidException가 발생하면 DefaultHandlerExceptionResolver가 처리하고 400 응답코드를 돌려준다.

3.1.18 컨트롤러 메서드 아규먼트 상의 @RequestPart 어노테이션

이 새로운 어노테이션은 "multipart/form-data" 요청의 컨텐츠에 대한 접근을 제공한다. Section 16.10.5, “Handling a file upload request from programmatic clients” 와 Section 16.10, “Spring's multipart (file upload) support”를 참고해라.

3.1.19 UriComponentsBuilder와 UriComponents

UriComponents 클래스를 새로 추가했다. UriComponents 클래스는 모든 URI 컴포넌트에 대한 접근을 제공하는 URI 컴포넌트의 불변(immutable) 컨테이너다. UriComponentsBuilder 클래스는 UriComponents 인스턴스의 생성을 돕는다. 이 두 클래스를 함께 사용하면 URI 템플릿 변수의 생성과 확장을 포함해서 URI를 준비하는 관점과 인코딩에 걸친 전 과정을 제대로 제어할 수 있다.

대부분의 경우에 새롭게 추가된 클래스들은 기존의 UriTemplate를 훨씬 유연하게 대체할 수 있다. 내부적으로 UriTemplate는 같은 클래스에 기반을 두고 있다.

ServletUriComponentsBuilder의 서브클래스는 서블릿 요청에서 정보를 복사하는 정적 팩토리 메서드를 제공한다. Section 16.7, “Building URIs”를 참고해라.


출처 - http://blog.outsider.ne.kr/732





Posted by linuxism
,


Spring Roo란?


스프링 루는 자바언어를 사용하는 텍스트 기반의 RAD(RApidy Development) 툴이다. 

루(Roo)는  Real Object Oriented 의 약자임과 동시에 캥거루를 의미하는 단어로,  스프링 루의 마스코트

또한 캥거루이다. 

 

루는 자바 이외에 어떤 다른 언어와 플랫폼을 필요로 하지 않으며, 기존의 엔터프라이즈 애플리케이션을 개발하는 방식을 사용한다.

루쉘이라는  커맨드 라인 프로그램이 실행시켜 두고 , 프로그래머는 텍스트 에디터 또는 IDE를 사용하여 개발을 수행하면, 

루쉘이 백그라운드에서 파일시스템 변경을 인지하고, 자동으로 필요한 파일들을 생성하고 관리해준다.  

루는 완전한 Round-trip(양방향) 인식을 제공하는데 이것은 프로그래머는 루에 명령없이도 어떠한 파일도 변경할 수 있고, 

루는 이러한 변경사항을 자동으로 인식하여, 필요한 파일들을 생성하는 특징을 나타낸다. 

 

루에 대한 잘못된 생각들을 알아보면....

 

 

 

루는 런타임이 아니다

루는 배포시에 프로젝트에 포함되지 않으며,  Roo관련 JAR 파일을 클래스에서 발견할 수도 없으며, Roo 어노테이션이 클래스파일에

컴파일되어 포함되지도 않는다.  이러한 특징은 언제라도 루를 프로젝트에서 제거할 수 있다는 no lock-in 특징을 의미한다. 

루를 사용하기 위한 승인이 필요치 않으며, 런타임에 프로젝트 속도를 감소시키거나, 메모리를 낭비하고,  배포구조를 망치는 어떻한

부작용도 없다. 

 

 

루는 IDE 플러그인이 아니다

루는 자신의 커맨드 쉘 윈도우 안에서 완벽하게 동작하며,  파일시스템을 모니터링하며 지능적이고 , 점진적으로  적절한 시기에

변경에 응답한다.  이것은 vi, emacs 등 어떤 에디터를 사용할 수 있게한다. 

 

 

루는 어노테이션 처리 라이브러리가 아니다

어노테이션 처리  API 는 자바 6에서 추가된 특징으로, 루는 이 API 를 사용하지 않는다. 루는 자바5 와도 동작할 수 있다. 

 

 

요약하면 루는 Inter-Type-Declaration의 능동/수동 코드생성의 조합을 수행하는 애드온 기반의 아키텍처를 사용한다.


 

 

루의 특징

  • Spring, Maven, JUnit, 등 바탕 코드 자동생성
  • Round-trip 지원
  • No Lock in, No runtime Dependency




Roo를 사용하는 이유

  • 생산성이 뛰어나다

루를 사용하면  자바 개발자들이 복잡한 엔터프라이즈 애플리케이션을 수분안에 가장 좋은 방식(Best Practice)으로 작성할 수 있다. 

자바를 수년동안 개발했던 개발자들은 자바의 생산성 문제를 인식하게 되는데, 새로운 프로젝트를 생성하고, 개발이 정상궤도에

오르기까지 수일이 걸리기 때문이다.  세계에서 가장 많이 사용되어지고 있으며, 많은 성숙한 라이브러리를 제공하고,  뛰어난 

성능과 광범위한 표준을 지원하는 매력적인 자바라는 플랫폼에, 루를 사용하여 뛰어난 생산성까지 가미할 수가 있다.  

생산성 외에도 팀으로 행동하며, 언젠간 다른 사람이 작성한 코드를 유지보수 할 수도 있기 때문에, 프로로서 아키텍처인 표준과 

관례를 따르는 것도 중요하다.  루는 최적화된, "구성보다는 관례"를 따르는 방식으로 서로 다른 배경과 경험을 갖는 개발자들간의 차이도 

극복하게 해준다. 


  • 업계 표준을 준수한다

루는 자바5를 사용하는 개발자를 대상으로 설계되었기 때문에, 대부분이 익숙한 기술들이다

루 프로젝트가 사용하는 기술들은  Spring(Spring Framework, Spring Security, Spring Web Flow), Maven, Java Server Pages,

Java Persistence API(JPA, 하이버네이트 같은..), Tiles, AspectJ을 포함한다.  엔터프라이즈 자바 프로젝트에서 가장 많이 사용되는

기술들을 포함했다. 또한 애드온 방식을 사용해 구현되었기 때문에 프로젝트에 쉽게 다른 기술을 사용할 수 있다. 

루는 이러한 기술들을 프로젝트에 매우 보수적이고, 점진적으로 추가하는 접근방법을 취한다. 루는 새로운 프로젝트를 시작할 때, 

단순한 JAR 를 빌드한다고 가정하기 때문에 어떠한 의존성도 갖지 않는다. 이후에 Persistence Provider가 필요할 때, JPA가 

설치되고, JavaBean  Validation 어노테이션을 필드에 사용할 때 해당 라이브러리가 프로젝트에 추가된다. Spring Security, 

Spring Web Flow 등 루가 지원하는 모든 기술들이 그러한 방식으로 추가된다.  이것은 엔지니어링 트레이드오프 가 없게 한다는

루의 철학과 일맥상통하는 방식이다.


  • 사용 및 배우기 쉽다.

루 개발자들은 Jef Raskin의 "The Human Interface" 라는 책에서 영감을 받아 루를 설계했다.  그는 사람들이 인터페이스에 자연스럽게 

습관화 될 수 있도록 사용하기 쉽게 만들어야 할 의무가 있다고 주장했다. 루는 이러한 사용자가 정말로 집중에할 점을 방해하지 않는 
인터페이스 설계를 모티브로 하고 있다.

루는 텍스트 기반의 인터페이스로, 학습성(배우기 쉬운) vs  풍부성 vs 정보의 명료성이라는 트레이트오프를 가지고 있다. GUI는 

위 세가지 요구사항을 모두 만족할 수 있지만, 루는 학습성과 풍부성에 좀더 초점을 맞추었다.  명료성은 루쉘이 직관적인 탭기반 

 완성시스템을 제공하여 극복했다. 명료성을 위해서, 이전에 완료된 명령에 기반하여 명령의 대상을 결정하는 "문맥인식" 과 명령축약의

특징을 추가했다. 

루의 학습성은 3가지 방식으로 이루어진다. 첫째, 업계표준의 자바 기술을 선택했고 둘째,  개입없이 루는 백그라운드에서 자동으로 동작하며, 

셋째,  현재 프로젝트 상태에 기초하여 다음에 할것을 제안해주는 hint와 같은 명령을 제공한다. 그외에도 지능적인 탭완성 및 많은 문서와

리소스를 제공한다. 


 

  • 엔지니어링 트레이오프가 없다

루 애플리케이션은 더 작은 배포크기를 갖으면, CPU 타임의 관점에서 더 빠르게 동작하고, 더 적은 메모리를 소비한다

또한 코드 어시스트, 디버깅, 프로파일링과 같은 IDE 서비스도 문제 없이 사용할 수 있도록 지원한다. 

더 작은 배포크기는 루의 점진적인 의존성 추가 접근방법을 통해 이루어진다. 작은 JAR 파일로 시작하여 실제로 필요할 때만, 

의존성을 추가한다. Roo 1.0.0 부터 루기반의 웹애플리케이션 WAR은 13Mb인데, 여기에는 스프링과 Spring JavaScript(Dojo내장),

하이버네이트, URL rewriting과 같은 더 작은 라이브러리가 포함되어 있다.  30Mb 이상의 WAR  공간을 절약하게 되고 이것은, 업로드와 

컨테이너 시작을 더 빠르게 한다. 

시작시간은,  AspectJ의 뛰어난 컴파일 타임 위빙을 통해 이루어지는데,  싱글톤 객체들의 의존성 주입과 도메인객체 advising 과 같은

진보된 요구사항을 만족할 수 있게한다. 또한 스프링 로딩시 전형적으로 생성되던 동적 프락시들이 더 이상 필요하지 않게된다. 

동적 프락시 생성 오버헤드가 없기 때문에 시작이 더 빠르며,  동적프락시 흐름 제어를 위한 CPU 타임의 낭비가 없어 루 애플리케이션은 

더 빠르게 동작한다.  프락시 객체를 사용하지 않는다는 것과 루의 런타임 컴포넌트가 없다는 것은 어떤 메모리 비용이 들지 않는다는 

장점도 있다.  점점 더 엔터프라이즈 애플리케이션들이 가상화되고, 클라우드되는 환경에서 공유하드웨어에 대한 성능의 문제는 더욱더 

큰 장점으로 작용할 것이다. 

루는 실용적이고, 유연하며, 유지보수 하기 쉬운 애플리케이션 아키텍처를 가지고 있다.  DAO 레이어를 제거하고, 어노테이션 기반의

의존성 주입을 사용하여 엔티티에 자동으로 의존성을 주입하는데, 이 아키텍처는 극적으로 작성해야할 Java 및 XML의 코드의 양을

줄이고, 개발 사이클과 리택토링 경험을 향상시킨다.

 

 

  • 쉬운 Roo 제거

요구사항의 변경, 더 좋은 대체툴의 등장, 납득할 수 없을 정도의 버그, 다른 소프트웨어의 버전을 지원하지 문제 등 

여러가지 이유로 인해 툴을 제거해야할 현실적인 가능성이 있다. 루는 런타임이 존재하지 않기 때문에 이러한 문제들은 루에서

상당수 해결된다.  루를 제거하기로 결정했다면, 단 몇분 만에 제거할 수 있다.  어떠한 코드도 작성할 필요 없으며, 큰 변경또한 
발생하지 않는다.  단순히 이클립스에서 "push in refactor"  명령을 수행하고, 정규표현식 기반의 탐색/대체기능을 사용하면 된다. 



Roo 아키텍처

아키텍처 개요

 

스프링 Roo는 자바로 작성된, 기업용 애플리케이션 개발에 초점을 두고 있다. 현재 버전에서는 전형적으로 

관계형 데이터베이스 백단, 퍼시턴스 접근을 위해 Java Persistence API, 스프링 프레임웍 의존성 주입과 트랜잭션 관리,

JUnit테스트, Maven 빌드구성, 뷰기술로 JSP를 사용하는 스프링 MVC 프론트엔드를 가지고 있다. 이런 형태는 가장 현대적인

자바기반 기업 애플리케이션 형태이다. 

하지만 루를 사용하여, 개발할 수 있는 자바 애플리케이션의 제약은 없다는 것이 중요하다. 

루 1.0.0를 사용해서도 , 어떤 종료의 애플리케이션을 개발할 수 있다. 현재 버전의 루를 사용하여 쉽게 해결할 수 있는 몇가지 요구사항

타입의 예이다. 


1 JMS큐에서 메시지를 수신받고, JMS 또는 SMTP로 응답을 전송


2 서비스 레이어를 작성하거나 (Spring의 @Service 스테레오 타입 어노테이션 사용), 

  리모팅 프로토콜을 사용하여 서비스 레이어를 rich client에 노출, 공개 (스프링의 remoting services)


3 스프링의 새로운 @Scheduled 또는 @Aync 어노테이션을 사용하여 데이터베이스에 일련에 사전정의된 액션을 실행하는 것


4 최소한의 시간투자로 최신의 스프링, AspectJ의 특징을 사용 


루와 전통적인 핸드라이팅 애플리케이션의 주요한 차이점 중 하나는 루가 불필요한 추상화 계층을 추가하지 않았다는 것이다. 

전통적인 자바 엔터프라이즈 애플리케이션은 DAO, 서비스, 도메인, 컨트롤러 계층으로 구성된다. 루 애플리케이션에서는 

entity(도메인 레이어와 유사) 와 web layer만을 사용한다. 서비스 레이어는 애플리케이션이 필요할 때 서비스 레이어를 추가할 수 있으며, 

DAO 레이어는 루애플리케이션에서는 추가되는 경우가 거의 없다. 


루 차기 버전에서는 클라우드 지원과  RIA 프레임웍에 대한 지운이 확장될 예정이다. 현재도 Cloud Foundry, Amazon Web Services,

Google App Engine 과 같은 클라우드에 배치하는 루 애플리케이션을 작성할 수 있지만, 미래에 비관계형 데이터베이스와 함께 더쉽고

편이하게 사용할 수 있는 더 많은 애드온들이 추가될 것이다. RIA 관점에서, Google Web Toolkit 프론트엔드를 작성할 수 있는 서비스도

추가될 예정이다. (GWT와 Roo 모두 엔지니어링 퍼모먼스와 first-class 자바 중심 개발방법에 초점을 두고 있음)  

Apache Maven 의 대안으로 Apache Ivy 지원에 대한 요구사항도 있다. 

 



핵심 기술 

 

AspectJ

 

AspcectJ는 정의된 포인트컷에 advice를 적용하는 AOP 로 가장 잘 알려져있지만,  루 프로젝트들은 AspectJ의 강력한 inter-type declaration(ITD) 특성을 사용한다. 이것이 루가 사용하는 마술이다. 일반 java 파일로부터 다른 컴파일 단위로 메서드와 필드들을

클래스 파일에 생성해 넣는다.  생성된 코드는 독립된 파일이기 때문에 그 파일들의 생명주기와 컨텐츠는 java 파일에 무엇을 하고

있는지와는 완전히 독립적으로 관리할 수 있다. 

 

 

ITD 가 어떻게 동작하는지 알아보자. 아래와 같이 새로운 프로젝트를 만들고 엔티티를 추가하자 

스크린샷_2010-08-31_오전_9.06.17.png

Hello.java  파일 외에도, 일련의 Hello_Roo_*.aj 파일들이 생성되었다.  *_Roo_*.aj 형태를 갖는 파일들이 Aspect ITD 

파일들이며, Roo에 의해 관리된다. 이 파일들을 직접 편집해서는 안된다. 

 

 

Hello.java 파일은 다음과 같은 단순한 형태를 갖는다.

스크린샷_2010-08-31_오전_9.26.15.png

몇몇 어노테이션들이 추가되었는데, 이런 Roo 어노테이션들은 소스수준에서 유지되며, .class 파일로 컴파일되지 않는다.

Roo 어노테이션들은 항상 @Roo*로 시작하여, 코드 어시스트 기능을 사용할 수 있다.  

 

IDT파일들 중의 Hello_ROO_ToString.aj 을 보자 

스크린샷_2010-08-31_오전_9.27.18.png

 

ITD는 자바코드와 매우 유사하다. 큰 차이점은 priviledged aspect 로 선언되어있으며, 각 멤버들은 특정한 타겟타입을 식별한다. 

Hello.toString은  Hello 타입에 toString 메서드를 추가하라는 의미이다. 

 

 

javap 명령을 사용해 생성된 클래스 파일을 확인한 결과이다.

스크린샷_2010-08-31_오전_9.40.43.png

Roo가 AspectJ ITP를 통해 java 파일에 위 그림과 같은 멤버들을 추가하였다. toString 메소드 뿐만아니라, 

스프링의 ConfigurableObject 인터페이스를 구현하고 있으며,  JPA EntityManager에 대한 접근자, 몇몇 퍼시스턴스 메소드, 

getter, setter 들이 추가가 되었다.  이런 유용한 특징들이 round-trip 방식으로  자동적으로 관리된다. 

java 파일에  toString 메소드를 정의하거나, 프로그래머가 직접 toString 메소드를 정의하면, 더 높은 우선순위를 갖게되어

자동으로 Hello_Roo_ToString.aj 파일이 삭제된다. 

 

또한 루애플리케이션은 AspectJ의 뛰어난 AOP 특징을 사용하여, 싱글턴 객체를 사용하여 의존성을 주입하고, 

메소드 호출의 일부로 트랜잭션 서비스가 사용된다. 

 

 

Spring

루의 디폴트 애플리케이션은  스프링 프레임웍만을 포함하고 있으며, Spring Security, Spring Web Flow와 같은 다른 프레임웍을 

점진적으로 추가할 수 있는  명령들을 제공하고 있다. 모든 루 애플리케이션들은 Spring Aspect를 사용하며, 스프링 프레임웍의  

Configurable 의존성 주입과 트랜잭션 어드바이스를 사용한다.  또한 디폴트로 스프링에 어노테이션 기반 컴포넌트 스캐닝과

데이베이스 커넥션 풀과 JPA 프로바이더와 같은 객체 생성 및 의존성 주입을 위해 스프링 프레임웍에 의존한다. 

 

 

Entity Layer

Roo 프로젝트에서 entity와 field는 문제 domain을 표현하는 첫번째 진입점이 된다.  entity는 데이터베이스에 저장되는 

특별한 형태의 domain object로,  일반적으로 하나의 entity는 하나의 table을 field 는 하나의 column을 표현하지만, 루쉘을

통해 쉽게 커스터마이징 할 수 있어서, 해당하는 어노테이션을 알 필요도 없다. 

 

 

@RooEntity 어노테이션이 퍼시스턴은  Entity객체를 얻어오는 정적메서드와 JPA  퍼사드 메소드글, 식별자와 버전을 위한

getter, setter를 추가하는 .aj 파일을 생성한다. (Hello_Roo_Entity.aj ). @RooEntity 어노테이션을 제거하여, JPA 를  직접 구

현 할 수도 있다. ( 식별자와 버전은 남음)
@RooJavaBean 어노테이션은 클래스 내 모든 필드에 대한 getter, setter 를 추가하는 Hello_Roo_JavaBean.aj 파일을 
생성시키며, 이 메소드를 직접구현하면 자동으로 해당하는 메소드가 ITD에서 제거된다. 

@RooToString 어노테이션은 public void toString 메소드를 추가하는데, 이 메소드는 자동생성된 web controller에서 연관된

엔티티를 보여주기 위해 사용된다. 이 메소드 내부에서는 Caleander 객체를 사용하며, 컬렉션을 포함하는 양방향 관계에서

흔히 나타나는 원형참조를 피할수 있도록 관리해준다. 

 

 

반드시 루쉘에서 엔티티 클래스를 생성할 필요는 없다. 어떤 편집기나 IDE를 사용하여  엔티티 클래스를 작성하고, 

@RooToString, @RooJavaBean 어노테이션을 사용할 수 있는데, 이러한 메소드는 저장될 필요가 없는(엔티티가 아닌)

많은 도메인 객체를 가지고 있을 때 특히 유용하다 


 

Web Layer

Roo 1.0.0은 선택적으로 자동생성된 웹 컨트롤러 레이어를 사용할 수 있도록 제공한다.  이 레이어는  요청이 REST 관례를

따르도록 보장하는 많은 URL rewriting 규칙을 포함하고 있다. 또한 Apache Tiles, Spring JavaScript 외에도 단일 명령으로

쉽게 Spring Security를 설정할 수 있게 해준다. 

이 컨트롤러들은 항상 요청을 @RooEntitiy 클래스에서 제공하는 메소드로 직접적으로 위임하는데, 호환성을 위해서 

@RooEntity 구현에 의해 제공되는 디폴트 식별자와 버전 관례를 준수하는게 좋다. 

대부분의 Roo 애플리케이션들은 비지니스 로직을 엔티티와 웹 컨트롤러 사이에 놓으며, 가끔은 서비스레이어에 놓기도 한다. 


Optional Services Layer

웹 애플리케이션은 대부분의 로직을 웹컨트롤러 핸들 메소드에, 나머지를 엔티티 메소드에 작성하기 때문에 거의 서비스 레이어를

필요로 하지않는다.  하지만 비지니스 로직을 필요로 하는 다음과 같은 경우도 있다. 

 

 

  • 로직이 특정 엔티티에만 속하지 않고 여러 엔티티로 확장되야 하는 경우
  • 웹요청의 범위를 넘어 비지니스 로직이 적용되야 하는 경우 
  • 원격 클라이언트 접근이 필요할 때 (remoting protocol을 통해 메소드들을 노출하는게 더 편리하기 때문)
  • 아키텍처 정책이 서비스 레이어를 요구할 때 
  • HTTP  관련 관리와  비지니스 로직에 대한 책임 분할을 통해, 더 높은 수준의 응집도를 필요로 할때 
  • 서비스 레이어에 보안 인증 메타데이터와 트랜잭션 경계를 놓는게 더 선호되는 경우 

 

루는 AspectJ의 ITD 기반 아키텍처를 통해 관심을 분리하기 때문에, 서비스 레이어 코드를 생성하지 않는다. 

서비스 레이어를 직접 작성하려 한다면 클래스에 스프링에 @Services 스테레오 타입 어노테이션을 사용하되, 

루 프로젝트에서 생성한 패키지 내에 클래스를 위치시켜, 스프링프레임웍 시작시 서비스 레이어를 탐지할 수 있게

해야한다.

 

 


Goodbye DAOs

대부분이 작성하는 일반적인 웹 애플리케이션에 반드시 필요하지는 않기 때문에,  서비스레이어와 함에 DAO 레이어가 제거되었다. 

DAO 레이어가 필요한 주요한 동기를 생각해조면 루 애플리케이션에서 필요하지 않는 이유를 더 잘 알수 있을 것이다. 

 

  • Testing

 

  • Separation of concern

DAO 레이어를 사용하는 이유 중 하나는 객체지향 설계에서 추구하는 높은 응집도를 구현하기 위해서이다. 

높은 응집도는 관심의 분리와 동일하다고 할 수 있다. AspectJ 의 ITD를 통해, 퍼시스턴스 메소드를 프로그래머가 아닌 Roo  

처리하도록 하여 관심의 분리를 달성하고 있다. 

 

  • Pluggable implementaions

DAO 의 다른 장점 중 하나로 하나의 퍼시스턴스 라이브러이에서 다른 것으로의 변경이 용이하다는 것이다. 

현재 애플리케이션은 API 수준의 추상화를 JPA를 통해 제공하는데, 루는 자동생성된 메서드에서 JPA 를 사용하며, 

DAO 레이어 없이도, 대체 구현을 플러그 할 수 있는 능력을 지원한다.

 

  • Non-JPA persistence

몇몇  엔티티들을 JPA Provider를 사용하지 않고, 저장하고 싶을 경우가 있을 것이다. 소규모의 클래스들만이 이러한 요구사항이 

필요하다면, 나머지 대다수의 엔티티들을 Roo를 사용하여 관리할 수 있다. 대규모의 클래스들이 이러한 요구사항을 필요로 

한다면 사용자가 직접 (Roo가 JPA Provider에 대해 했던 것처럼) 자동으로 ITD들을 관리해주는  루 애드온을 작성할 수 있다. 

 

 

  • Security authorisation



Roo 설치하기

 

0 시스템 요구사항

Linux, Apple, Windows-based opeating system

Sun, JRocket, IBM Java5, 6 installation => $JAVA_HOME  환경변수가 JDK 홈을 가리키도록 설정

Apache Maven 2.0.9 이상버전 설치  =>  PATH 환경변수에 추가 



1 다운로드 사이트에서 루 애플리케이션 다운받기

SpringSource Tool Suit (Roo 사용을 쉽게하는 이클리스 기반의  IDE)다운로드

http://www.springsource.com/products/springsource-tool-suite-download

STS를 설치하면, roo쉘과 STS IDE와 톰캣서버가 설치된다. 

 

2  Roo쉘 설치된 경로를 ROO_HOME 환경변수로 설정한다.

 

3 roo 쉘명령 링크 생성 

   윈도우이면, $ROO_HOME \bin 을 PATH 환경변수에 추가

   리눅스라 애플이라면, 다음과 같이 심볼릭 링크를 생성한다. 

   sudo ln -s $ROO_HOME/bin/roo.sh /usr/bin/roo

 

 4 Roo가 설치됐는지 확인한다. 

mkdir roo-test

cd roo-test

roo quit

cd..

rmdir roo-test

 


출처 - http://hiddenviewer.springnote.com/pages/6325139









Posted by linuxism
,


Method chaining - Wikipidea : http://en.wikipedia.org/wiki/Method_chaining

자바 7에 추가될뻔한 기능이었다고 한다. ^^; 자바의 빈클래스에 막 길들어지기 시작한 내게는 조금 낯선 형태랄까?
setter 메소드에서 클래스(this)를 리턴해주는 형태니까...

Chaining.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class DateChaining {
 
    private String year;
    private String month;
    private String day;
     
    public String getMonth() {
        return month;
    }
 
    public DateChaining setMonth(String month) {
        this.month = month;
        return this;
    }
 
    public String getDay() {
        return day;
    }
 
    public DateChaining setDay(String day) {
        this.day = day;
        return this;
    }
 
    public String getYear() {
        return year;
    }
 
    public DateChaining setYear(String year) {
        this.year = year;
        return this;
    }
 
    @Override
    public String toString() {
        return "DateChaining [year=" + year + ", month=" + month + ", day="
                + day + "]";
    }
 
}

ChainingTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package test;
 
import main.DateChaining;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
 
import org.junit.Test;
 
public class ChainingTest {
     
    @Test
    public void 체이닝_테스트() {
        //given
        DateChaining chain = new DateChaining();
        //when
        chain.setYear("2011").setMonth("07").setDay("17");
        //then
        assertThat(chain.getYear(), is("2011"));
        assertThat(chain.getMonth(), is("07"));
        assertThat(chain.getDay(), is("17"));
    }
     
    @Test
    public void 순서흐트러진_체이닝_테스트() {
        //given
        DateChaining chain = new DateChaining();
        //when
        chain.setMonth("07").setDay("17").setYear("2011");
        //then
        assertThat(chain.getYear(), is("2011"));
        assertThat(chain.getMonth(), is("07"));
        assertThat(chain.getDay(), is("17"));
    }
     
    @Test
    public void 중복된_필드에대한_세트선언시() {
      //given
        DateChaining chain = new DateChaining();
        //when
        //
        chain.setYear("2011").setMonth("07").setDay("17").setYear("2012");
        //then
        assertNotSame(chain.getYear(), is("2011"));
        assertThat(chain.getMonth(), is("07"));
        assertThat(chain.getDay(), is("17"));
    }
}
이렇게 쓰는 것에 낯설기는 하지만... 익숙하게 사용했을때 어떤 장점이 있는지 확인해보고 익혀두는 것도 나쁘지 않겠다.


출처 - http://java.ihoney.pe.kr/175




'Development > Java' 카테고리의 다른 글

java - xml 읽고 쓰기  (1) 2012.10.22
java - java 7 새로운 기능 및 특징  (2) 2012.10.20
java - Timer 및 TimerTask Class  (0) 2012.10.06
java - 가비지 컬렉션(Garbage Collection)  (0) 2012.10.05
jdom - xmlns, xsi 설정  (0) 2012.10.04
Posted by linuxism
,