Whiteship's Note

'2009/04'에 해당되는 글 28건

  1. 2009.04.30 스프링 Roo petclic 예제 실행 성공 (2)
  2. 2009.04.30 Roo 설치하기
  3. 2009.04.30 스프링 Roo 프로젝트 이름 투표하기
  4. 2009.04.30 Spring Roo가 나왔습니다.
  5. 2009.04.29 동원훈련 2박3일 끌려가기 싫으시면 동원훈련이 끝난 동네로 이사를 가세요~ (19)
  6. 2009.04.29 이클립스 WTP server.xml 설정이 적용되지 않을 때 (2)
  7. 2009.04.28 Prototype VS JQuery 트랜드 비교 (2)
  8. 2009.04.28 재밌는 상상~ 누드 비치에 사무실 차리기 (6)
  9. 2009.04.27 문자열 연결 성능 비교 (4)
  10. 2009.04.27 기트(Git)와 SVN으로 동시에 버전 관리하기 (4)
  11. 2009.04.25 Github 맘에 드네~
  12. 2009.04.24 토비님의 S3Matrix 소스 보기 1. pom.xml (2)
  13. 2009.04.21 090419 경마 공원 나들이 (4)
  14. 2009.04.21 Spring Expression Language(SpEL) (2)
  15. 2009.04.20 또치야~~ 사진 찍을까? 사진?! (4)
  16. 2009.04.20 What's new in Spring 3.0? (2)
  17. 2009.04.20 캬~ 나도 이제 DSLR 유저 (6)
  18. 2009.04.17 못살겠다 대한민국 (7)
  19. 2009.04.17 초간단 CURD, 검색, 페이징, 정렬 구현 완료 (2)
  20. 2009.04.17 외국 IT 기업에서 원하는 걸 보자꾸나~ (5)
  21. 2009.04.16 '개발' 역시 참 맛있다. (2)
  22. 2009.04.14 Github에 pull, push하기 (2)
  23. 2009.04.13 2009년 벗꽃놀이 다녀옴 (6)
  24. 2009.04.13 OpenSprout Nexus 이용하여 스프링 3.0 라이브러리 추가하기 (2)
  25. 2009.04.09 기트(git) config
  26. 2009.04.07 기트(git) 주요 명령어 (2)
  27. 2009.04.03 오랜만에 보는 미드 - lie to me (4)
  28. 2009.04.03 우와~ 스프링 tc 서버다!! (6)

스프링 Roo petclic 예제 실행 성공

Spring Roo/etc : 2009.04.30 19:47




1. 프로젝트 디렉토리 만들기

# mkdir petclinic

2. 디렉토리로 이동하기

# cd petclinic

3. 루 실행

# roo

4. 스크립트 실행

roo> script clinic.roo
roo> exit

5. 이클립스 프로젝트로 변환

mvn eclipse:eclipse

6. 이클립스 프로젝트로 임폴트

7. 콘솔에서 테스트

mvn test

8. Run As -> Run on server

간단하네요.. 소스 코드를 봤더니, 애노테이션과 AspectJ의 향연입니다. 자바 소스 코드는 거의 없다시피 합니다. 하이버네이트를 사용했습니다. 도메인이 CRUD를 담당하는지(물론 어딘가로 위임하겠죠.), 도메인과 컨트롤러 밖에 보이지 않습니다. 도메인이 역할을 위임하는 녀석들이 보이지 않습니다.

@Entity
@RooJavaBean
@RooToString
@RooEntity(finders = { "findVisitsByDescriptionAndVisitDate", "findVisitsByVisitDateBetween", "findVisitsByDescriptionLike" })
public class Visit {

    @Size(max = 255)
    private String description;

    @NotNull
   @Past
    @Temporal(TemporalType.TIMESTAMP)
    private Date visitDate;

    @NotNull
    @ManyToOne
   @JoinColumn
    private Pet pet;

    @ManyToOne
   @JoinColumn
    private Vet vet;
}

하늘색은 JPA 애노테이션(하지만 실제로 사용하는 라이브러리는 하이버네이트, 왜냐면 JPA가 표준이까) 녹색은 Roo 애노테이션, 남색은 javax.validation 애노테이션입니다. @Past는 항상 입력되는 Date가 입력되는 시점 기준으로 이전 날짜여야 한다네요. 오호..

Roo를 학습하려면 Roo가 제공하는 애노테이션과 그 기능을 파악하는게 주요해 보입니다. 그리고 Roo가 가정하고 있는 CoC도 익혀야겠죠. 좀 더 자세히 보려면 Roo가 제공하는 Aspect들을 조사해봐야겠습니다.

AspectJ 파일들을 보려면 이클립스에서 네비게이터로 보면 됩니다. 아니면 Filters 옵션에서 Hide generated ROO ITDs의 체크를 없애면 패키지 익스플로러에서도 볼 수 있습니다.



흠.. 기발한 것 같습니다. AspectJ를 자동생성해서 자바로 만든 클래스에 @Configurable을 붙이고 테스트까지 자동생성합니다. @_@ 와.. 정말이지 이건 애노테이션과 AspectJ의 향연입니다.
신고

'Spring Roo > etc' 카테고리의 다른 글

스프링 Roo 1.0.0.RC1 배포~  (0) 2009.07.22
Getting Started with Spring Roo  (0) 2009.05.28
스프링 Roo petclic 예제 실행 성공  (2) 2009.04.30
Roo 설치하기  (0) 2009.04.30
스프링 Roo 프로젝트 이름 투표하기  (0) 2009.04.30
Spring Roo가 나왔습니다.  (0) 2009.04.30
top


Roo 설치하기

Spring Roo/etc : 2009.04.30 15:56




1. 메이븐 버전확인

mvn -v

2.0.9 이상이어야 함.

2. 자바 버전 확인

java -version

자바 5 이상이어야 함.

3. roo 압축파일 풀기

4. ROO_HOME을 환경 변수에 추가하기

5. ROO_HOME/bin을 PATH에 추가하기

6. STS 2.0.1 준비하기

7. ROO 이클립스 플러그인을 STS/dropins 디렉터리에 추가하기

다음 STS 배포 부터는 이 플러긴도 포함되서 배포할 예정.

8. 메이븐 로컬 저장소에 Roo 추가하기

리눅스/맥: mvn install:install-file -DgroupId=org.springframework.roo -DartifactId=roo-annotations -Dversion=1.0.0.A1 -Dpackaging=jar -Dfile=$ROO_HOME/dist/roo-annotations-1.0.0.A1.jar

윈도: mvn install:install-file -DgroupId=org.springframework.roo -DartifactId=roo-annotations -Dversion=1.0.0.A1 -Dpackaging=jar -Dfile=%ROO_HOME%/dist/roo-annotations-1.0.0.A1.jar

9. 콘솔에서 roo 입력해보기

10. hint 입력해보기

11. q 입력해서 종료하기
신고

'Spring Roo > etc' 카테고리의 다른 글

스프링 Roo 1.0.0.RC1 배포~  (0) 2009.07.22
Getting Started with Spring Roo  (0) 2009.05.28
스프링 Roo petclic 예제 실행 성공  (2) 2009.04.30
Roo 설치하기  (0) 2009.04.30
스프링 Roo 프로젝트 이름 투표하기  (0) 2009.04.30
Spring Roo가 나왔습니다.  (0) 2009.04.30
top


스프링 Roo 프로젝트 이름 투표하기

Spring Roo/etc : 2009.04.30 14:59


Roo 라는 이름은 프로젝트 내부에서 사용한 이름인데, 공식 이름은 아직 안 정한 듯 합니다. 그냥 Roo라고 해도 괜찮을 것 같은데 요즘 투표 중인가 봅니다.

http://cloud.springsource.com/vote

심심하신 분들은 이 곳으로 가셔서 투표해보세요.

선택지에는 요런게 있습니다.

Spring HyperDrive
Spring Roo
Spring Boost
Spring Spark
Spring Dart

재미있는 건 저 링크에 들어갈 때마다 선택지의 순서가 달라진다는 겁니다. 공정성을 위해 그렇게 만들어 둔 것 같은데.. 참 센스가 돋보입니다.
신고

'Spring Roo > etc' 카테고리의 다른 글

스프링 Roo 1.0.0.RC1 배포~  (0) 2009.07.22
Getting Started with Spring Roo  (0) 2009.05.28
스프링 Roo petclic 예제 실행 성공  (2) 2009.04.30
Roo 설치하기  (0) 2009.04.30
스프링 Roo 프로젝트 이름 투표하기  (0) 2009.04.30
Spring Roo가 나왔습니다.  (0) 2009.04.30
top


Spring Roo가 나왔습니다.

Spring Roo/etc : 2009.04.30 14:24


http://www.springsource.org/roo

알고 계신분들은 예전부터 알고 계시고 그 소스 코드를 궁금해 하셨을 겁니다. 전 이 녀석의 소스 코드보다 이걸 사용해서 만든 애플리케이션 구조와 코드가 더 궁금했는데, 알파 버전 이기는 해도 일단 예제와 함께 공개가 되서 신나네요. 생각보다 빨리나와서 놀랐습니다.ㅎㅎ

Roo는 무엇인가?

새로운 언어나 문법을 익히지 않고 자바 애플리케이션을 엄청 빠르게 만들 수 있게 해주는 프레임워크입니다. 3분 안에 100타 미만으로 애플리케이션을 만들 수 있게 도와준다고 합니다. 탭 자동완성과 힌트를 제공하며 컨텍스트를 인지하는 커맨드 라입 쉘을 제공합니다. 이 쉘을 띄운 다음에 애플리케이션 베이스를 만드는 것 같습니다. 마치 Grails나 RoR 처럼요. 생산성에 초점을 둔 프레임워크로 보면 될 것 같습니다. 그러면서도 성능 문제도 없고, 유연성을 잃지도 않고, 비침략적인 코드를 유지하는... 엄친아 격인 프레임워크라고 해야 되나..

