다음은 Java 기반 템플릿엔진인 Thymeleaf의 튜토리얼 및 자습서의 번역본이다.

모쪼록 이 강력한 녀석을 바탕으로, SI 뿐 아니라 SM 시장도 광명을 찾게 되기를 바랄 뿐이다.

혹자는 이 템플릿엔진의 무용론을 주장하지만, 

템플릿엔진 하나 갖고 개발 상의 모든 문제를 해결할 수 있을 것처럼 얘기한 적도 없거니와

세상에 그런게 있기는 하냐고 되묻고 싶다.

그리고 이 템플릿엔진의 효용에 대해 - 아는 만큼 보인다는 말을 해 주고 싶다.



여튼 번역본 다운로드는 아래 링크를 누르면 번역본을 다운로드 할 수 있다.

(게으른 탓에 향후 증보는 없을 것이다)



thymeleaf_Tutorial_번역본_v1.1_20131213.pdf


thymeleaf_InteractiveTutorial_자습서_v1.0_20131213.pdf




이제 막 활성화 되어 계속 버전업 되는 템플릿엔진이다 보니 매뉴얼이 계속 변경되고 있다.

자세한 원문 정보는 Thymeleaf의 홈페이지에서 확인하기 바란다.

http://www.thymeleaf.org/documentation.html



당연히 카피레프트이고, 맘대로 퍼가고 읽고 써도 좋다.

물론 출처를 밝히지 않아도 상관 없지만, 밝혀 주면 기분은 좋을 것 같다.



-----------------------------------------------


지난 해 이런 저런 이유로 Thymeleaf 에 대해 공부 하게 됐다.

무척 막강한 템플릿 엔진임에도 불구하고, 국내에는 소개된 자료가 거의 없다.

튜토리얼을 더듬더듬 읽어 내리다..

화딱지가 나 번역을 해 버렸다.


번역하는 동안 쓰고 읽다 보면 좀 더 공부가 잘 되겠지, 하는 생각으로.

그런데 기본적으로 워낙 사용법이 간단하다 보니, 이 녀석을 쓰는 법을 익히는 데 꼭 번역이 필요했던 것은 아닌 것 같다.


뭐 어떻든.. 

기껏 번역을 했으니 좀 더 많은 사람들이 봤으면 하는 바람으로 번역본을 공개~!

전문 번역가도 아니고, 영어에 탁월한 재능이 있기는 커녕~ 이므로..

오역과 의역이 넘나 들 것이다.


그래도 자습서는 꽤 볼 만 할 것이라 자평한다. (응?)

저작자 표시 비영리 변경 금지
신고
Posted by Kunner

댓글을 달아 주세요

  1. kkanding

    와 이걸 번역해주시다니 정말감사합니다! 잘보겠습니다!

    2014.04.02 10:36 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. 멋진인생

    번역 감사합니다 ^^

    2014.04.10 10:24 신고 [ ADDR : EDIT/ DEL : REPLY ]
  3. 감사드립니다^^; 큰절 드리고 싶네요 ㅠ

    2015.03.14 17:27 신고 [ ADDR : EDIT/ DEL : REPLY ]
  4. 아직 열어보진 않았는데 먼저 감사인사드리고 싶습니다.^^ 저 또한 Thymeleaf의 효용에 의문점을 가지고 있긴 한데, 아직 배움과 경험이 많이 부족한 듯 합니다. 여튼 잘보겠습니다!

    2015.04.01 11:21 신고 [ ADDR : EDIT/ DEL : REPLY ]
  5. 유상훈

    번역 해주셔서 감사합니다~ㅎ

    2015.04.02 09:40 신고 [ ADDR : EDIT/ DEL : REPLY ]
  6. mazdah

    감사합니다. 유용하게 사용하도록 하겠습니다.

    2015.04.13 16:22 신고 [ ADDR : EDIT/ DEL : REPLY ]
  7. 유상훈

    안녕하세요 혹시 타임 리프 사용하시나요??

    제 메일로 답변 주세요 ㅎ

    hue@hellomarket.com 이에요~

    2015.04.17 11:30 신고 [ ADDR : EDIT/ DEL : REPLY ]
  8. jooni06

    진짜 감사합니다^^

    2015.11.06 16:30 신고 [ ADDR : EDIT/ DEL : REPLY ]
  9. 이진욱

    너무 감사합니다. 잘 보겠습니다~ ^^

    2017.04.01 19:08 신고 [ ADDR : EDIT/ DEL : REPLY ]
  10. 로미

    번역 감사합니다 ㅠㅠ~!!! 너무나 필요했던 자료예요~!!!ㅠㅠㅠ

    2017.07.14 11:04 신고 [ ADDR : EDIT/ DEL : REPLY ]

