<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>소내기의 겸손한 지식</title>
	<atom:link href="http://sonegy.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://sonegy.wordpress.com</link>
	<description>Just another WordPress.com site</description>
	<lastBuildDate>Sat, 18 Feb 2012 05:31:01 +0000</lastBuildDate>
	<language>ko</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='sonegy.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>소내기의 겸손한 지식</title>
		<link>http://sonegy.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://sonegy.wordpress.com/osd.xml" title="소내기의 겸손한 지식" />
	<atom:link rel='hub' href='http://sonegy.wordpress.com/?pushpress=hub'/>
		<item>
		<title>JCO 지속적인 개발,빌드 배포(박재성)</title>
		<link>http://sonegy.wordpress.com/2012/02/18/jco-%ec%a7%80%ec%86%8d%ec%a0%81%ec%9d%b8-%ea%b0%9c%eb%b0%9c%eb%b9%8c%eb%93%9c-%eb%b0%b0%ed%8f%ac%eb%b0%95%ec%9e%ac%ec%84%b1/</link>
		<comments>http://sonegy.wordpress.com/2012/02/18/jco-%ec%a7%80%ec%86%8d%ec%a0%81%ec%9d%b8-%ea%b0%9c%eb%b0%9c%eb%b9%8c%eb%93%9c-%eb%b0%b0%ed%8f%ac%eb%b0%95%ec%9e%ac%ec%84%b1/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 05:31:01 +0000</pubDate>
		<dc:creator>sonegy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[jco]]></category>

		<guid isPermaLink="false">http://sonegy.wordpress.com/?p=75</guid>
		<description><![CDATA[삽질 좀 줄이며 살자. 프로젝트를 성공하기.. 가장중요한것? 사람 진부하지만 가장핵심적인열할 단순반복적인 일이 항상 존재한다. 서버셋팅 중복 코드 빌드 테스트 배포 단순반복적인-&#62; 컴퓨터가 할수 있는일 그렇지만 사람도 할수 있어 자꾸 하게된다. 단순반복에 시간할애를 하지 않아 결국 방치된다. 프로젝트 후 단순반복적인 일이 점점 커지게 되는데&#8230;&#8230; 프로젝트7일후 Jira,Subversion,db,eclipse,tomcat,java,maven&#8230;&#8230; 프로젝트18일후 소스는 바꾸지 않았지만, 동작하던게 동작하지 않는다. 왜? Database schema, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=75&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>삽질 좀 줄이며 살자.</p>
<p><del>프로젝트를 성공하기.. 가장중요한것?</del><br />
<del> 사람</del><br />
<del> 진부하지만 가장핵심적인열할</del></p>
<p>단순반복적인 일이 항상 존재한다.</p>
<ol>
<li>서버셋팅</li>
<li>중복 코드</li>
<li>빌드</li>
<li>테스트</li>
<li>배포</li>
</ol>
<p>단순반복적인-&gt; 컴퓨터가 할수 있는일<br />
그렇지만 사람도 할수 있어 자꾸 하게된다.</p>
<p>단순반복에 시간할애를 하지 않아 결국 방치된다.</p>
<p>프로젝트 후 단순반복적인 일이 점점 커지게 되는데&#8230;&#8230;</p>
<hr />
<h3>프로젝트7일후</h3>
<p>Jira,Subversion,db,eclipse,tomcat,java,maven&#8230;&#8230;</p>
<h3>프로젝트18일후</h3>
<p>소스는 바꾸지 않았지만, 동작하던게 동작하지 않는다.<br />
왜? Database schema, data에 문제가 발생!<br />
이후<br />
개발자PC에도 db를 따로 세팅한다.</p>
<h3>프로젝트20잃후</h3>
<p>개발서버배포<br />
svn,mvn,tomcat etc&#8230; 스크립트 생성</p>
<h3>프로젝트25일후</h3>
<p>다시 소스는 변환이 없지만, 그래도 애러!<br />
왜? sql schema가 merge가 되지 않았다.<br />
orm인경우<br />
schema싱크가 쉽다. 이러면 욕먹나?<br />
orm이 아닌경우<br />
maven carbon five plugin사용<br />
개발단계에서 schme배포를 훈련을 할수 있어 실서버에서도 그대로 적용할수 있다. 어차피 해야되는일 개발단계에서도 하도록 하여 DB도 형상관리에 도움을 받아보자.</p>
<h3>프로젝트35일</h3>
<p>30%이상 깨진 단위테스트가 되었다.<br />
mvn에서 test를 강제한다.</p>
<h3>프로젝트45일후</h3>
<p>테스트는 잘되었지만, 갯수가 점점 줄어들고 있다.<br />
@Ignoe!!!!!! 이 사용되고 있다.<br />
테스트의 길은 길다.<br />
지속적 통합툴(젠킨스)! commit후 test확인을 강제한다.</p>
<h3>프로젝트50일후</h3>
<p>수정작업이 많아짐<br />
UI개발자 에게 실플한 개발환경<br />
개발하기 쉬운 설치환경을 만들어주자.<br />
많은 개발자가 투입되더라도 쉽게 확장할수 있다.</p>
<blockquote><p>이슈<br />
개발자PC별, 개발서버의 데이터베이스 설정이 다르다.<br />
로그레벨과 같이 각 배포 서버에 따라 다른 설정이 필요하다.<br />
mvn resource마다 구분을 둘수 있다.</p></blockquote>
<p>네이버메인에 고정광고가 걸림<br />
VM을 이용한 웹서버 확장!<br />
Capistrano를 이용한 vm서버에 배포!<br />
DB확장</p>
<blockquote><p>이슈<br />
서비스를 운영하면서 대규모로 기능 추가를 해야한다.<br />
branch마다 개발서버환경이 필요하다. VM을 두어 branch마다 적용을 해두자. 그렇지만 full stack아닌 필요한 부분만.</p></blockquote>
<p>마치머<br />
쉽지않지만, 결국 수작업으로 반복적인 일을 하게 된다. 이전에 선도적으로 대응이 필요하다는게 생각임. 도입을 하게 되면 사이드 이페트가 생기기 마련이지만, 해결가능한 다른 방법이 있다. 문제인식이 있다면 개선을 해야된다. 이런 습관을 들여보자. 그렇게 되어 작은 성공을 이루어 보자.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sonegy.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sonegy.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sonegy.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sonegy.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sonegy.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sonegy.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sonegy.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sonegy.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sonegy.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sonegy.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sonegy.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sonegy.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sonegy.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sonegy.wordpress.com/75/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=75&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sonegy.wordpress.com/2012/02/18/jco-%ec%a7%80%ec%86%8d%ec%a0%81%ec%9d%b8-%ea%b0%9c%eb%b0%9c%eb%b9%8c%eb%93%9c-%eb%b0%b0%ed%8f%ac%eb%b0%95%ec%9e%ac%ec%84%b1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5d5f4f2f669a194ad95a8650d9d5d22f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sonegy</media:title>
		</media:content>
	</item>
		<item>
		<title>StringTemplate 4.0 소개</title>
		<link>http://sonegy.wordpress.com/2012/02/08/stringtemplate-4-0-%ec%86%8c%ea%b0%9c/</link>
		<comments>http://sonegy.wordpress.com/2012/02/08/stringtemplate-4-0-%ec%86%8c%ea%b0%9c/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 07:09:53 +0000</pubDate>
		<dc:creator>sonegy</dc:creator>
				<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://sonegy.wordpress.com/?p=35</guid>
		<description><![CDATA[Spring이 아닌 String이다!. http://www.stringtemplate.org/ 에서 글어온 내용이다. What is StringTemplate? StringTemplate is a java template engine (with ports for C#, Python, Ruby, and Scala) for generating source code, web pages, emails, or any other formatted text output. StringTemplate is particularly good at multi-targeted code generators, multiple site skins, and internationalization/localization. It evolved over years of effort [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=35&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Spring이 아닌 String이다!.</p>
<p><a href="http://www.stringtemplate.org/">http://www.stringtemplate.org/</a> 에서 글어온 내용이다.</p>
<blockquote><p><strong>What is StringTemplate?</strong><br />
<strong>StringTemplate</strong> is a java template engine (with ports for C#, Python, Ruby, and Scala) for generating source code, web pages, emails, or any other formatted text output. StringTemplate is particularly good at multi-targeted code generators, multiple site skins, and internationalization/localization. It evolved over years of effort developing <a href="http://www.jguru.com/"><strong>jGuru.com</strong></a>. StringTemplate also generates this website and powers the <a href="http://www.antlr.org/"><strong>ANTLR v3</strong></a> code generator. See the <a href="http://www.antlr.org/wiki/display/ST/Five+minute+Introduction"><strong>Five minute introduction</strong></a>.</p></blockquote>
<p>얼마전부터 메일템플릿을 구성할때 쓰던 템플릿프레임웍인데, 3.0에서 4.0으로 판올림이 되었다. 메이저 버젼을 업했다고 새로운 기능은 클래스 이름이 바꿔버렸다. <a href="http://www.ksug.org/105">http://www.ksug.org/105</a> 이건 예전에 소개했던 자료인데, 코드도 바꼈네. Spring이라면 일어나지 말아야 하는 일이 일어났어!!!</p>
<p>Maven에 이렇게 넣어주시고</p>
<p><pre class="brush: xml;">
		&lt;dependency&gt;
			&lt;groupId&gt;org.antlr&lt;/groupId&gt;
			&lt;artifactId&gt;ST4&lt;/artifactId&gt;
			&lt;version&gt;4.0.4&lt;/version&gt;
		&lt;/dependency&gt;
</pre></p>
<hr />
<p>템플릿파일은 .stg이다 StringTemplateGroup이라는 소리맞다. 친절하게 확장자 검사도 하시고, 단순 시스템파일리소스를 찾다가 없으면 classpath를 뒤지게 된다. Maven이라면 src/main/resources에 잘 넣어두면 된다는거겠지.</p>
<p><pre class="brush: xml;">
		STGroup group = new STGroupFile(&quot;string_template_example.stg&quot;);
</pre></p>
<hr />
string_template_example.stg 은 Template을 Group방식으로 넣어줬다. page함수만 선언 되어 있지만 다른 함수를 추가할 수 있고, 게다가 서로 호출할수도 있다. 템플릿 변환을 위해 delimiterStartChar 와 delimiterStopChar를 줄수 있는데 기본값은 &#8221;다 html이 주 용도라서 &#8216;$,&#8217;$'릴 이용했다.<br />
<pre class="brush: xml;">
delimiters &quot;$&quot;, &quot;$&quot;
page(person,messageList,toLink) ::= &lt;&lt;
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div&gt;
		$person.name$가 $person.email$의 이메일 $person.startDate;format=&quot;yyyy-MM-dd HH:mm:ss&quot;$ 시작시간
	&lt;/div&gt;
	&lt;p&gt;
		&lt;table&gt;
		&lt;tbody&gt;
			$messageList:{it |		
			&lt;tr&gt;
				&lt;td&gt;$it.title$&lt;/td&gt;
				&lt;td&gt;$it.sendDate;format=&quot;yyyy-MM-dd HH:mm:ss&quot;$&lt;/td&gt;
			&lt;/tr&gt;
			};separator=&quot;\n&quot;$
			
			$if(!messageList)$
				 없음
			$endif$
		&lt;/tbody&gt;
		&lt;/table&gt;
		
		&lt;a href=&quot;$toLink;format=&quot;xml-encode&quot;$&quot;&gt;링크&lt;/a&gt;
	&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
&gt;&gt;
</pre></p>
<hr />
템플릿을 rendering할때 타입별로 render를 추가 할수 있다. 4.0에서는 디폴트 Renderer를 제공을 해준다. 기호에 맞게 고쳐서 써줄수도 있다.</p>
<p><pre class="brush: java;">
		group.registerRenderer(Date.class, new DateRenderer());
		group.registerRenderer(String.class, new StringRenderer());
</pre></p>
<p>AttributeRenderer.java</p>
<p><pre class="brush: java;">
......
    public String toString(Object o, String formatString, Locale locale)
......
</pre></p>
<hr />
인터페이스를 살펴보니 format과 locale을 받는다. stg파일에서 &#8220;;&#8221;을 구분자로 지정하면 지정한데로 output foramt을 맞출수 있다는걸 알수 있다.</p>
<p>toLink라는 변수는 format을 xml-encode타입으로 지정한다는 의미이다. toLink는 String이고 xml-encode는 html escape하겠다는 의미이다. 참고로 render의 파라미터는 &#8220;;&#8221;을 구분자로 이용한다.</p>
<p><pre class="brush: xml;">
		&lt;a href=&quot;$toLink;format=&quot;&gt;링크&lt;/a&gt;
</pre></p>
<p>messageList는 Collection이다. :{}로 이작하는 부분은 StringTemplate에서 정의한 Inline Function기능을 표한하는 식이다. &#8220;:{it|&#8230;&#8230;}&#8221; for(Item it : messageList) 라는 java표현식이라고 여기면 된다. &#8220;:&#8221;는 함수 호출의 의미로 쓰이기 때문에 inline function을 이름을 주어 호출할 수 있다.</p>
<p><pre class="brush: xml;">
			$messageList:{it |		
			&lt;tr&gt;
				&lt;td&gt;$it.title$&lt;/td&gt;
				&lt;td&gt;$it.sendDate;format=&quot;yyyy-MM-dd HH:mm:ss&quot;$&lt;/td&gt;
			&lt;/tr&gt;
			};separator=&quot;\n&quot;$
</pre></p>
<p><span id="more-35"></span></p>
<hr />
위의 내용을 나열한 테스트 코드다.<br />
<pre class="brush: java;">
		Person person = new Person();
		person.setName(&quot;이재일&quot;);
		person.setEmail(&quot;sonegy@nhn.com&quot;);
		Calendar prevCal = GregorianCalendar.getInstance();
		prevCal.add(GregorianCalendar.DAY_OF_YEAR, -1);
		person.setStartDate(prevCal.getTime());
		person.setEndDate(GregorianCalendar.getInstance().getTime());
		
		List messageList = new ArrayList();
		messageList.add(new Message(&quot;test1&quot;, GregorianCalendar.getInstance().getTime()));
		messageList.add(new Message(&quot;test2&quot;, GregorianCalendar.getInstance().getTime()));
		messageList.add(new Message(&quot;test3&quot;, GregorianCalendar.getInstance().getTime()));
		messageList.add(new Message(&quot;test4&quot;, GregorianCalendar.getInstance().getTime()));
		messageList.add(new Message(&quot;test5&quot;, GregorianCalendar.getInstance().getTime()));
		
		STGroup group = new STGroupFile(&quot;string_template_example.stg&quot;);
		group.registerRenderer(Date.class, new DateRenderer());
		group.registerRenderer(String.class, new StringRenderer());
		ST stPage = group.getInstanceOf(&quot;page&quot;);
		stPage.add(&quot;person&quot;, person);
		stPage.add(&quot;messageList&quot;, messageList);
		stPage.add(&quot;toLink&quot;, &quot;http:/xxxxxxxxx&quot;);
		
		logger.info(&quot;string template:{}&quot;, stPage.render());
</pre></p>
<p>ST stPage = group.getInstanceOf(&#8220;page&#8221;);에서 적절한 page 인스턴스를 꺼내서 .stg파일에 선언한데로 page에 arguments를 넣어주고 stPage.render()하면 끝이다!</p>
<p><pre class="brush: java;">
		ST instance = new ST(templateGroup, templateText);
</pre><br />
templateGroup에 어려가지 function을 선언해두고 templateText에 적절한 template내용을 넣어두고 render를 해두면 다양하게 사용할수 있다.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sonegy.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sonegy.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sonegy.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sonegy.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sonegy.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sonegy.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sonegy.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sonegy.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sonegy.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sonegy.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sonegy.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sonegy.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sonegy.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sonegy.wordpress.com/35/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=35&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sonegy.wordpress.com/2012/02/08/stringtemplate-4-0-%ec%86%8c%ea%b0%9c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5d5f4f2f669a194ad95a8650d9d5d22f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sonegy</media:title>
		</media:content>
	</item>
		<item>
		<title>Spring 3.1과 ehcache</title>
		<link>http://sonegy.wordpress.com/2011/12/29/spring-3-1%ea%b3%bc-ehcache/</link>
		<comments>http://sonegy.wordpress.com/2011/12/29/spring-3-1%ea%b3%bc-ehcache/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 01:11:04 +0000</pubDate>
		<dc:creator>sonegy</dc:creator>
				<category><![CDATA[ehcache]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[cache]]></category>

		<guid isPermaLink="false">http://sonegy.wordpress.com/?p=28</guid>
		<description><![CDATA[현재 프로젝트는 Spring 3.0.5에 iBatis 캐쉬를 켜서 쓰고 있다.누구도 iBatis에 내장 되어 있는 캐쉬 모델은 추천을 하지도 않고, 게다가 개발PC에서 올리고 한참후 지나면 vm이 멈추는 기현상이 발생이 되긴 하지만, 운영서버와, 개발서버는 아무 이상이 없다. 맥이 잠자기 모드에 들어갈때 먼가 문제가 생기는 모양이다. 여하튼 보이지 않는 위협이 도사리고 있다는 말씀. ibatis에서만 쓸수 있는 케쉬이기도 하고, 이것은 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=28&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>현재 프로젝트는 Spring 3.0.5에 iBatis 캐쉬를 켜서 쓰고 있다.누구도 iBatis에 내장 되어 있는 캐쉬 모델은 추천을 하지도 않고, 게다가 개발PC에서 올리고 한참후 지나면 vm이 멈추는 기현상이 발생이 되긴 하지만, 운영서버와, 개발서버는 아무 이상이 없다. 맥이 잠자기 모드에 들어갈때 먼가 문제가 생기는 모양이다. 여하튼 보이지 않는 위협이 도사리고 있다는 말씀.</p>
<p>ibatis에서만 쓸수 있는 케쉬이기도 하고, 이것은 화면 캐쉬도 할수 있고 전방위적으로 쓸 수 있는 ehcache를 서보기로 했다. 어차피 부하가 걸린 서버도 아니고, 반복적인 DB호출이 있는 부분만 살짝 짧게 캐쉬를 줄예정이다.</p>
<p>참고 자료 : <a href="http://whiteship.me/?p=13271" rel="nofollow">스프링 3.1 Cache Abstraction</a></p>
<p>pom.xml</p>
<p><pre class="brush: xml;">
&lt;pre&gt;......
        &lt;spring-version&gt;3.1.0.RELEASE&lt;/spring-version&gt;
......
        &lt;dependency&gt;
            &lt;groupId&gt;net.sf.ehcache&lt;/groupId&gt;
            &lt;artifactId&gt;ehcache-core&lt;/artifactId&gt;
            &lt;version&gt;2.5.0&lt;/version&gt;
        &lt;/dependency&gt;
.......
</pre></p>
<p>maven설정에서 spring 3.1.0으로 올리고 ehcahce-core를 추가했다. ehcache를 추가하면 Terracotta캐쉬 서버까지 같이 딸려온다. READ만 하는 경우면 OK라서 core만 가져왔다.</p>
<p>applicationContext-cache.xml</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:cache=&quot;http://www.springframework.org/schema/cache&quot;
    xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/cache &gt;

    &lt;cache:annotation-driven cache-manager=&quot;cacheManager&quot; /&gt;
    &lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.ehcache.EhCacheCacheManager&quot;&gt;
        &lt;property name=&quot;cacheManager&quot;&gt;
            &lt;bean class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot;&gt;
                &lt;property name=&quot;configLocation&quot; value=&quot;classpath:ehcache.xml&quot;&gt;&lt;/property&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</pre></p>
<p>spring 3.1에서 cache추상화를 시켜서 ehcache만 bean으로 등록하면 된다.</p>
<p>ehcache.xml</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ehcache xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:noNamespaceSchemaLocation=&quot;http://ehcache.org/ehcache.xsd&quot; updateCheck=&quot;false&quot;&gt;
    &lt;diskStore path=&quot;java.io.tmpdir&quot; /&gt;

    &lt;defaultCache
        maxElementsInMemory=&quot;50000&quot;
        eternal=&quot;false&quot;
        timeToIdleSeconds=&quot;300&quot;
        timeToLiveSeconds=&quot;600&quot;
        overflowToDisk=&quot;false&quot;
        diskPersistent=&quot;false&quot;
        diskExpiryThreadIntervalSeconds=&quot;120&quot;
        memoryStoreEvictionPolicy=&quot;LRU&quot;&gt;
    &lt;/defaultCache&gt;
    &lt;cache name=&quot;storedEmp&quot;
        maxElementsInMemory=&quot;10000&quot;
        eternal=&quot;false&quot;
        timeToIdleSeconds=&quot;0&quot;
        timeToLiveSeconds=&quot;600&quot;
        overflowToDisk=&quot;false&quot;
        diskPersistent=&quot;false&quot;
        diskExpiryThreadIntervalSeconds=&quot;120&quot;
        memoryStoreEvictionPolicy=&quot;LRU&quot;&gt;
    &lt;/cache&gt;
    &lt;cache name=&quot;involvedAccessGroup&quot;
        maxElementsInMemory=&quot;10000&quot;
        eternal=&quot;false&quot;
        timeToIdleSeconds=&quot;0&quot;
        timeToLiveSeconds=&quot;60&quot;
        overflowToDisk=&quot;false&quot;
        diskPersistent=&quot;false&quot;
        diskExpiryThreadIntervalSeconds=&quot;120&quot;
        memoryStoreEvictionPolicy=&quot;LRU&quot;&gt;
    &lt;/cache&gt;
&lt;/ehcache&gt;
</pre></p>
<p>용어 설명<br />
timeToIdleSeconds 몇초간 유휴상태가 지나면 캐쉬를 갱신한다. 0이면 사용하지 않음<br />
timeToLiveSeconds 설정한 초까지 캐쉬를 살린다. 0이면 무한!</p>
<p>캐쉬를 디스크에 쓰지 않으려고 overflowToDisk와 diskPersistent는 꺼버렸다.<br />
그리 많은 캐쉬가 필요한 시스템이 아님.</p>
<p><pre class="brush: xml;">
......
    &lt;import resource=&quot;applicationContext-cache.xml&quot; /&gt;
......
</pre></p>
<p>마지막으로 applicationContext에 import!</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE sqlMapConfig PUBLIC &quot;-//ibatis.apache.org//DTD SQL Map Config 2.0//EN&quot;
        &quot;http://ibatis.apache.org/dtd/sql-map-config-2.dtd&quot;&gt;
&lt;sqlMapConfig&gt;
    &lt;settings useStatementNamespaces=&quot;true&quot; cacheModelsEnabled=&quot;false&quot; classInfoCacheEnabled=&quot;false&quot;/&gt;
......
</pre></p>
<p>기존 ibatis캐쉬는 쓰지 않는다.</p>
<p>이제 @Cacheable, @CacheEvict를 이용해 키쉬를 설정하면 된다.</p>
<p><pre class="brush: java;">
......
    @Transactional(readOnly = true)
    @Cacheable(value=&quot;storedEmp&quot;)
    public Emp getEmpBy(String empNo) {
        Emp paramEmp = new Emp();
        paramEmp.setEmpNo(empNo);
        return empRepository.getEmpBy(paramEmp);
    }

    @Transactional(readOnly = true)
    @Cacheable(value=&quot;involvedAccessGroup&quot;)
    public boolean isInvolvedAccessGroup(String empNo) {
        boolean involvedAccessGroup = empRepository.isInvolvedAccessGroup(empNo);

        if (!involvedAccessGroup) {
            Emp paramEmp = new Emp();
            paramEmp.setEmpNo(empNo);
            Emp emp = empRepository.getEmpBy(paramEmp);

            List&lt;String&gt; exceptionAccessGroup = empRepository.getExceptionAccessGroup();
            involvedAccessGroup = exceptionAccessGroup.contains(emp.getDeptCd());
        }
        return involvedAccessGroup;
    }
......
</pre></p>
<p>@Cacheable에서 value값은 ehcache의 cache이름이다. ibatis캐쉬에서는 캐쉬모델을 하나만 잡아두면 여려종류의 select에서 쓸수 있었지만, 이건 cache마다 큰 Map이라고 보면 된다. storedEmp를 다른곳에서 쓰게 된다면 parameter key마다 같은 캐쉬결과를 리턴한다.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sonegy.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sonegy.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sonegy.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sonegy.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sonegy.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sonegy.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sonegy.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sonegy.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sonegy.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sonegy.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sonegy.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sonegy.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sonegy.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sonegy.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=28&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sonegy.wordpress.com/2011/12/29/spring-3-1%ea%b3%bc-ehcache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5d5f4f2f669a194ad95a8650d9d5d22f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sonegy</media:title>
		</media:content>
	</item>
		<item>
		<title>SpringBatch에서 CompositeItemWriter활용</title>
		<link>http://sonegy.wordpress.com/2011/12/28/springbatch%ec%97%90%ec%84%9c-compositeitemwriter%ed%99%9c%ec%9a%a9/</link>
		<comments>http://sonegy.wordpress.com/2011/12/28/springbatch%ec%97%90%ec%84%9c-compositeitemwriter%ed%99%9c%ec%9a%a9/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 14:30:10 +0000</pubDate>
		<dc:creator>sonegy</dc:creator>
				<category><![CDATA[spring]]></category>
		<category><![CDATA[springbatch]]></category>

		<guid isPermaLink="false">http://sonegy.wordpress.com/?p=22</guid>
		<description><![CDATA[Chapter 6. ItemReaders and ItemWriters 스프링 배치 래퍼런스 문서에 간단한 소개가 있다. write메소드만 적절히 잘 굴러갈수 있지만, 특정 Writer중 문제가 생긴다. 파일을 써야할때는 별도의 파일에 대한 open, close에 대한 전후 처리 기능이 필요한데, 그냥 위와 같은 간단히 구현하면 Exception을 내고 장렬히 산화 한다. 파일처리를 하는 Writer를 살펴보면 &#160; FlatFileItemWriter는 ItemWriter말고 ItemStream을 구현해 놓고 파일처리를 추상화 했다. 결국 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=22&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2><a href="http://static.springsource.org/spring-batch/reference/html/readersAndWriters.html">Chapter 6. ItemReaders and ItemWriters</a></h2>
<p>스프링 배치 래퍼런스 문서에 간단한 소개가 있다. write메소드만 적절히 잘 굴러갈수 있지만, 특정 Writer중 문제가 생긴다. 파일을 써야할때는 별도의 파일에 대한 open, close에 대한 전후 처리 기능이 필요한데, 그냥 위와 같은 간단히 구현하면 Exception을 내고 장렬히 산화 한다.</p>
<p>파일처리를 하는 Writer를 살펴보면</p>
<p><pre class="brush: java;">
public class FlatFileItemWriter&lt;T&gt; extends ExecutionContextUserSupport implements ResourceAwareItemWriterItemStream&lt;T&gt;,
        InitializingBean {
......
</pre></p>
<p>&nbsp;</p>
<p><pre class="brush: java;">
public interface ResourceAwareItemWriterItemStream&lt;T&gt; extends ItemStream, ItemWriter&lt;T&gt; {
    void setResource(Resource resource);
}
</pre><br />
<pre class="brush: java;">
public interface ItemStream {
 ......
}
</pre></p>
<p>FlatFileItemWriter는 ItemWriter말고 ItemStream을 구현해 놓고 파일처리를 추상화 했다. 결국 레퍼런스에 있던 CompositeItemWriter를 쓴다면 문제가 생긴다. SpringBatch는 배치처리를 하기 위한 충분한 인프라를 제공한다. 추상화가 잘되어 있음으로 ItemWriter건 ItemProcesor건 ItemReader건 추가적인 기능인경우는 인터페이스로 잘구현해 놓으면 적절한 행위를 할수 있게 되어 있다.</p>
<p><pre class="brush: java;">
public class CompositeItemWriter&lt;T&gt; implements ItemStreamWriter&lt;T&gt;, InitializingBean {
   ......
}
</pre></p>
<p>job안에 step에서 Stream타임의 Writer일때 별도의 처리를 해주는 기능을 쓰기 위해서는 Composite타입에서도 ItemStream가 올수 있음을 알려줘야 한다. 그래서 Batch에는 간단히 구현해 놓았다.</p>
<p><pre class="brush: xml;">
    &lt;bean id=&quot;sendAppToPushServerWrtier&quot; class=&quot;org.springframework.batch.item.support.CompositeItemWriter&quot;&gt;
        &lt;property name=&quot;delegates&quot;&gt;
            &lt;list&gt;
                &lt;bean class=&quot;com.nhncorp.ins.mnext.batch.http.HttpCallWriter&quot;&gt;
                    &lt;property name=&quot;delayTimemillis&quot; value=&quot;1000&quot;/&gt;
                    &lt;property name=&quot;callUrlFormat&quot;
                        value=&quot;http://xxx/xxxxx/xxxxx?xx=%22{}%22&quot; /&gt;
                &lt;/bean&gt;
                &lt;bean class=&quot;org.springframework.batch.item.file.FlatFileItemWriter&quot; scope=&quot;step&quot;&gt;
                    &lt;property name=&quot;resource&quot; value=&quot;#{jobParameters['smsListResultLoc']}&quot; /&gt;
                    &lt;property name=&quot;lineAggregator&quot;&gt;
                        &lt;bean class=&quot;org.springframework.batch.item.file.transform.DelimitedLineAggregator&quot;&gt;
                            &lt;property name=&quot;delimiter&quot; value=&quot;,&quot;&gt;&lt;/property&gt;
                            &lt;property name=&quot;fieldExtractor&quot;&gt;
                                &lt;bean class=&quot;org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor&quot;&gt;
                                    &lt;property name=&quot;names&quot; value=&quot;empNo,result&quot;&gt;&lt;/property&gt;
                                &lt;/bean&gt;
                            &lt;/property&gt;
                        &lt;/bean&gt;
                    &lt;/property&gt;
                &lt;/bean&gt;
            &lt;/list&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
</pre></p>
<p>위와 같은 CompositeItemWriter를 써보도록 하자. 이제 끝!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sonegy.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sonegy.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sonegy.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sonegy.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sonegy.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sonegy.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sonegy.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sonegy.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sonegy.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sonegy.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sonegy.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sonegy.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sonegy.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sonegy.wordpress.com/22/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=22&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sonegy.wordpress.com/2011/12/28/springbatch%ec%97%90%ec%84%9c-compositeitemwriter%ed%99%9c%ec%9a%a9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5d5f4f2f669a194ad95a8650d9d5d22f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sonegy</media:title>
		</media:content>
	</item>
		<item>
		<title>Hello world!</title>
		<link>http://sonegy.wordpress.com/2011/12/28/hello-world/</link>
		<comments>http://sonegy.wordpress.com/2011/12/28/hello-world/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 07:20:10 +0000</pubDate>
		<dc:creator>sonegy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://sonegy.wordpress.com/?p=1</guid>
		<description><![CDATA[Welcome to WordPress.com. After you read this, you should delete and write your own post, with a new title above. Or hit Add New on the left (of the admin dashboard) to start a fresh post. Here are some suggestions for your first post. You can find new ideas for what to blog about by [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=1&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Welcome to <a href="https://wordpress.com/">WordPress.com</a>. After you read this, you should delete and write your own post, with a new title above. Or hit <a title="Direct link to the Add New in the Admin Dashboard" href="/wp-admin/post-new.php">Add New</a> on the left (of the <a title="Direct link to this blog's admin dashboard" href="/wp-admin">admin dashboard</a>) to start a fresh post.</p>
<p><a title="Learn WordPress.com—From zero to hero." href="http://learn.wordpress.com/">Here</a> are some suggestions for your first post.</p>
<ol>
<li>You can find new ideas for what to blog about by reading <a title="The Daily Post at WordPress.com—post something every day" href="http://dailypost.wordpress.com/">the Daily Post</a>.</li>
<li>Add <a title="Click the &quot;Press This&quot; link on this page to activate the Press this bookmark feature." href="/wp-admin/tools.php">PressThis</a> to your browser. It creates a new blog post for you about any interesting  page you read on the web.</li>
<li><a title="Edit the first post on this blog." href="/wp-admin/post.php?post=1&amp;action=edit">Make some changes to this page</a>, and then hit preview on the right. You can always preview any post or edit it before you share it to the world.</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sonegy.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sonegy.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sonegy.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sonegy.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sonegy.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sonegy.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sonegy.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sonegy.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sonegy.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sonegy.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sonegy.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sonegy.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sonegy.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sonegy.wordpress.com/1/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sonegy.wordpress.com&amp;blog=30880696&amp;post=1&amp;subd=sonegy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sonegy.wordpress.com/2011/12/28/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5d5f4f2f669a194ad95a8650d9d5d22f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sonegy</media:title>
		</media:content>
	</item>
	</channel>
</rss>