재밌겠네요. 어디 잘 돌아가나 한 번 예제라도 돌려봐야겠습니다~
신고

'Spring Roo > etc' 카테고리의 다른 글

스프링 Roo 1.0.0.RC1 배포~  (0) 2009.07.22
Getting Started with Spring Roo  (0) 2009.05.28
스프링 Roo petclic 예제 실행 성공  (2) 2009.04.30
Roo 설치하기  (0) 2009.04.30
스프링 Roo 프로젝트 이름 투표하기  (0) 2009.04.30
Spring Roo가 나왔습니다.  (0) 2009.04.30
top


동원훈련 2박3일 끌려가기 싫으시면 동원훈련이 끝난 동네로 이사를 가세요~



요즘 동원훈련 기간이죠? 학교에서 두 번 다녀올땐 학생이라고 당일치기 시켜주더니, 작년 부터 직장인이라고 2박3일이나 데려가더라구요. 정말 정말 지겨워 죽는 줄 알았습니다. ㅠ.ㅠ Kill zone 같은 미드를 보여주던지, Call of Duty 같은 게임을 시켜주라구요.

어쨋든, 그래서 저는 올해가 4년차니까 2박 3일 동원 훈련을 가야하는데, 제가 얼마전에 전입신고를 해서 색시랑 살고 있는 곳으로 주소지를 이전했습니다. 그랬더니 글쎄 이동네 동원 훈련이 끝났다고 6시간 교육만 받으러 오라는 통지서가 왔어요. 크하핫


결론은 2박 3일에서 6시간 교육으로 줄었다는거~ 나이수!!! 설마 6시간 동안 빡쎄게 굴리려는 건 아니겠죠?ㅋㅋ
신고
top


이클립스 WTP server.xml 설정이 적용되지 않을 때

모하니?/Coding : 2009.04.29 13:22


<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" />

server.xml에 이런 설정이 들어있는데 이것을 인코딩 문제로

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>

이렇게 변경했습니다. 그런데 변경한 설정이 먹질 않더군요.

server를 우클릭하고 cleanup도 해봤습니다. 적용되지 않았습니다.

그래서 server를 더블클릭하고 HTTP/1,1 포트를 변경한 다음에 서버를 재가동 해봤더니 설정이 적용되서 원하는 결과를 얻을 수 있었습니다.

다시 포트를 원래대로 돌린다음에 실행해 봤더니 이번에도 적용이 됐습니다.

server.xml을 직접 편집할 경우 설정이 제대로 안 먹을 수 있으니, server를 더블클릭해서 어떤 설정을 변경한 다음 저장하고 다시 시도해보시기 바랍니다. 저처럼 될지도 몰라요~


신고
top


Prototype VS JQuery 트랜드 비교

Good Tools : 2009.04.28 16:47


둘의 동향을 비교해보기 위해 구글 트랜드 검색을 했습니다. JQuery가 러시아에서 왜케 인기가 좋은지 궁금하네요? 러시아 사람이 만들었나요? 인도와 타이완 중국에서도 인기가 좋네요.


구글 트랜드 말고도 트랜드를 비교 검색해주는 사이트가 있었던 것 같은데 기억이 안나네요. @_@
원랜 그걸 찾으려고 구글에서 trend를 검색했는데 구글 트랜드가 보이길래 이걸 써봤습니다.ㅋㅋ 암튼 구글 대단해요~
신고
top


재밌는 상상~ 누드 비치에 사무실 차리기

모하니?/Thinking : 2009.04.28 10:38


성윤이랑 아침에 잡담을 하다가 이야기가 이상한데로 샜습니다. 처음엔 프로 스프링 2.5 출간 기념 및 봄싹 감수 회식 자리에 대해 대화를 하다가 스프링 팀 블로그 번역 얘길 하며 영어의 중요성을 서로 각인 시키다가 결국 누드 비치에 사무실을 차리자는 얘기까지 나왔죠.

결론은 그렇습니다. 누드 비치에 사무실을 차리기 위해 열심히 영어 공부를 하자.

얼마나 행복할까요. 열심히 코딩하다가 눈이 피곤해서 창밖을 내다보면 급속 충전으로 눈이 맑아 집니다. 오랜시간 의자에 파묻힌 척추와 모니터로 빨려들어가는 거북목을 풀어주기 위해 기지게를 피며 밖으로 나가면 환한 햇살과 시원한 바람, 에메랄드 빛 바닷가가 절 끌어 당깁니다. 그러면 전 발가벗고 물속에 뛰어 들어 수영을 하다 오는거죠~

아~ 상상만 해도... 참 즐겁네요.


신고

'모하니? > Thinking' 카테고리의 다른 글

쓰리좝 시작인가...  (6) 2009.08.31
약속의 힘  (2) 2009.07.23
벌써 한 달이 넘었군요.  (12) 2009.07.07
스프링소스의 끼워주기(?) 패키지  (2) 2009.06.17
이제 다시 복귀 할 시간  (8) 2009.06.07
재밌는 상상~ 누드 비치에 사무실 차리기  (6) 2009.04.28
외국 IT 기업에서 원하는 걸 보자꾸나~  (5) 2009.04.17
'개발' 역시 참 맛있다.  (2) 2009.04.16
저 결혼해요~~  (92) 2009.03.02
난 몇 살?  (0) 2009.01.28
새로운 인연  (28) 2009.01.19
top


문자열 연결 성능 비교

모하니?/Coding : 2009.04.27 18:06


예전에도 한 번 해본 것 같은데 잘 기억이 안나서 다시 해봤습니다.

package perfomance;

import org.junit.Before;
import org.junit.Test;
import org.springframework.util.StopWatch;

public class StringAppendTest {

    StopWatch stopWatch;

    @Before
    public void setUp(){
        stopWatch = new StopWatch();
        stopWatch.start();
    }

    @Test
    public void appendByPlus() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByPlusExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Plus: " + stopWatch.getLastTaskTimeMillis());
    }

    @Test
    public void appendByContinuousPlus() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByContinuousPlusExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Continuous Plus: " + stopWatch.getLastTaskTimeMillis());
    }

    @Test
    public void appendByBuilder() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByBuilderExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Builder: " + stopWatch.getLastTaskTimeMillis());
    }

    @Test
    public void appendByBuffer() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByBufferExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Buffer: " + stopWatch.getLastTaskTimeMillis());
    }

    private void runAppendByContinuousPlusExample() {
        String result = "a";
        result += "bc" + "de";
    }

    private void runAppendByBufferExample() {
        StringBuffer buffer = new StringBuffer("a");
        buffer.append("bc");
        buffer.append("de");

    }

    private void runAppendByBuilderExample() {
        StringBuilder builder = new StringBuilder("a");
        builder.append("bc");
        builder.append("de");
    }

    private void runAppendByPlusExample() {
        String result = "a";
        result += "bc";
        result += "de";
    }


}

결과는 연속 + 연산과 Builder를 사용한 것이 제일 빠릅니다. 연속해서 +를 사용하면 JVM이 내부적으로 StringBuilder를 사용해서 연결해준다고 합니다. 이 테스트 결과를 확인해도 비슷하다는 것을 알 수 있습니다. 결과는 매번 다르지만, 평균적으로 다음과 같이 나옵니다.

위에서 사용한 StopWathch는 스프링 라이브러리에 들어있습니다.
3.0 기준으로 core 번들에 들어있습니다.

by Plus: 46
by Continuous Plus: 16
by Builder: 16
by Buffer: 31

신고
top


기트(Git)와 SVN으로 동시에 버전 관리하기

Good Tools : 2009.04.27 14:14


기트에서는 SVN 정보를 버전관리에서 제외하고 SVN에서는 기트 정보를 버전관리에서 제외해줘야 합니다. 그래야 깔끔하겠죠. 기트로 버전 관리는 하는데 괜히 모든 폴더마다 .svn 폴더가 생기고 그 안에 또 여러 폴더와 파일들까지 딸려 온다면... 쫌~ 그르치요~!