프로그램을 개발할 때 테스트가 얼마나 중요한지에 대해서는 말해봐야 입만 아프다.
하지만 테스트가 얼마나 중요한지 아는 것과, 테스트를 실제로 수행하는 것과는 약간의 차이가 있다.
프로젝트를 진행할 때 당장 코드 써내려가기만도 바빠 죽겠는데 테스트까지 면밀하게 하기가 여간 어렵지 않기 때문이다.

통상적으로 웹프로그램 테스트를 한다고 하면 WEB UI위에 올려 놓고 하는 경우가 많다.
하지만 이는 클래스나 모듈에 대한 단위테스트로는 매우 부적절하다.
프로그램이 오류가 났을 때 이게 지금 개발한 클래스나 모듈의 문제인지, 브라우저의 문제인지, 서버의 문제인지 기타 다른 부분의 문제인지 알기가 쉽지 않기 때문이다.

따라서 작성코드에 대한 단위테스트는 WEB UI가 아닌 실행 가능한 자바 클래스 자체에서 수행해야 한다.
또 기존 코드와 구분하기 위해 별도의 클래스를 만들어서 진행하는 것이 좋다.
DB의 입출력 테스트라면, 개발된 클래스로 입력과 출력을 테스트해 보고 제대로 수행이 됐는지 알아 보는 식이다.
이러한 테스트를 각각 void main() 메소드를 이용해 진행할 수도 있겠지만 프로그램 규모가 커질 수록, 테스트할 대상이 많아질 수록 개별적으로 테스트 하는 것은 매우 어려운 일이다.
따라서 테스트를 할 때는 테스트 자동화 도구를 이용하는 것이 좋다.

대표적인 테스트 자동화 도구에는 JUnit 이 있다.
테스트 자동화 도구 JUnit을 이용할 때의 장점은 아래와 같다.

1. 테스트의 수행과 결과 확인이 용이하다.
2. 테스트를 위한 자원의 할당과 반환이 효율적이다.
3. 다수의 테스트에서 동일한 명령을 수행해야 할 경우, 해당 명령을 매번 복기하지 않고 미리 정의해 둔 것으로 재사용할 수 있다.


아래는 JUnit을 이용해 Spring 프레임워크에서 ApplicationContext가 하나만 만들어져서 재사용되는지 확인해보는 테스트이다.

package springbook.learningtest.junit;

더보기


@RunWith(SpringJUnit4ClassRunner.class)        //테스트 중 함께 수행할 class 파일이다.
@ContextConfiguration("junit.xml")         //ApplicationContext를 지정해 줄 수 있다.

public class JUnitTest {
        @Autowired ApplicationContext context;        //Autowired 명령을 통해 자동으로 할당한다.

        static Set<JUnitTest> testObjects = new HashSet<JUnitTest>();
        static ApplicationContext contextObject = null;        //위에서 Autowired 된 context 와 비교를 위한 임시 변수

        @Test public void test1() {        //@Test Annotation을 삽입하면 JUnit에서 해당 메소드를 테스트 단위로 인식한다.
                assertThat(testObjects, not(hasItem(this)));        //assertThat()의 두 인수가 서로 같지 않으면 false를 반환한다.
                testObjects.add(this);
  
                assertThat(contextObject == null || contextObject == this.context, is(true));        //둘 중 어떤 것이라도 성립하면 true
                contextObject = this.context;
        }

        @Test public void test2() {
                assertThat(testObjects, not(hasItem(this)));
                testObjects.add(this);
  
                assertTrue(contextObject == null || contextObject == this.context);        //해당 조건이 맞으면 true, 아니면 fasle
                contextObject = this.context;
        }