기트에서 SVN 정보를 버전관리 대상에서 제외하는 방법은 간단합니다. 프로젝트 루트에 .gitignore 파일을 만들고 그 안에 .svn 과 .svn/* 을 추가해주시면 됩니다. 두 번째 것 만 등록해도 될런지 모르겠습니다.


반대로 SVN에서는 프로젝트 루트에 있는 .git 폴더와 .gitignore 파일만 ignore 시켜주면 됩니다. 이렇게 하면 이제부터 이클립스에서는 subversive 플러긴을 이용해서 SVN에 커밋&업데이트를 할 수 있고, 콘솔로는 기트를 이용하여 로컬에 commit을 하고 원격에 push, pull 하면서 두 개의 버전관리 시스템을 사용할 수 있겠습니다.

둘 중 하나는 뷰 전용으로 하고, 다른 것 하나를 주요 버전 관리 시스템으로 사용하면 좋을 것 같습니다. 예를 들어, SVN을 뷰 전용으로 사용하고 기트를 사용하여 실제 개발을 하면서 중간 중간 push할 때 마다 SVN에 같이 커밋해주는 식으로 사용하면 될 것 같습니다.
신고

'Good Tools' 카테고리의 다른 글

오늘 하루 타일즈(Tiles)에 낚였나보다~  (2) 2009.05.01
스프링 MVC에서 타일즈 2 사용하기  (2) 2009.05.01
Tiles와 SiteMesh 차이  (0) 2009.05.01
Tiles VS SiteMesh  (2) 2009.05.01
Prototype VS JQuery 트랜드 비교  (2) 2009.04.28
기트(Git)와 SVN으로 동시에 버전 관리하기  (4) 2009.04.27
Github 맘에 드네~  (0) 2009.04.25
Github에 pull, push하기  (2) 2009.04.14
기트(git) config  (0) 2009.04.09
기트(git) 주요 명령어  (2) 2009.04.07
기트(Git) 주요 개념  (8) 2009.03.30
top


Github 맘에 드네~

Good Tools : 2009.04.25 10:44



보시다시피 그래프로 브랜치 흐름을 보여줍니다. 와우.. 멋지지 않나요. 여기서 그치지 않고 점들을 클릭하면 해당 빌드에 대한 상세 정보 페이지로 이동합니다.

게다가 소스 코드 다운로드와 위키, 이슈트래커까지 제공해주죠. @_@

좋치 않나요. 속도도 SVN 호스팅 사이트와는 비교할 수 없이 빠르더군요. 기트를 사용해보실 분들에게 강추합니다~
신고

'Good Tools' 카테고리의 다른 글

스프링 MVC에서 타일즈 2 사용하기  (2) 2009.05.01
Tiles와 SiteMesh 차이  (0) 2009.05.01
Tiles VS SiteMesh  (2) 2009.05.01
Prototype VS JQuery 트랜드 비교  (2) 2009.04.28
기트(Git)와 SVN으로 동시에 버전 관리하기  (4) 2009.04.27
Github 맘에 드네~  (0) 2009.04.25
Github에 pull, push하기  (2) 2009.04.14
기트(git) config  (0) 2009.04.09
기트(git) 주요 명령어  (2) 2009.04.07
기트(Git) 주요 개념  (8) 2009.03.30
JGit 설치  (0) 2009.03.26
top

TAG GitHub, 기트

토비님의 S3Matrix 소스 보기 1. pom.xml

모하니?/Coding : 2009.04.24 10:55


하루(실제로는 몇 시간 만에 작성했으로 예상되지만)만에 TDD로 개발한 프로젝트 소스를 볼 수 있다니 정말 즐겁습니다.

이 프로젝트는 취지부터가 멋집니다. 사부님이 자신이 하던 일이 반복적이여서 그걸 프로그래밍으로 간편화한 것이 바로 이 프로젝트 입니다. pom.xml 파일을 뒤져가며 엑셀로 그 의존성들을 정리하던 것을 자동화 한 거죠. 멋집니다. +_+ 그러면서도 다른 사람들에게 유용한 정보를 줄 수 있으니... 그저 멋지다는 표현밖엔 안 떠오르네요. 역시 사부님이라고 부를만 합니다.

생각난김에 이쯤에서 왜 자꾸 토비님을 사부님이라고 하는지 언급해야겠네요. 토비님은 제가 '토비님'이라고 부르는걸 달갑지 않게 생각하십니다. 채팅에서도 몇 번이나 지적을 받았고, 실제 업무 중에도 오프라인에서 '토비님'이라고 불렀다가 '이건 아니다.' 싶었습니다. 그래서 회사에서 직책 명칭인 '이사님'이라고 불렀지만 업무 중이 아닐 때에도 자꾸 '이사님'이라고 부르기는 뭐해서 마땅한 표현이 없을까 고민하던 중 떠오른 단어가 '사부님'입니다. 원래는 형이라고 부르라고 했었는데, '형'이라고 하기엔 나이차도 좀 있으시고 '형'같지 않은 포스가 느껴져서 '형님'이라고 하니까 무슨 안 그래도 덩치도 좀 있으신데 '형님' '형님'하면 안 좋은 이미지가 떠오르자나요. 그래서 이것 저것 많이 알려주시기도 하고, 업무 할 때 사수 역할도 해주시니까 '사부님'이라고 부르기로 했습니다.

사설이 엄청 길었는데요. 각설하고, 본론으로 들어가겠습니다. 일단 사부님 코드를 받으시면 에러가 납니다. 의존성 에러죠. 해결하기가 힘들겁니다. 왜냐면, 상위 pom을 사용했는데 그 상위 pom이 여러분 로컬에 있을리 만무하자나요.ㅋㅋ 하지만 그렇다고 해서 pom.xml에 상위 pom이 배포되어 있는 저장소 정보가 있는 것도 아닙니다. 결국 빨간 불이 들어온 소스 코드를 보시면서 테스트도 돌려보지 못하고 눈팅만 해야 할지도 모릅니다.

캬캬캬. 그래서 제가 pom.xml을 조금 수정했습니다. 이걸 쓰시면 테스트를 돌려보실 수 있을 겁니다.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.opensprout</groupId>
    <artifactId>s3matrix</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <dependencies>
        <!-- opensprout's spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.web.servlet</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.aspects</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.orm</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.test</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>
        <!-- excel -->
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>com.springsource.jxl</artifactId>
            <version>2.6.6</version>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-library</artifactId>
            <version>1.1</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>spring-latest</id>
            <name>Spring Latest by OpenSprout</name>
            <url>http://www.opensprout.org/nexus/content/repositories/spring-latest</url>
        </repository>
        <repository>
            <id>com.springsource.repository.bundles.external</id>
            <name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
            <url>http://repository.springsource.com/maven/bundles/external</url>
        </repository>
        <repository>
            <id>opensprout nexus</id>
            <name>OpenSprout Nexus public</name>
            <url>http://www.opensprout.org/nexus/content/groups/public</url>
        </repository>
    </repositories>
</project>


신고
top


090419 경마 공원 나들이





사람도 많고 복잡해 보여서 경마는 안 해보고 주변만 둘러보고 왔습니다. 가족끼리 나들이 오신 분들이 정말 많더라구요. 위 사진들은 색시가 찍어준 사진 들 중 일부입니다. 돈을 잃었을 때와 땄을 때 기분을 표현해 봤습니다. 그 뒤 두 개는 도박을 하지 않는 사람이 그냥 쉬는 모습입니다. 안 하는게 맘편하고 좋쵸.

가장 맘에 드는 사진은 요거..


캬~~ 뒤에 바위만 진짜 바위였으면 달력같은데 말이죠.ㅋㅋ



신고

'모하니? > TakingAPicture' 카테고리의 다른 글

090419 경마 공원 나들이  (4) 2009.04.21
또치야~~ 사진 찍을까? 사진?!  (4) 2009.04.20
top


Spring Expression Language(SpEL)

Spring/3.0 : 2009.04.21 17:12


참조: 7. Spring Expression Language (SpEL)

번역, 요약 및 편역 합니다.

7.1 도입

스프링 EL(SpEL)은 실행시(runtime)에 객체 그래프 질의와 조작을 지원하는 강력한 EL(Expression Language)이다. 통합 EL(Unified EL)과 언어 문법이 비슷하지만, 메서드 호출과 기본 문자열 템플릿 같은 추가 기능을 제공한다.

OGNL, MAVEL, JBoss EL 같은 다른 자바 EL도 있지만, 스프링 EL은 스프링 커뮤니티에 모든 스프링 포트폴리오 제품에서 사용할 수 있는 단일 EL을 제공하기 위해 만들었다. 이 언어의 기능은 스프링 포트폴리오의 요구사항을 기반으로 도출했다. 그 중에는 이클립스 기반의 스프링소스 툴 스위트(STS)에서 코드 완성에 필요한 도구도 포함되어 있다.

SpEL이 스프링 포트폴리오에 표현 평가(evaluation) 기반을 제공하기는 하지만, 그렇다고 해서 스프링에 강력하게 묶여있지는 않다. 독립적으로 사용할 수 있다. 독립적으로 사용하는 예제가 이 번 장에 많이 나와있다. 그러려면 약간의 부트스트랩 역할을 하는 (파서 같은)기반 클래스들을 만들어야 한다. 스프링 사용자들은 그런 기반 시설을 사용할 필요가 없고 그저 표현식을 사용하면 된다. 일반적인 SpEL 사용법은 XML 또는 애노테이션 기반 빈 설정에 사용하는 것인데 빈 정의할 때 EL 사용하기 절에서 살펴볼 수 있다.

이번 장은 EL 기능과 API와 그리고 문법을 살펴본다. 

7.2. 기능 개요

EL은 다음의 기능을 제공한다.

      Literal expressions: 상수 표현
      Boolean and relational operators: 불린과 관계형 연산자
      Regular expressions: 정규 표현식
      Class expressions: 클래스 표현식
      Accessing properties, arrays, lists, maps: 속성, 배열, 리스트, 맵에 접근하기
      Method invocation: 메서드 호출
      Relational operators: 관계형 연산자
      Assignment: 대입
      Calling constructors: 생성자 호출
      Ternary operator: 3항 연산자
      Variables: 변수
      User defined functions: 사용자 정의 함수
      Collection projection: 콜렉션 보기
      Collection selection: 콜렉션 선택
      Templated expressions: 템플릿 표현식

7.3. 스프링의 Expression 인터페이스를 사용한 표현식 평가

이번 절에서는 간단한 SpEL 인터페이스와 그 EL 사용법을 살펴보겠다. EL 레퍼런스에서 자세한 내용을 참조하라.

다음 코드는 SpEL API를 사용하여 상수 문자열 표현식 'Hello World' 값을 구한다.

ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("'Hello World'");
String message = (String) exp.getValue();

message 변수의 값은 'Hello World'다.

여러분이 주로 사용할 SpEL 클래스와 인터페이스는 org.springframework.expression 패키지와 그 하위 패키지 spel.antlr과 spel.support에 있다.

EL은 ANTLR 문법을 사용하며 lexer와 파서(parser)를 구성할 때 사용한다. ExpressionParser 인터페이스는 표현식 파싱을 책임진다. 이 예제에서 표현식은 홑따옴표로 둘러쌓여있는  문자열 상수다. Expression 인터페이스는 앞에서 정의한 표현식 값을 도출하는 책임을 지니고 있다. parser.parseExpression을 호출할 때는 ParseException이 발생할 수 있고 exp.getValue를 호출할 때는 EvaluationException이 발생할 수 있다.

SpEL은 메서드 호출, 속성 접근, 생성자 호출 같은 다양한 기능을 제공한다.

다음 예제는 메서드 호출의 예로, concat 메서드를 호출한다.

ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.concat('!')");
String message = (String) exp.getValue();

SpEL은 . 기호를 사용하여 속성의 속성에도 접근할 수 있다. 예를 들어 prop1.prop2.prop3에 접근할 수 있고 값을 설정할 수 있다.

ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.bytes.length");  // invokes 'getBytes().length'
int length = (Integer) exp.getValue();

문자열의 생성자도 호출할 수 있다.

ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("new String('hello world').toUpperCase()");
String message = exp.getValue(String.class);

여기서 public <T> T getValue(Class<T> desiredResultType) 이 메서드를 주목해서 살펴보자. 이 메서드를 사용하면 결과 값을 캐스팅하지 않아도 된다. 값이 T 타입 또는 등록된 타입 컨버터로 캐스팅이 되지 않을 때는
EvaluationException가 발생한다.

좀 도 흔한 SpEL 사용처는 특정 객체 인스턴스에 대한 표현식일 것이다. 다음 예제는 Inventor 클래스의 인스턴스에서 Name 속성을 가져온다.

// Create and set a calendar
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);

//  The constructor arguments are name, birthday, and nationaltiy.
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");

ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("name");

EvaluationContext context = new StandardEvaluationContext();
context.setRootObject(tesla);

String name = (String) exp.getValue(context);

마지막 줄에서 'name' 변수는 "Nikola Tesla"가 설정된다. StandardEvaluationContext 클래스에 "Name" 속성을 찾아볼 객체를 알려준다. 같은 표현식을 새로운 루트 객체로 설정해가며 여러 번 재사용할 수 있다. Expression은 리플렉션을 사용한다.

노트

SpEL을 독립적으로 사용할 때는 파서와 Evaluation context를 만들어야 한다. 하지만 설정 파일의 일부로 SpEL을 사용할 때는 파서와 Evaluation context, root 객체 등을 암묵적으로 스프링이 설정해 준다.

마지막으로 간략히 살펴볼 예제는 불린 연산자를 사용하는 것이다.

Expression exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(context, Boolean.class);  // evaluates to true

7.3.1 EvaluationContext 인터페이스

EvaluationContext 인터페이스는 사용하여 속성, 메서드, 필드를 찾을 수 있고 타입 변환을 수행하는데 이용할 수 있다. 구현하여 제공하는 클래스로 StandardEvaluationContext가 있는데, 객체를 다룰 때 리플렉션을 사용하고, 최적화를 위해 Method, Field, Constructor 인스턴스를 캐싱한다.

StandardEvaluationContext의 setRootObject 메서드를 사용해서 식을 적용할 루트 객체를 명시한다. 또한 setVariable과 registerFunction을 사용하여 표현식에서 사용할 변수와 함수를 명시할 수 있다. 변수와 함수 사용법은 EL 레퍼런스의 변수와 함수 절을 참조하라. StandardEvaluationContext는 또한 커스텀 ConstructorResolver, MethodResolver, PropertyAccessor등을 등록하여 SpEL이 표현식을 다루는 방법을 확장할 수 있다. 자세한 내용은 이들 클래스의 JavaDoc을 참조하라.

7.3.1.1 타입 변환

SpEL은 기본으로 스프링 코어에서 사용할 수 있는 변환 서비스(org.springframework.core.convert.ConversionService)를 사용한다. 이 변환 서비스는 기본 변환기를 내장하고 있지만 커스텀 변환기를 추가하는 것도 가능하다. 또한 핵심 기능으로 제네릭(Generic)을 인식한다. 즉 표현식에서 제네릭 타입을 사용하면, 스프링은 타입 일관성을 유지하기 위해 해당 타입으로 변환을 시도한다는 것이다.

실제로 어떻게 될까? setValue()를 사용하여 문자열을 Boolean 타입의 리스트에 넣는다. SpEL은 해당 리스트의 요소가 Boolean 타입이어야 한다는 것을 인식하고 적절하게 문자열을 Boolean 타입으로 변환해준다.

class Simple {
    public List<Boolean> booleanList = new ArrayList<Boolean>();
}
       
Simple simple = new Simple();

simple.booleanList.add(true);

StandardEvaluationContext simpleContext = new StandardEvaluationContext(simple);

// false is passed in here as a string.  SpEL and the conversion service will
// correctly recognize that it needs to be a Boolean and convert it
parser.parseExpression("booleanList[0]").setValue(simpleContext, "false");

// b will be false
Boolean b = simple.booleanList.get(0);
       
7.4. 빈 정의할 때 EL 사용하기 절

SpEL 표현식은 XML과 애노테이션 기반 설정에서 BeanDefinition에 대한 메타데이터를 정의할 때 사용할 수 있다. 두 경우 모두 표현식을 정의할 때 #{표현식} 문법을 사용한다.

7.4.1. XML 기반 설정

속성 또는 생성자-인자 값을 아래와 같이 표현식에 설정할 수 있다.

<bean id="numberGuess" class="org.spring.samples.NumberGuess">
    <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>

    <!-- other properties -->
</bean>

'systemProperties' 변수는 미리 정의되어 있다. 따라서 아래 처럼 표현식에서 사용할 수 있다. 미리 정의되어 있는 변수는 #기호를 붙일 필요가 없다.

<bean id="taxCalculator" class="org.spring.samples.TaxCalculator">
    <property name="defaultLocale" value="#{ systemProperties['user.region'] }"/>

    <!-- other properties -->
</bean>

또한 다른 빈의 속성을 그 이름으로 참조할 수도 있다.

<bean id="numberGuess" class="org.spring.samples.NumberGuess">
    <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>

    <!-- other properties -->
</bean>


<bean id="shapeGuess" class="org.spring.samples.ShapeGuess">
    <property name="initialShapeSeed" value="#{ numberGuess.randomNumber }"/>

    <!-- other properties -->
</bean>

7.4.2. 애노테이션-기반 설정

@Value 애노테이션을 필드, 메서드 그리고 메서드와 생성자의 매개변수에 사용하여 기본 값을 설정할 수 있다.

다음 예제는 필드 변수에 기본 값을 설정한다.

public static class FieldValueTestBean

  @Value("#{ systemProperties['user.region'] }")
  private String defaultLocale;

  public void setDefaultLocale(String defaultLocale)
  {
    this.defaultLocale = defaultLocale;
  }

  public String getDefaultLocale()
  {
    return this.defaultLocale;
  }

}

이번에는 같은 작업을 세터 메서드에 한다.

public static class PropertyValueTestBean

  private String defaultLocale;

  @Value("#{ systemProperties['user.region'] }")
  public void setDefaultLocale(String defaultLocale)
  {
    this.defaultLocale = defaultLocale;
  }

  public String getDefaultLocale()
  {
    return this.defaultLocale;
  }

}

자동 연결(Autowiring)을 사용하는 메서드와 생성자에도 @Value 애노테이션을 사용할 수 있다.

public class SimpleMovieLister {

    private MovieFinder movieFinder;
    private String defaultLocale;

    @Autowired
    public void configure(MovieFinder movieFinder,
                          @Value("#{ systemProperties['user.region'] } String defaultLocale) {
        this.movieFinder = movieFinder;
        this.defaultLocale = defaultLocale;
    }

    // ...
}
public class MovieRecommender {

    private String defaultLocale;
   
    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao,
                            @Value("#{ systemProperties['user.country'] } String defaultLocale) {
        this.customerPreferenceDao = customerPreferenceDao;
        this.defaultLocale = defaultLocale;
    }

    // ...
}

7.5. EL 레퍼런스

생략

7.6. 예제에서 사용한 클래스

생략



신고
top


또치야~~ 사진 찍을까? 사진?!




복실복실한게 곰돌이처럼 이뻤으나 털이 날려서 깔끔하게 밀었습니다. 별로 똑똑한 종이 아니라는데, '빵'이라고 하면 드러눕고, '손'이라고 하면 앞발도 주고, '다른 손'이라고 하면 반대 쪽 앞발을 내밉니다. 또 '공 물어와 공공공' 이러면 또치가 좋아하는 빨간 공을 재빨리 물어옵니다. 마지막으로 '간식 줄까?' 라고 하면 방방 뛰면서 빨리 달라고 보챕니다.

그러나.. 자기가 알아 듣지 못하는 말을 하면 저런 갸우뚱~ 하는 표정을 보여주지요. "또치야 아구 이쁘다~~ 넌 앞으로 나의 촬영 모델이야~"
신고

'모하니? > TakingAPicture' 카테고리의 다른 글

090419 경마 공원 나들이  (4) 2009.04.21
또치야~~ 사진 찍을까? 사진?!  (4) 2009.04.20
top

TAG 또치

What's new in Spring 3.0?

Spring/etc : 2009.04.20 19:34


참조: http://www.epril.com/resources/spring3/reference/html/ch02.html

요약 및 편역합니다.

2.1 자바 5

전페 프레임워크 코드를 제네릭, 가변인수(varargs) 같은 자바 5 기능을 사용하도록 수정했다. FactoryBean, 스프링 AOP, ApplicationListener 코드에 제네릭을 활용했다. 또한, TrasactionCallback과 HibernateCallback과 같은 콜백 인터페이스들은 제네릭한 결과를 반환하도록 수정했다. 스프링 코어 코드베이스를 전반적으로 자바 5에 최적화 시켰다.

스프링의 TaskExecutor 추상화 계층을 자바 5의 java.util.concurrent 시설과 밀접하게 통합되도록 수정했다. JSR-236(자바 EE 6 Concurrency Utilies)에 포함되어 있는 Callable, Future, ExecutorService 어댑터, ThreadFactory 연동 등을 지원한다. 또한 (EJB 3.1 @Asynchronous 또는) @Async 애노테이션을 사용하여 비동기 메서드 호출도 지원한다.

2.2. 개선한 문서

추가된 기능에 맞게 3.0 문서 작업을 새로 했고, 검증을 했지만 그래도 틀린 부분이 있다면 이슈를 등록해 달라.

2.3. 새로운 모듈 구조와 빌드 시스템

다음과 같은 모듈로 새롭게 개정했고 소스 트리당 모듈.jar로 관리한다.

      org.springframework.aop
      org.springframework.beans
      org.springframework.context
      org.springframework.context.support
      org.springframework.expression
      org.springframework.instrument
      org.springframework.jdbc
      org.springframework.jms
      org.springframework.orm
      org.springframework.oxm
      org.springframework.test
      org.springframework.transaction
      org.springframework.web
      org.springframework.web.portlet
      org.springframework.web.servlet

* 더 이상 모든 구성요소를 담고 있던 spring.jar는 제공하지 않는다.

새로운 스프링 빌드 시스템을 사용한다. 그 시스템은 다음 기능을 제공한다.

      Ivy 기반 "스프링 빌드" 시스템
      일관된 배포 절차
      일관된 의존성 관리
      일관된 OSGi manifest 생성

2.4. 새로운 기능 살펴보기

다음은 스프링 3.0이 새롭게 제공하는 기능이다. 이 기능들을 자세히 살펴보겠다.

      Spring Expression Language
      IoC enhancements/Java based bean metadata
      Object to XML mapping functionality (OXM) moved from Spring Web Services project
      Comprehensive REST support
      @MVC additions
      Declarative model validation
      Early support for Java EE 6

2.4.1. 자바 5에 맞게 핵심 API 업데이트

BeanFactory 인터페이스가 타입에 맞는 빈을 반환한다.

      T getBean(Stringname, Class<T> requiredType)
      Map<String, T> getBeansOfType(Class<T> type)

스프링의 TaskExecutor 인터페이스가 java.util.concurrent.Executor를 상속 받는다.

      AsyncTaskExecutor를 확장하여 표준 Callables와 Futures를 지원한다.

새로운 자바 5 기반의 converter API와 SPI
 
      stateless ConversionService와 Converters
      표준 JDK PropertyEditor 대체제

타입을 가지고 있는 ApplicationListener<E>

2.4.2. 스프링 EL(Expression Language)

스프링은 통합 EL과 비슷한 EL을 토입했다. EL은 XML 정의와 애노테이션 기반 빈 설정에서 사용할 수 있다. 이 기능에 대한 자세한 설명은 Spring Expression Language (SpEL).장을 참조하라.

스프링 EL은 모든 스프링 포트폴리오 제품에서 사용할 수 있는 단일 EL을 제공하기 위해 만들었다.

다음은 데이터베이스 설정 프로퍼티에 EL을 사용하는 예제다.

<bean class="mycompany.RewardsTestDatabase">
    <property name="databaseName"
        value="#{systemProperties.databaseName}"/>
    <property name="keyGenerator"
        value="#{strategyBean.databaseKeyGenerator}"/>
</bean>

이 기능은 애노테이션에도 사용할 수 있다.

@Repository
public class RewardsTestDatabase {

    @Value("#{systemProperties.databaseName}")
    public void setDatabaseName(String dbName) { … }

    @Value("#{strategyBean.databaseKeyGenerator}")
    public voidsetKeyGenerator(KeyGenerator kg) { … }
}

2.4.3. IoC 컨테이너

2.4.3.1. 자바 기반 빈 메타데이타

JavaConfig 프로젝트의 몇몇 핵심 기능을 스프링 프레임워크로 가져왔다. 즉 다음의 애노테이션을 직접 사용할 수 있다는 뜻이다.
   
      @Configuration
      @Bean
      @Primary
      @Lazy
      @Import
      @Value

다음은 JavaConfig 기능을 사용하는 기본적인 빈 설정 예제다.

@Configuration
public class AppConfig{
    private @Value("#{jdbcProperties.url}") String jdbcUrl;
    private @Value("#{jdbcProperties.username}") String username;
    private @Value("#{jdbcProperties.password}") String password;

    @Bean
    public FooService fooService() {
        return new FooServiceImpl(fooRepository());
    }

    @Bean
    public FooRepository fooRepository() {
        return new HibernateFooRepository(sessionFactory());
    }

    @Bean
    public SessionFactory sessionFactory() {
        // wire up a session factory using
        // AnnotationSessionFactoryBean
        asFactoryBean.setDataSource(dataSource());
        return (SessionFactory) asFactoryBean.getObject();
    }

    @Bean
    public DataSource dataSource() {
        return new DriverManagerDataSource(jdbcUrl, username, password);
    }
}

이 것이 동작하게 하려며 애플리케이션 컨텍스트 XML 설정 파일에 다음과 같이 컴포넌트 스캔을 추가한다.

<context:component-scan
    base-package="com.myco.config"/>
 
2.4.3.2. 애노테이션을 활용한 팩토리 빈 정의

FactoryBean은 스프링 컴포넌트 정의와 표준 컴포넌트-스캔 기술을 사용한 등록 방식으로 정의할 수 있다. 자세한 내용은 Factory Bean Definitions using annotations을 참조하라.

2.4.4. Data 단

스프링 웹 서비스 프로젝트에서 객체(Object)를 XML로 맵핑하는 기능(OXM)을 스프링 프레임워크로 가져왔다, 이 기능은 org.springframework.oxm 패키지에 들어있다. OXM의 자세한 사용법은 Marshalling XML using O/X Mappers를 참조하라.

2.4.5. Web 단

웹 단에서 가장 흥미로운 새 기능은 RESTful 웹 서비스와 웹 애플리케이션 지원 기능이다. 또한 새로운 애노테이션도 사용할 수 있다.

2.4.5.1. 방대한 REST 지원

RESTful 애플리케이션을 만드는 서버쪽 지원은 기존의 MVC 웹 프레임워크에서 주도적인 역할을 하는 애노테이션에 대한 확장 기능으로 제공한다. 클라이언트쪽 지원은 RestTemplate 클래스로 제공한다. 이 둘 모두 HttpConverter를 사용하여 객체와 그것에 대한 HTTP 요청과 응답 사이를 변환 해준다.

MarhsallingHttpMessageConverter는 앞서 언급한 Object to XML 맵핑 기능을 사용한다.

자세한 내용은 REST support를 참조하라.

2.4.5.2 @MVC additions

@CookieValue와 @RequestHeaders 애노테이션이 추가됐다. Mapping cookie values with the @CookieValue annotationMapping request header attributes with the @RequestHeader annotation을 참조하라.

2.4.6 선언적인 모델 검증

하이버네이트 검증기, JSR 303

작업중... 스프링 3.0 M3 배포에 포함되어 있지 않다.

2.4.7 발빠른 자바 EE 6 지원

새로운 애노테이션 @Async (or EJB 3.1's @Asynchronous 애노테이션)을 사용하여 비동기 메서드 호출을 지원한다.

JSF 2.0, JPA 2.0, 기타 등등

작업중... 스프링 3.0 M3 배포에 포함되어 있지 않다.


신고
top


캬~ 나도 이제 DSLR 유저



색시한테 시원찮은 선물만 해줬는데 이 번엔 조금 제대로 선물을 사줬습니다. 중고로;;

캐논 400D


번들용 렌즈 EFS 18-55


Tamron 1750


400D야 신혼여행 잘 부탁해~
신고
top


못살겠다 대한민국

모하니?/Watching : 2009.04.17 14:36




캬~~ 노래 좋다! 노래방엔 없겠죠? 제목도 모르는데;;
신고
top


초간단 CURD, 검색, 페이징, 정렬 구현 완료

모하니?/Coding : 2009.04.17 11:58


Opensprout Nexus에서 제공하는 스프링 최신 버전(3.0 기반)을 사용했고 스프링 번들 저장소에 있는 하이버네이트 라이브러리를 사용했습니다. 그밖에는 뭐 서블릿 API, JSP, JSTL, taglib 등을 사용했고 로깅은 slf4j-log4j를 사용했습니다. DB는 별도의 설치가 필요없게 derby를 사용했고 c3po 풀링 라이브러리를 사용했습니다.

빌드는 메이븐으로 했고 War 배포 방식은 inplace로 했으며 라이브러리를 가져올 저장소는 모두 pom.xml에 등록해 두었습니다.(war 플러긴을 못 가져오는 버그가 발생하고 있다는데 조만간 해결되리라 생각합니다.)

도메인은 Member 하나이고, 하이버네이트 애노테이션이 추가되서 POJO라고 보기는 좀 힘들겠습니다. 하이버네이트 설정을 XML로 바꿀까 생각중입니다. 아니면 스프링처럼 JavaConfig 같은 스타일을 사용할 수는 없을지 궁금하네요. 지원해준다면 기꺼이 그렇게 바꾸고 싶습니다. 도메인 클래스는 POJO로 유지하고 하이버네이트 설정은 밖으로 분리할 수 있으니까요. 대신 그 설정 파일이 자바 파일이라면 이름 변경과 같은 리팩터링에도 유기적으로 반응할테니 JavaConfig와 유사한 장점을 지닐 수 있지 않을까 싶습니다.

Controller는 스프링 3.0의 URI 템플릿 기능을 사용해봤습니다. 재밌더군요. list와 add를 제외한 view, updat, delete에 적용해봤습니다. 기본 CRUD만 구현했을 때에는 컨트롤러가 썰렁했는데, 검색, 페이징, 정렬 기능이 추가될 때 마다 코드가 조금씩 늘어나기 시작해서 지금은 이런 모습이 되었습니다.

package whiteship.member;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import whiteship.domain.Member;
import whiteship.member.support.OrderParam;
import whiteship.member.support.SearchParam;
import whiteship.paging.PageParam;

@Controller
@SessionAttributes("member")
public class MemberController {

    @Autowired
    MemberService service;

    @Autowired
    MemberValidator validator;

    // Create
    @RequestMapping(value = "/member/add", method = RequestMethod.GET)
    public String addForm(Model model) {
        Member member = new Member();
        model.addAttribute(member);
        return "member/add";
    }

    @RequestMapping(value = "/member/add", method = RequestMethod.POST)
    public String addForm(Member member, BindingResult result,
            SessionStatus status) {
        validator.validate(member, result);
        if (result.hasErrors()) {
            return "member/add";
        } else {
            service.add(member);
            status.isComplete();
            return "redirect:/member/list.do";
        }
    }

    // Read
    @RequestMapping("/member/list")
    public ModelMap list(PageParam pageParam, SearchParam searchParam,
            OrderParam orderParam) {
        ModelMap modelMap = new ModelMap();
        modelMap.addAttribute(service
                .getMemberListByPageAndSearchAndOrderParam(pageParam,
                        searchParam, orderParam));
        modelMap.addAttribute(pageParam);
        modelMap.addAttribute(searchParam);
        modelMap.addAttribute(orderParam);
        return modelMap;
    }

    @RequestMapping("/member/{id}")
    public String view(@PathVariable int id, Model model, PageParam pageParam,
            SearchParam searchParam, OrderParam orderParam) {
        model.addAttribute(service.getMemberById(id));
        model.addAttribute(pageParam);
        model.addAttribute(searchParam);
        model.addAttribute(orderParam);
        return "member/view";
    }

    // Update
    @RequestMapping(value = "/member/update/{id}", method = RequestMethod.GET)
    public String updateForm(@PathVariable int id, Model model,
            PageParam pageParam, SearchParam searchParam, OrderParam orderParam) {
        model.addAttribute(service.getMemberById(id));
        model.addAttribute(pageParam);
        model.addAttribute(searchParam);
        model.addAttribute(orderParam);
        return "member/update";
    }

    @RequestMapping(value = "/member/update/{id}", method = RequestMethod.POST)
    public String updateForm(PageParam pageParam, SearchParam searchParam,
            OrderParam orderParam, Member member, BindingResult result,
            SessionStatus status) {
        validator.validate(member, result);
        if (result.hasErrors()) {
            return "member/update";
        } else {
            service.update(member);
            status.isComplete();
            return redirectURLWithPageAndSearchAndOrderParam(pageParam,
                    searchParam, orderParam);
        }
    }

    // Delete
    @RequestMapping("/member/delete/{id}")
    public String delete(@PathVariable int id, PageParam pageParam,
            SearchParam searchParam, OrderParam orderParam) {
        service.deleteById(id);
        return redirectURLWithPageAndSearchAndOrderParam(pageParam, searchParam, orderParam);
    }

    private String redirectURLWithPageAndSearchAndOrderParam(
            PageParam pageParam, SearchParam searchParam, OrderParam orderParam) {
        return redirectURLWithPageAndSearchParam(pageParam, searchParam)
                + "&field=" + orderParam.getField() + "&direction="
                + orderParam.getDirection();
    }

    private String redirectURLWithPageAndSearchParam(PageParam pageParam,
            SearchParam searchParam) {
        return pagedListURL(pageParam) + "&name=" + searchParam.getName()
                + "&email=" + searchParam.getEmail();
    }

    private String pagedListURL(PageParam pageParam) {
        return "redirect:/member/list.do?size=" + pageParam.getSize()
        + "&page=" + pageParam.getPage();
    }

}

List에서 페이징, 검색, 정렬 정보를 가지고 View로 간 다음 Update와 Delete 또는 뒤로가기(List) 기능에 그 정보들을 사용하거나 넘겨 줍니다. Update와 Delete에서는 해당 정보들을 이요하고, 처리를 끝 낸다음 페이징, 검색, 정렬 정보를 유지한채 List로 다시 넘어갑니다. 따라서 삭제 하기 전에 했던 페이징, 검색, 정렬 정보를 그대로 유지한 화면으로 돌아가게 됩니다.

이게 핵심이었습니다. 이 것 때문에 복잡해진 겁니다. 매개변수를 계속 물고 다녀야 하고, URL은 계속 복잡해지고, 페이징, 검색, 정렬 기능이 추가될 때마다 혹은 검색 변수가 추가될 때 마다 URL이 바뀌게 되는데 URL이 사방에 있기 때문에 수정 작업을 할 곳이 한 두곳이 아닙니다.

1. 일단 컨트롤러에서 URL 만드는 부분을 수정해야 합니다.
2. list.jsp
3. view.jsp
4. update.jsp

총 네 개의 파일을 수정해야 하고, 특히 페이징이 들어있는 list.jsp 파일의 경우 10~12줄 가량의 코드를 손봐야 합니다.


<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Whiteboard2</title>
</head>

<body>
<div>
<a href="/member/add.do">회원 추가</a>
</div>

<div>
<c:if test="${empty memberList}">
회원 목록이 없습니다.
</c:if>

<c:if test="${! empty memberList}">
<form:form method="GET" commandName="searchParam">
    이름: <form:input path="name" />
    이메일: <form:input path="email" />
    <input type="submit" value="검색" />
</form:form>


페이지 사이즈: ${pageParam.size}<br/>
현재 페이지: ${pageParam.page}<br/>
총 갯수: ${pageParam.totalRowsCount}<br/>
현재 페이지 첫 번째 목록 인덱스: ${pageParam.firstRowNumber}<br/>

<c:if test="${pageParam.totalRowsCount > pageParam.size}">

    <a href="/member/list.do?page=1&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=${orderParam.field}&direction=${orderParam.direction}">처음</a> |

    <c:if test="${pageParam.beginPage - 10 > 0}">
        <a href="/member/list.do?page=1&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=${orderParam.field}&direction=${orderParam.direction}">이전</a> |
    </c:if>

    <c:forEach begin="${pageParam.beginPage}" end="${pageParam.endPage}" varStatus="current">
        <c:choose>
            <c:when test="${current.count == pageParam.page}">
                <a href="/member/list.do?page=${current.count}&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=${orderParam.field}&direction=${orderParam.direction}"><strong>${current.count}</strong></a> |
            </c:when>
            <c:otherwise>
                <a href="/member/list.do?page=${current.count}&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=${orderParam.field}&direction=${orderParam.direction}">${current.count}</a> |
            </c:otherwise>
        </c:choose>
    </c:forEach>

    <c:if test="${pageParam.beginPage + 10 < pageParam.totalPage}">
        <a href="/member/list.do?page=${current.count + 10}&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=${orderParam.field}&direction=${orderParam.direction}">다음</a> |
    </c:if>

    <a href="/member/list.do?page=${pageParam.totalPage}&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=${orderParam.field}&direction=${orderParam.direction}">마지막</a>

</c:if>

<table>
    <tr>
        <th>
            <c:choose>
                <c:when test="${orderParam.field == 'email' && orderParam.direction == 'asc'}">
                    <a href="/member/list.do?page=1&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=email&direction=desc">이메일V</a>
                </c:when>
                <c:otherwise>
                    <a href="/member/list.do?page=1&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=email&direction=asc">이메일^</a>
                </c:otherwise>
            </c:choose>
        </th>
        <th>
            <c:choose>
                <c:when test="${orderParam.field == 'name' && orderParam.direction == 'asc'}">
                    <a href="/member/list.do?page=1&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=name&direction=desc">이름V</a>
                </c:when>
                <c:otherwise>
                    <a href="/member/list.do?page=1&size=${pageParam.size}&name=${searchParam.name}&email=${searchParam.email}&field=name&direction=asc">이름^</a>
                </c:otherwise>
            </c:choose>
        </th>
    </tr>
<c:forEach var="member" items="${memberList}">
    <tr>
        <td><a href="/member/${member.id}.do?size=${pageParam.size}&page=${pageParam.page}&name=${searchParam.name}&email=${searchParam.email}&field=${orderParam.field}&direction=${orderParam.direction}">${member.email}</a></td>
        <td>${member.name}</td>
    </tr>
</c:forEach>
</table>
</c:if>
</div>
</body>

</html>

이게 현재 list.jsp 파일입니다. 이클립스에서 보면 96줄에 해당합니다.

자 이제는 이것을 어떻게 하면 깔끔하고 편리하게 다듬을지 고민할 시간입니다. 좋은 의견 있으신 분들은 댓글 주시면 감사하겠습니다~ ^^

ps: 티스토리에서 아직도 코드 하이라이팅 플러긴 같은거 안 나왔죠?? 티스토리 서비스 한지가 몇 년 짼데 아직도 안 나와~~~ ㅠ.ㅠ


신고
top


외국 IT 기업에서 원하는 걸 보자꾸나~

모하니?/Thinking : 2009.04.17 10:21


channy님 블로그에 잼난 글이 올라와서 살펴봤습니다. 사실 잼난 글보다는 그래프가 눈에 확 띄어서 보게 되었는데 역시 글보다는 그림이 매력 만점인 것 같습니다.

어떤 능력을 원하는지 알고 그에 맞춰 준비한다면 외국 회사에 취직하는 것도 그리 어렵진 않을 것 같습니다. 자신의 무대를 한국으로 특화 시키는 것도 좋을지 모르겠지만, 할 수 있으면 외국 기업에 취직해보는 것도 재밌을 것 같습니다.

퍼와도 될지 몰겠지만 일단 그림만 퍼옵니다.ㅋㅋ


대충 보니까 일단 필요한 기술 다섯 개 이상 보유하고 있으면 좋겠구요.

이력서를 LaTex라는 걸로 만들어야 좋아하나 봅니다. 대충 살펴봤는데.. HTML 비슷하게 메타 표현식을 사용해서 문서를 만드는 도구 같습니다. 개발자가 아니면 사용하기 불편해 보이네요.

수업 이외의 프로그래밍 경험으로 특히 OS나 컴파일러 개발에 많은 점수를 주고 있습니다.

동적 언어(Perl, Python, Ruby) 중 하나는 잘 다룰 줄 아는게 좋겠네요.

프로그래밍 관련 클럽 리더 였거나 블로그 운영 등 커뮤니티 활동에도 후한 점수를 주고 있습니다.

대충 그렇군요. 지금 상태로는 취업하기가 좀 힘들겠네요. 열공 해야겠습니다~
신고

'모하니? > Thinking' 카테고리의 다른 글

약속의 힘  (2) 2009.07.23
벌써 한 달이 넘었군요.  (12) 2009.07.07
스프링소스의 끼워주기(?) 패키지  (2) 2009.06.17
이제 다시 복귀 할 시간  (8) 2009.06.07
재밌는 상상~ 누드 비치에 사무실 차리기  (6) 2009.04.28
외국 IT 기업에서 원하는 걸 보자꾸나~  (5) 2009.04.17
'개발' 역시 참 맛있다.  (2) 2009.04.16
저 결혼해요~~  (92) 2009.03.02
난 몇 살?  (0) 2009.01.28
새로운 인연  (28) 2009.01.19
친구의 DAO 테스트  (2) 2008.12.16
top


'개발' 역시 참 맛있다.

모하니?/Thinking : 2009.04.16 16:33


번역을 핑계대로 놀고 있던건지 놀고 있어서 번역을 한건지 모르겠는 시간이 지나가고 이젠 슬슬 다시 개발에 집중할 시간이 오고 있습니다.

먼저 사부님이 내주신 통짜(프레임으로 나눠져 있지 않은) 게시판 만들기 과제를 진행하고 있습니다. 차근 차근 CRUD -> 페이징 -> 검색 -> 정렬 기능까지 구현하는 것인데 오늘 검색까지 했고 내일 정렬까지 하면 끝날 것 같습니다. 이렇게 하루에 기능 하나씩 하면 될 것을 왜 지난 스터디때는 두 달이나 걸렸는지 몰겠습니다. 지금 이것도 상당히 느린편이죠. 보통 몇 시간이면 전부 다 구현이 가능할텐데 말입니다. 연습이 더 필요한 것 같습니다.

기능을 하나 하나 구현해 갈때마다 느끼는 것들이 있는데 그 것들을 기록해 두지 않고 몇일이 지나면 잊어벼려서 아쉽습니다. 아마 그래서 지금 이 글을 작성하고 있는 걸지도 모르겠습니다. 특히 이번 게시판 구현을 통해 느끼는 것은 URL을 만드는 것이 복잡해져서 어딘가 한 곳에서 관리할 수 있으면 좋겠다는 것입니다. 그리고 검색 조건이나 페이징 관련 매개변수들을 어떻게 하면 더 편하게 관리할 수 없을지, URL을 좀 더 단순하게 만들면서도 저런 정보들을 잘 들고 다닐 수는 없을지 등등이 고민 됩니다.

두 번째로 기존 시스템에 추가기능 요구사항이 들어와서 고객을 만나고 왔습니다. 회사에 직원이 별로 없는 관계로 직접 고객과 대면하여 요구사항을 정리할 수 있다는 것은 정말 행운인것 같습니다. 고객이 일하고 있는 도메인 지식을 쌓을 수 있고 그것을 개발자 입장에서 정리하여 다시 고객이 이해할 수 있는 그림이나 말로 표현하는 훈련을 자연스럽게 할 수 있습니다.

추가 기능은 재고관리에서 선입선출에 관한 것이었는데 닷넷 프로그램과 스프링+하이버로 만든 서버쪽 프로그램을 모두 손봐야 하는 상황이었습니다. 일단 되도록이면 기존 코드를 많이 건드리지 않도록 추가기능은 별도의 매서드로 분리하고 웹 서비스로 공개해놓고, wsdl로 잘 나와있는지 확인한 다음, 닷넷으로 가서 웹 서비스 URL을 로컬로 변경한 다음 업데이트 해주고, 닷넷 프로그램을 수정하여 원하는 화면을 그리고 코드를 수정하여 추가 기능을 구현했습니다. 중간에 데이터 테스트가 조금 필요한 부분이 있었지만 별로 복잡한 로직이 아니라서 일단 테스트는 생략하고 구현했습니다. 그리고나서 서버를 돌리고 닷넷을 돌리고 원하는 추가기능 시나리오를 테스트 합니다. 잘 동작하는 것을 확인했지만 아직 배포하지는 않았습니다. 오늘 내일 한 번씩 더 검증하고 배포해도 고객이 원하던 시간보다 일주일이나 더 빨리 만들어 주는 것이기 때문이죠.

세 번째로 조금 전 위의 시스템 사용자로 부터 에러 보고를 받았습니다. 배치를 실행하여 다른 쪽 서버에 있는 데이터와 싱크를 맞추던 도중 에러가 발생했습니다. 에러 메시지 조차 없이 사용자 친화적으로 '관리자에게 문의하시로'라는 문구가 있었습니다. 귀찮기도 하고 감도 안잡혀서 일단 선임개발자에게 메일을 포워딩했습니다. 그러자 에러가 발생 가능한 지점을 설명해 주시고 그쪽을 살펴보라고 하십니다. 일단은 어떤 작업을 하다가 발생한 에러인지 확인했으니까 로컬에서 해당 작업을 재현해 봤습니다. 똑같은 에러를 볼 수 있었스빈다. 다행이라고 생각하고 콘솔에 찍힌 에러 로그를 자세히 들여다 봤습니다. 이 배치를 돌리기 전에 다른 배치를 돌려서 이번 배치를 돌 때 필요한 다른 데이터를 먼저 싱크 했어야 한다는 생각이 들어서 선임개발자인 사부님께 물어보고 확인을 받았습니다. 그래서 필요하다고 생각한 다른 배치를 로컬에서 먼저 실행하고 에러가 발생한 배치를 돌렸습니다. 잘 동작했습니다. 빙고! 전화로 간단하게 대처법을 통지해주고 오늘 하루 일과는 끝납니다.

원래는 조금 더 일하다 집에 가야 하는데 오늘은 본가에 들려서 김치도 가져가야되고, 머리도 좀 아프고, 색시가 어제부터 끙끙 앓고 있는 바람에 후딱 들어가봐야겠습니다.


신고

'모하니? > Thinking' 카테고리의 다른 글

벌써 한 달이 넘었군요.  (12) 2009.07.07
스프링소스의 끼워주기(?) 패키지  (2) 2009.06.17
이제 다시 복귀 할 시간  (8) 2009.06.07
재밌는 상상~ 누드 비치에 사무실 차리기  (6) 2009.04.28
외국 IT 기업에서 원하는 걸 보자꾸나~  (5) 2009.04.17
'개발' 역시 참 맛있다.  (2) 2009.04.16
저 결혼해요~~  (92) 2009.03.02
난 몇 살?  (0) 2009.01.28
새로운 인연  (28) 2009.01.19
친구의 DAO 테스트  (2) 2008.12.16
S1A 첫 날 - 뢉 해럽 Q&A  (0) 2008.12.02
top

TAG 개발

Github에 pull, push하기

Good Tools : 2009.04.14 11:37


간단하지 않더군요. public 저장소라길래 아무나 소스 코드 받고 아무나 소스 코드 수정해서 올릴 수 있나보다 했는데.. 그게 아니더군요. 아무나 소스 코드를 받아 갈 수는 있습니다. 하지만 아무나 소스 코드를 수정할 수는 없더군요. 즉.. pull은 자유롭지만 push는 그렇지 않았습니다. push를 하려면 공개키, 비공개키를 만든다음, 공개키를 public 저장소에 등록해 두어야 push할 수 있습니다.

0. pull 하기

git pull URI

이런 형태로 하면 프로젝트를 가져옵니다. 따라서 workspace에서 실행하는게 좋겠죠.

1. 공개키, 비공개키 만들기

http://github.com/guides/providing-your-ssh-key

여기를 참조하셔서 리눅스, 맥, 윈도우에서 키를 만듭니다.
주의할 것이 있는데, 키를 만들 때 사용한 passPhrase..
키워드 같은 것을 기억해 두세요. 기억력이 약하시면 어딘가에 저장해 두세요.

2. 공개키를 public 저장소에 등록하기

사용자 삽입 이미지

이런 식으로 공개키를 등록해 줍니다. 물론 저 화면에는 아무나 들어갈 수 없고 public 저장소 주인장만 들어갈 수 있죠. 따라서 팀원들은 공개키를 만든 다음에 주인장에게 공개키를 전달해야 합니다.

3. push 하기

git push git@github.com:사용자/저장소.git

이런 형태로 쓰면 됩니다. 그러면 중간에 passphrase를 입력하라는 콘솔이 뜹니다. 그럼 이제 키를 만들 때 입력한 passphrase를 입력하시면 끝~~

다음에는 branch, merge, conflic 해결등을 다뤄볼까 합니다.
신고

'Good Tools' 카테고리의 다른 글

Tiles와 SiteMesh 차이  (0) 2009.05.01
Tiles VS SiteMesh  (2) 2009.05.01
Prototype VS JQuery 트랜드 비교  (2) 2009.04.28
기트(Git)와 SVN으로 동시에 버전 관리하기  (4) 2009.04.27
Github 맘에 드네~  (0) 2009.04.25
Github에 pull, push하기  (2) 2009.04.14
기트(git) config  (0) 2009.04.09
기트(git) 주요 명령어  (2) 2009.04.07
기트(Git) 주요 개념  (8) 2009.03.30
JGit 설치  (0) 2009.03.26
아이폰 애플리케이션 iDie  (0) 2009.03.03
top

TAG Git, GitHub, Pull, push

2009년 벗꽃놀이 다녀옴



확대

사람이 너무 많아서 힘들었지만, 나름대로 재밌었네요.
날씨가 흐려서 이번 주 내로 꽃잎이 다 떨어질 것 같아요.
평일 저녁에 가면 사람이 그래도 좀 적을테니 한 번 가보세요~
신고
top


OpenSprout Nexus 이용하여 스프링 3.0 라이브러리 추가하기

OSAF : 2009.04.13 10:11


참조:
Spring 3.0 (4) - Maven에서 Spring 3.0 최신버전 사용하기
Spring3.0 (5) - 스프링 모듈의 의존관계
Maven의 version range를 사용할 때 주의할 점

일단 사부님이 관리 중인 OpenSprout Nexus를 메이븐 settings.xml나 프로젝트의 pom.xml에 등록해 주세요.

<repository> 
    <id>spring-latest</id> 
    <name>Spring Latest by OpenSprout</name> 
    <url>http://www.opensprout.org/nexus/content/repositories/spring-latest</url> 
</repository> 

다음으로 스프링 번들 리파지토리도 등록해주세요.

<repository> 
    <id>com.springsource.repository.bundles.external</id>  
    <name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name> 
    <url>http://repository.springsource.com/maven/bundles/external</url> 
</repository>

이제 준비는 끝났습니다. 본격적으로 스프링 3.0 라이브러리를 추가하면 됩니다. 추가하는 방법은 두 가지가 있을 수 있습니다. 모든 라이브러리를 직관적으로 명시해주는 방법과 추이적 종속성을 이용하여 반드시 명시해야 할 것만 명시하는 방법이 있습니다.

사용자 삽입 이미지
원본 이미지: http://toby.epril.com/?p=598

사부님이 그린 그림을 보면 빨간색 박스로 표시한 라이브러리만 추가하면 파란색으로 칠한 모든 라이브러리를 추이적으로 가져올 거라는 것을 알 수 있습니다. 따라서.. pom.xml에 다음과 같이 설정하면 스프링 라이브러리 중에 필요한 것은 대부분 가져옵니다.

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.web.servlet</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.aspects</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.orm</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>org.springframework.test</artifactId>
            <version>[3.0.0.BUILD-00000000000000,9.9.9.BUILD]</version>
        </dependency>

버전 범위 표시를 저렇게 한 이유는 세 번째 참조 글에서 확인할 수 있습니다.

이렇게 해서 가져온 라이브러리들을 M2Eclipse 플러긴의 Dependency Graph 또는 Dependency Hierarchy로 확인할 수 있습니다.

사용자 삽입 이미지
사용자 삽입 이미지

스프링 3.0이 어떤 제 3 라이브러리(어떤 버전을) 사용하는지 궁금하다면

http://spreadsheets.google.com/pub?key=ppDRa3Yit-05zS2cqWYFlNA

사부님이 작성하신 위 문서를 참조하시면 됩니다.

나이스!! 이제는 드디어 스프링 3.0 개발을 시작합니다~
신고
top


기트(git) config

Good Tools : 2009.04.09 10:57


참조: http://www.kernel.org/pub/software/scm/git/docs/git-config.html

사용자 삽입 이미지

--global 옵션을 사용하려고 시도하면 처음에 fatal: $HOME not set git 이런 에러를 만나게 됩니다. 그럼 환경 변수에 $HOME 변수를 추가해주고 다시 시도해보면 잘 동작할 겁니다.

기트 설정 파일의 위치는 세 종류가 있습니다. 특정 저장소와 관련된 설정, 컴터 사용자 관련 설정, 컴터 관련 설정이 있습니다.

아무런 옵션을 주지 않고 git config 라고 사용하면 그 하위 폴더에 .git/config에 설정 합니다. 명시적으로 -f ./git/config 또는 --file ./git/config 같은 식으로 설정할 수도 있습니다.

ex) git conifg user.name "whiteship"

컴터 사용자 관련 설정은 --global 옵션을 사용하면 되고, 시스템 관련 설정은 --system을 사용하면 됩니다.

설정한 정보는 --list 옵션으로 보는데, 살펴볼 설정 위치를 명시해주지 않으면 모든 위치의 설정 성보를 보여줍니다.

ex) git config --list

사용자 삽입 이미지

신고

'Good Tools' 카테고리의 다른 글

Tiles VS SiteMesh  (2) 2009.05.01
Prototype VS JQuery 트랜드 비교  (2) 2009.04.28
기트(Git)와 SVN으로 동시에 버전 관리하기  (4) 2009.04.27
Github 맘에 드네~  (0) 2009.04.25
Github에 pull, push하기  (2) 2009.04.14
기트(git) config  (0) 2009.04.09
기트(git) 주요 명령어  (2) 2009.04.07
기트(Git) 주요 개념  (8) 2009.03.30
JGit 설치  (0) 2009.03.26
아이폰 애플리케이션 iDie  (0) 2009.03.03
구글 토크 사전  (4) 2009.01.05
top


기트(git) 주요 명령어

Good Tools : 2009.04.07 16:42


참조: http://git-scm.com/documentation

로컬 명령어

git config      저장소 또는 글로벌 옵션 가져오거나 설정할 때 사용.
git init     비어있는 기트 저장소 만들거나 기존의 저장소 다시 초기화.
git add     파일 내용을 인덱스에 추가.
git status     작업 트리(working tree) 상태 보기.
git commit     저장소에 변경 사항 기록하기.
git log     커밋 히스토리 보기.
git show     특정 객체 정보 보기.
git tag     태그 만들고, 나열하고, 삭제하고, 검증할 때 사용.

원격 명령어

git clone      저장소를 새 디렉터리에 복사하기.
git remote     추적중인 저장소(tracked repository) 집합 관리하기.
git pull     다른 저장소 또는 로컬 브랜치에서 가져온(fetch) 다음 병합하기(merge).
git fetch     다른 저장소에서 가져오기.
git push     연관된 객체로 원격 저장소 업데이트.

브랜치 명령어

git checkout      브랜치 또는 패스(path)를 작업 트리로 체크아웃하기.
git branch     브랜치 목록 나열하기, 만들기, 삭제하기할 때 사용.
git merge     두 개 이상의 개발 히스토리를 하나로 합치기.
git rebase     브랜치 베이스를 변경할 때 사용(?).

기타 명령어

git diff      커밋, 작업 트리 등 변경 사항 보기.
git apply     기트 인덱스 파일과 작업 트리에 패치(patch) 적용하기.
git format-patch     이메일로 보낼 패치 준비하기.
git am     메일 박스에있는 패치 적용하기.
신고

'Good Tools' 카테고리의 다른 글

Prototype VS JQuery 트랜드 비교  (2) 2009.04.28
기트(Git)와 SVN으로 동시에 버전 관리하기  (4) 2009.04.27
Github 맘에 드네~  (0) 2009.04.25
Github에 pull, push하기  (2) 2009.04.14
기트(git) config  (0) 2009.04.09
기트(git) 주요 명령어  (2) 2009.04.07
기트(Git) 주요 개념  (8) 2009.03.30
JGit 설치  (0) 2009.03.26
아이폰 애플리케이션 iDie  (0) 2009.03.03
구글 토크 사전  (4) 2009.01.05
Word Cloud 만들어보기  (0) 2008.12.08
top


오랜만에 보는 미드 - lie to me



사용자 삽입 이미지

제목이 암시하듯이 '거짓말'을 주제로 한 드라마 입니다. 위에 보이는 연구원(?)들은 사람들의 미세한 표정 및 몸짓으로 거짓말 인지 아닌지 판별 하는 사람들이고, 가운데 카리스마 풀풀 풍기는 아저씨가 대장입니다.

이마에 주름도 생기지 않고 우는 거짓 울음, 눈가에 주름이 생기지 않고 입만 웃고 있는 거짓 웃음, 거짓말 할 때는 질문에 대한 반응 속도가 평소보다 느리다는 거, 한쪽 어깨를 들어올리는 행위, 뒤로 물러나며 팔짱을 끼는 행위 등등~

중요한 건 상대방이 하는 말이 아니라 미세한 몸짓과 표정이더군요. 프리즌 브레이크 이후로 꾸준히 보게 되는 미드네요. 강추합니다! 지금은 시즌 8까지 나왔습니다.
신고
top

TAG Lie To Me

우와~ 스프링 tc 서버다!!

Spring/etc : 2009.04.03 10:55


참조: http://www.springsource.org/node/1251

베타 버전이네요. 음.. 설치부터 간단하지가 않군요. 세 가지 구성요소를 설치해야 하는데, 하나는 tc 서버, 나머지는 AMS와 AMS 에이전트 입니다. 이 둘은 예~전에 한 번 설치해서 본적이 있었는데, 서버나 애플리케이션의 리소스 상황을 보여주고 관리하는데 편리한 기능을 제공하는 시스템이었습니다.

사용자 삽입 이미지

이 그림 한 장이면 이 세 개의 구성요소 간의 관계와 어떤 형태로 설치할 수 있는지 한 눈에 볼 수 있습니다.

AMS Sever, AMS Agent, tc Server를 한 컴퓨터에 모두 설치할 수도 있지만, 저렇게 나눠서 설치할 수도 있으며 그럴 때 AMS Server는 한 곳에만 설치하면 되고, 여러 컴퓨터에 각각 tc Server를 (한개 또는 여러개)설치하고  AMS Server로 정보를 보내줄 AMS Agent도 역시 컴퓨터 마다 하나씩만 설치하면 됩니다.

즉.. 이 들간의 관계를 그려보면 다음과 같다는 것을 알 수 있습니다.

사용자 삽입 이미지

드디어 나올 것이 나왔네요. 기쁩니다!! 이 녀석으로 개발을 시작해야겠습니다.
신고
top

TAG tc Server






티스토리 툴바