       @Test public void test3() {
                assertThat(testObjects, not(hasItem(this)));
                testObjects.add(this);
  
                assertThat(contextObject, either(is(nullValue())).or(is(this.contextObject)));        //either(().or())는 둘 중 어떤 것을 만족해도 true
                contextObject = this.context;
        }

}


JUnit을 이용한 테스트든, 전통적인 방식의 WEB UI를 이용한 테스트든..
테스트의 중요성은 따로 말할 필요가 없다.

더 나아가 개발이 잘 됐는지 확인하기 위한 테스트로서가 아니라 TDD(Test Driven Development)로서의 테스트로까지 테스트의 역할을 확장할 필요가 있다.
TDD에 대해서는 따로 언급하지 않는다.




저작자 표시 비영리 변경 금지
신고
Posted by Kunner

댓글을 달아 주세요

클래스간에 의존관계를 주입하는 방법에 대해서 설명하고 있다.

클래스 모델이나 코드에서 각각의 클래스들간의 관계를 직접 지정하게 되면, 향후 클래스나 코드의 변경이 일어날 때 마다 관련된 모든 코드를 손봐야 한다.
이는 소프트웨어 개발 시 높은 응집도와 낮은 결합도를 고려해야 한다는 원칙에 위배된다.
따라서 클래스를 개발 할 때 IoC(Inversion of Control)과 DI(Dependency Injection)을 고려해 개발한다.

사실 뭐 이 정도는 그리 대단한 내용이 아니다.
스프링 아니어도 기존에 개발할 때 마다 늘 하던 일이기도 하다.(xml이나 배열등의 노가다로)
하지만 스프링을 쓰면 이런 작업들을 하나하나 수동으로 하는 대신, 스프링의 특정 기술을 쓰면 된다.
거기에 더해, 싱글톤 레지스트리를 자동으로 구현해 주는 덕분에 서버 자원 관리에 이점이 있다.(한번 로드 된 ApplicationContext는 계속 재사용된다.)


스프링에서 DI를 구현하는 방법은 여러가지가 있지만, 그 중에 가장 많이 사용 되는 것은 역시 XML을 이용한 방식이다.
XML의 샘플은 아래와 같다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <bean id="dataSource" class="org.spring.jdbc.datasource.SimpleDriverDataSource">
                <property name="driverClass" value="com.mysql.jdbc.Driver">        //JDBC로 사용할 클래스 이름
                <property name="url" value="jdbc:mysql://localhost/springbook">        //DB 연결 url 
                <property name="username" value="spring">        //DB 사용자 이름
                <property name="password" value="book">        //DB 사용자 비밀번호
        </bean>
        <bean id="userDao" class="springbook.user.dao.UserDao">        //프로그램 전체에서 불러 쓸 수 있다. id에는 중복값이 올 수 없다.
                <property name="dataSource" ref="dataSource">        //다른 빈과의 관계를 주입할 수 있다. (붉은 색으로 표시된 부분)
        </bean>
</beans>


그리고 각 클래스에서 이러한 의존성을 인식하게 하기 위해 아래의 라인을 추가한다.

ApplicationContext context= new GenericXmlApplicationContext("applicationContext.xml");        //xml의 경로는 클래스 root를 기준으로 한다.

만약 root에서부터 xml 파일의 경로를 찾기가 번거로운 경우 다음과 같은 방법을 사용해도 된다.

ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml","UserDao.class");        //UserDao.class 와 같은 경로라는 뜻


이렇게 하면 각 클래스 파일간의 의존성 관계를 스프링이 제어하도록 할 수 있다.



저작자 표시 비영리 변경 금지
신고
Posted by Kunner

댓글을 달아 주세요

  1. 정진철

    <property name="url" value="jdbc:mysql://localhost/springbook"> //JDBC JAR파일의 경로
    jar파일 경로가 아니라 DB url 아닌가요

    2011.11.08 15:45 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 네 말씀하신게 맞습니다.
      보통 써놓고 다시 안 읽어 보다보니.. 말씀하시기 전엔 미처 몰랐네요.
      고쳐 놓겠습니다. 감사합니다. ^^

      2011.11.08 20:28 신고 [ ADDR : EDIT/ DEL ]