<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Archives-2016 on</title><link>https://taetaetae.github.io/tags/archives-2016/</link><description>Recent content in Archives-2016 on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sat, 31 Dec 2016 16:59:43 +0000</lastBuildDate><atom:link href="https://taetaetae.github.io/tags/archives-2016/index.xml" rel="self" type="application/rss+xml"/><item><title>2016 회고</title><link>https://taetaetae.github.io/2016/12/31/adieu-2016/</link><pubDate>Sat, 31 Dec 2016 16:59:43 +0000</pubDate><guid>https://taetaetae.github.io/2016/12/31/adieu-2016/</guid><description>&lt;p>2016년, 내겐 정말 수많은 일들이 있었고 그 어느때보다 (전역 후로) 미친듯이 회사에 집중했던 시간들로 기억난다. 무작정 다가오는 새해를 맞이하는것도 좋지만 올 한해를 되돌아보는 시간을 갖고, 나를 다시 점검해보는 차원에서 일명 &amp;lsquo;회고&amp;rsquo;를 해볼까 한다.&lt;/p>
&lt;!-- more -->
&lt;h2 id="회사">회사&lt;/h2>
&lt;p>정말 열심히 했다. 잘했는지는&amp;hellip; 잘 모르겠다. 난 잘한것 같다. 물론 내 하루중에 가장많은 시간을 쏟은것도 있지만 작년에 많이 하지 못하던것을 &amp;lsquo;날씨&amp;rsquo;라는 서비스를 홀로 맡으면서 정말 많은것을 배우고 결과물도 후회하지 않을만큼 나온것 같다. 지나고보면 구지 하지 않아도 월급은 똑같이 나올테고, 시키지도 않았는데 그시간에 잠을 더 잤으면 하는 생각도 들지만 후회하지 않는다. 아무도 없는 사무실 나혼자 12시넘어서 퇴근을 해도 즐거웠으니까, 그거면 됬다.
모바일 개편이라는 큰 업무를 무사히(?) 해쳐내고는 사내에서 조직(서비스)을 변경할수 있는 기회가 되어 나홀로 지원, 다행스럽게도 합격을 해서 지금은 네이버페이 와 관련된 일을 하고있는 중이다. 기존 서비스운영을 하면서 느끼지 못했던, 초기 설계부터 시작하여 어떤 기술스택을 쓸것인가에 대한 선택부터 다양한 시행착오를 통해 이제 한 두달 되었는데 정말 많이 배우고 있다. 너무 힘들지만 너무 행복하다.
돌이켜보면 작심삼일로 개발 관련된 공부를 등한시 한게 너무 후회가 된다. 바쁘다는 이유하나만으로 (솔직히 바쁘다는건 핑계다) 기능구현에만 신경을 써왔는데, 내년부터는 할수만 있다면 업무 외적으로 나만의 개발트리를 세워보고 싶다.&lt;/p>
&lt;h2 id="건강">건강&lt;/h2>
&lt;p>일주일에 한번 이상 오전엔 배드민턴, 저녁엔 헬스장엘 가려고 노력했다. 그 결과였을까, 사랑니 뺀거 말고는 병원을 단한번도 안갔다. 감기조차 걸리지 않는게 다행이라고 생각하지만, 요즘들어(야근이 많아져서인지) 책상에 앉아있는 자세가 불량해서 거북목이 되가고 있다. 폼롤러도 구비했고 어깨 펴지라고 밴드도 구입해서 사용은 하는데 잘 실천이 안되는 중이다.
작년에 자전거를 잃어버리다 되찾고는 자전거를 등한시 하게 되는것 같다. 이또한 핑계겠지. 내년엔 꼭 4대강중 하나 잡고 종주한번 해야겟다. 기필코.. 아맞다 수영도. ㅠㅠ 물에 뜨질 않으니 큰일이다&amp;hellip;&lt;/p>
&lt;h2 id="사람관계">사람관계&lt;/h2>
&lt;p>학교선후배동기 및 동아리 사람들, 군대 동기들 및 소대원들 과 선임 장교분들, 기타 등등&amp;hellip; 올해 들어서인지. 연락에 너무 무색할만큼 잊고 살았던것 같다. 지나고보면 다른곳에 신경쓴다고 연락을 못했다고 핑계를 대고 있는 나이지만, 또 한편으로는 그 연락 10분 시간이 없다는건 &amp;hellip; 역시나 핑계다. 나를 도와주고 나를 믿어주고 나를 생각해주는 사람들을 조금이라도 더 신경써서 연락하고 찾아 뵙는 시간을 내년부터서라도 가져야겠다.&lt;/p>
&lt;h2 id="마치며">마치며&lt;/h2>
&lt;p>일단 첫번째로 내년부터 할일은, 기술 블로그를 운영하는것이다. 솔직히 두달전 이 gitHub 를 이용해서 블로그를 만들긴 했지만 그닥 포스팅도 못했고 방치 수준이였으니&amp;hellip; 적어도 한달에 한두개 정도는 포스팅 해보려고 노력해야겟다. 글쓰는게 힘들고 시간이 많이 들어가는 작업이지만, 돌이켜 생각하면 다 내 자산이고 나를 다시 바라볼수 있는 기회니까. 꼭 기술블로그만이 아닌, 하루를 기록하는 무언가를 해야겠다. 막상 한해를 돌이켜보니 그때는 뭐했는지 기억도 안나네..
두번째로는 지킬수 있는 계획을 잡는것이다. 올 한해 목표중에 이룬건 10개중에 단 두개&amp;hellip; (그중에 노래대회나가기, 스쿠버다이빙 하기, 자유형 마스터하기도 있다;;) 부끄럽다..&lt;/p>
&lt;p>2016년, 나라도 뒤숭숭 하고 정신없던 한해였지만 나름 의미있던 시간들을 보낸것 같아 다행이라 생각한다.
음,. 10점만점에 8점??
2017년! 다시한번 일어서자! 화이팅!!&lt;/p></description></item><item><title>Spring Transaction 옵션</title><link>https://taetaetae.github.io/2016/10/08/20161008/</link><pubDate>Sat, 08 Oct 2016 18:04:19 +0000</pubDate><guid>https://taetaetae.github.io/2016/10/08/20161008/</guid><description>&lt;h3 id="상황">상황&lt;/h3>
&lt;p>스프링 환경에서 일반적으로 DAO 나 BO 레벨에서 다음과 같이 코딩을 하게 된다.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="nd">@Transactional&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">isolation&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Isolation&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">READ_COMMITTED&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">propagation&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Propagation&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">REQUIRED&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rollbackFor&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Exception&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">class&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">method&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">throws&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Exception&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sqlMapClient&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">delete&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;~~~~&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>무분별하게 Ctrl+C,V 신공으로 트랜잭션 어노테이션을 가져다가 사용할수도 있겠으나, 각 값들이 어떤 역활을 아는지에 대해 알고 넘어갈 필요성이 있다.&lt;/p>
&lt;h3 id="transactional">@Transactional&lt;/h3>
&lt;p>우선 해당 어노테이션을 적용하면 적용된 클래스 또는 메소드에 트랜잭션이 적용된다. 따라서 로직 흐름에 맞추어 전체적으로 트랜잭션을 적용할것인지, 아니면 특정 메소드에 적용할것인지 전략을 잘 세워야 한다.&lt;/p>
&lt;h3 id="isolation">isolation&lt;/h3>
&lt;p>격리수준이라는 옵션이다. 트랜잭션에서 일관성이 없는 데이터를 허용하도록 하는 수준을 말하는데 옵션은 다음과 같다.&lt;/p>
&lt;ol>
&lt;li>READ_UNCOMMITTED (level 0)&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>트랜잭션에 처리중인 혹은 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용&lt;/li>
&lt;li>어떤 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 B라는 아직 완료되지 않은(Uncommitted 혹은 Dirty) 데이터 B를 읽을 수 있다.
&lt;blockquote>
&lt;p>Dirty read : 위와 같이 다른 트랜잭션에서 처리하는 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있는 현상을 dirty read 라고 하며, READ UNCOMMITTED 격리수준에서만 일어나는 현상&lt;/p>&lt;/blockquote>
&lt;/li>
&lt;/ul>
&lt;ol start="2">
&lt;li>READ_COMMITTED (level 1)&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>dirty read 방지 : 트랜잭션이 커밋되어 확정된 데이터만을 읽는 것을 허용&lt;/li>
&lt;li>어떠한 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 해당 데이터에 접근할 수 없다.&lt;/li>
&lt;/ul>
&lt;ol start="3">
&lt;li>REPEATABLE_READ (level 2)&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능하다.&lt;/li>
&lt;li>선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때까지 후행 트랜잭션이 갱신하거나 삭제하는 것을 불허함으로써 같은 데이터를 두 번 쿼리했을 때 일관성 있는 결과를 리턴함&lt;/li>
&lt;/ul>
&lt;ol start="4">
&lt;li>SERIALIZABLE (level 3)&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>완벽한 읽기 일관성 모드를 제공&lt;/li>
&lt;li>데이터의 일관성 및 동시성을 위해 MVCC(Multi Version Concurrency Control)을 사용하지 않음(MVCC는 다중 사용자 데이터베이스 성능을 위한 기술로 데이터 조회 시 LOCK을 사용하지 않고 데이터의 버전을 관리해 데이터의 일관성 및 동시성을 높이는 기술)&lt;/li>
&lt;li>트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능하다.&lt;/li>
&lt;/ul>
&lt;h3 id="propagation--전파옵션">propagation ( 전파옵션)&lt;/h3>
&lt;ul>
&lt;li>REQUIRED : 부모 트랜잭션 내에서 실행하며 부모 트랜잭션이 없을 경우 새로운 트랜잭션을 생성&lt;/li>
&lt;li>REQUIRES_NEW : 부모 트랜잭션을 무시하고 무조건 새로운 트랜잭션이 생성&lt;/li>
&lt;li>SUPPORT : 부모 트랜잭션 내에서 실행하며 부모 트랜잭션이 없을 경우 nontransactionally로 실행&lt;/li>
&lt;li>MANDATORY : 부모 트랜잭션 내에서 실행되며 부모 트랜잭션이 없을 경우 예외가 발생&lt;/li>
&lt;li>NOT_SUPPORT : nontransactionally로 실행하며 부모 트랜잭션 내에서 실행될 경우 일시 정지&lt;/li>
&lt;li>NEVER : nontransactionally로 실행되며 부모 트랜잭션이 존재한다면 예외가 발생&lt;/li>
&lt;li>NESTED : 해당 메서드가 부모 트랜잭션에서 진행될 경우 별개로 커밋되거나 롤백될 수 있음. 둘러싼 트랜잭션이 없을 경우 REQUIRED와 동일하게 작동&lt;/li>
&lt;/ul>
&lt;h3 id="no-rollback-for---예외처리-기본값--없음">no-rollback-for - 예외처리 (기본값 : 없음)&lt;/h3>
&lt;p>특정 예외가 발생하더라도 롤백되지 않도록 설정&lt;/p>
&lt;h3 id="스프링-배치에서의-트랜잭션-내가-당했던-문제">스프링 배치에서의 트랜잭션 (내가 당했던(?) 문제)&lt;/h3>
&lt;p>스프링 배치에서는 Tasklet 에서 기본적으로 step 단위 트랜잭션을 지원하고 있다고 한다.
기본적으로 job이 하나의 tasklet 의 step 으로 실행하다보니 명시적이진 않지만 내부적으로 전체 트랜잭션으로 걸려있게 된다. 나같은 job 내 DAO delete 메소드에서 @Transactional 설정을 하고 그 DAO 메소드를 반복문에 의해 delete 하는 로직을 수행하는 부분이 있었는데 부모의 트랜잭션(tasklet에서 설정된 트랜잭션)으로 인해 dao 를 몇번 호출하던 job단위로 트렌젝션이 걸리게 되었다. (결국 트랜잭션은 반복문이 다 끝나야 적용이 된다는점.)
그러다보니 가끔 DB Query Lock이 걸렸는데 DB레벨에서 undolog를 남기는게 너무 무거워져 lock이 발생&lt;/p>
&lt;p>따라서 전파옵션을 수정해서 해당 문제를 해결하였다.&lt;/p>
&lt;pre tabindex="0">&lt;code># 기존
begin 
delete &amp;lt; for 반복문
commit

# 전파옵션 수정 (기존 REQUIRES 에서 REQUIRES_NEW 으로 수정)
for
 begin
 delete
 commit
for end 
&lt;/code>&lt;/pre></description></item><item><title>디자인패턴-싱글톤</title><link>https://taetaetae.github.io/2016/10/06/20161006/</link><pubDate>Thu, 06 Oct 2016 17:03:48 +0000</pubDate><guid>https://taetaetae.github.io/2016/10/06/20161006/</guid><description>&lt;p>디자인 패턴중에 가장 잘 알려진 싱글톤 에 대해서 알아보고자 한다. 멀티 스레드 환경에서 자주 이용되는 패턴이라고만 들었는데 이번 기회를 통해 제대로 정리해보자&lt;/p>
&lt;h2 id="싱글톤이-무엇인가">싱글톤이 무엇인가&lt;/h2>
&lt;blockquote>
&lt;p>싱글톤(Singleton)은 정확히 하나의 인스턴스만 생성되는 클래스이다.&lt;/p>&lt;/blockquote>
&lt;p>라고 이펙티브 자바에서 정의되어있다. 즉, 딱 하나만 생성하고 이를 여기저기서 사용하는 패턴이라 생각하면 될듯 하다. 싱글 스레드 환경에서는 당연히 인스턴스를 공유할 상황이 없겠지만 대부분 멀티 스레드 환경이기 때문에 싱글톤 패턴은 아주 중요한 부분이다.&lt;/p>
&lt;h3 id="아주-고전적인-방법-위험한-방법">아주 고전적인 방법 (위험한 방법)&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">class&lt;/span> &lt;span class="nc">Singleton&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Singleton&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">Singleton&lt;/span>&lt;span class="p">(){}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Singleton&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">getInstance&lt;/span>&lt;span class="p">(){&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">){&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">			&lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Singleton&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">		&lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">	&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>위와 같은 상황에서 if절을 도달하는 시점이 각 스레드마다 다를경우 문제가 발생할 수 있다.(교묘한 시점에 객체가 1개 이상 반환될 여지가 있음) 이를 해결하기 위해서는 다음과 같이 getInstance()를 동기화 해주면 된다. 하지만 불필요하게 동기화 하는 오버헤드만 증가하게 된다.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">class&lt;/span> &lt;span class="nc">Singleton&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Singleton&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">Singleton&lt;/span>&lt;span class="p">(){}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">synchronized&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Singleton&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">getInstance&lt;/span>&lt;span class="p">(){&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">null&lt;/span>&lt;span class="p">){&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Singleton&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">uniqueInstance&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="public-static-인스턴스로-생성">public static 인스턴스로 생성&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">final&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LocalCache&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sharedObject&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LocalCache&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">LocalCache&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>이코드는 간단하다는 장점이 있는 반면에 유연하지 못한 부분이 있다. (아래 이어서 설명)&lt;/p>
&lt;h3 id="private-static-final-인스턴스로-생성">private static final 인스턴스로 생성&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">final&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LocalCache&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sharedObject&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LocalCache&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">private&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">LocalCache&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">static&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LocalCache&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">getInstance&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">sharedObject&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>이렇게 하면 factory 메소드를 통해 객체를 반환받고, 반환 받는 시점에 다양한 작업들을 할수 있다.&lt;/p>
&lt;h3 id="enum-으로-생성">enum 으로 생성&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">enum&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LocalCacheEnum&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">LocalCache&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c1">//etc another functions&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>잘 사용하지는 않지만 가장 좋은 세번째 방법인 enum으로 클래스를 만드는 방법이라고 한다. 복잡한 직렬화나 리플렉션(reflection) 상황에서도 직렬화가 자동으로 지원되고, 인스턴스가 여러개 생기지 않도록 확실하게 보장해준단다. (by effective java)&lt;/p>
&lt;h2 id="그럼-어디서-사용될까">그럼 어디서 사용될까&lt;/h2>
&lt;ol>
&lt;li>static 으로 선언해서 공통적으로 사용되는 부분이나 환경설정&lt;/li>
&lt;li>내용이 변경되면 다른 클래스에서도 그 부분이 똑같이 적용되어 실행되어야 할때&lt;/li>
&lt;li>자주 사용되는 부분을 싱글톤으로 만들어 생성되는 시간을 줄일때&lt;/li>
&lt;li>스프링에서의 DB커넥션 로직&lt;/li>
&lt;/ol></description></item><item><title>hexo 환경 구축하기</title><link>https://taetaetae.github.io/2016/09/23/20160923/</link><pubDate>Fri, 23 Sep 2016 10:26:53 +0000</pubDate><guid>https://taetaetae.github.io/2016/09/23/20160923/</guid><description>&lt;h3 id="개요">개요&lt;/h3>
&lt;p>&lt;a href="https://taetaetae.github.io/2016/09/18/hexo_github_blog" rel="">이전포스팅&lt;/a> 에서 이야기 한것과 같이 어느곳에서든지&lt;code>(집 또는 회사 등)&lt;/code> 블로그 포스팅을 할수 있는 환경을 만들고 싶었다. (git을 이용해서.) 그래서 git repository 를 두개를 만들었고, 하나는 실제 블로그서버로 이용하고 하나는 블로그를 포스팅하는 hexo 환경을 저장하게 된다. 지금부터 이야기 할 내용은 hexo환경을 git repository 에서 pull 받아서 환경구성하는 부분을 이야기 하려고 한다.&lt;/p>
&lt;h3 id="환경구성">환경구성&lt;/h3>
&lt;p>&lt;code>hexo설치와 git설치는 되어있다고 가정.&lt;/code>
먼저 구성할 폴더를 생성하고 이 폴더에 hexo 환경을 구성하겠다고 초기 셋팅을 한다&lt;/p>
&lt;pre tabindex="0">&lt;code>mkdir blog
hexo init blog
&lt;/code>&lt;/pre>&lt;p>그리고 hexo환경을 저장해둔 repository를 가져와야 하므로 git설정을 한다&lt;/p>
&lt;pre tabindex="0">&lt;code>cd blog/
git init
git remote add origin https://github.com/taetaetae/hexo.git
git fetch
&lt;/code>&lt;/pre>&lt;p>필요없는&lt;code>초기셋팅이 되는 파일&lt;/code>은 지우고&lt;/p>
&lt;pre tabindex="0">&lt;code>rm source/_posts/hello-world.md
rm -r themes/landscape/ #해당 테마를 사용하고 있다면 지울필요가 없다.
&lt;/code>&lt;/pre>&lt;p>hexo환경 repository 를 pull받는다&lt;/p>
&lt;pre tabindex="0">&lt;code>git reset --hard origin/master
git pull origin master
&lt;/code>&lt;/pre>&lt;p>hueman테마의 검색 기능을 사용한다는 가정하에 필요한 플러그인과, 나중에 deploy 할때 필요한 플러그인을 설치해준다&lt;/p>
&lt;pre tabindex="0">&lt;code>npm install hexo-deployer-git --save
npm install -S hexo-generator-json-content
&lt;/code>&lt;/pre>&lt;p>이렇게 되면 기존처럼 환경설정이 마무리 되고, 포스팅을 할수 있게 된다.&lt;/p>
&lt;h3 id="추가">추가&lt;/h3>
&lt;ul>
&lt;li>canonical 속성
npm install &amp;ndash;save hexo-auto-canonical&lt;/li>
&lt;li>사이트맵 속성
npm install hexo-generator-seo-friendly-sitemap &amp;ndash;save&lt;/li>
&lt;li>feed 속성
npm install hexo-generator-feed &amp;ndash;save&lt;/li>
&lt;/ul></description></item><item><title>hexo + github + blog 연동하기</title><link>https://taetaetae.github.io/2016/09/18/hexo_github_blog/</link><pubDate>Sun, 18 Sep 2016 15:38:34 +0000</pubDate><guid>https://taetaetae.github.io/2016/09/18/hexo_github_blog/</guid><description>&lt;h2 id="들어가기에-앞서">들어가기에 앞서&lt;/h2>
&lt;p>예전부터 블로그를 운영해야지 하구서 tistory, naver blog 등 다양한 플랫폼으로 시작을 했었지만 이렇다할 운영이 안되었고 &lt;del>사실 열정이 부족했었다.&lt;/del> 직접 홈페이지를 만들기에는 너무 많은 허들이 있다보니 (서버구축, 호스팅, 도메인 등 &amp;hellip;) 계속 차일피일 미루고 있었다.
그러다 github에서 제공하는 pages라는 걸 이용해서 무료로 도메인과 웹호스팅을 할수 있다는 부분을 알게되었고, 거기에다 jekyll을 이용하면 설치형 블로그를 운영할수 있다는것에 놀라웠다. 하지만 jekyll을 적용해보려고 이것저것 하다보니 ruby라는 언어로 만들어져있고 커스터마이징이 어렵다는 부분을 확인, 좀더 알아보다 hexo 라는 걸로 해당 블로그를 만들게 되었다.
필자처럼 남들과는 다른 블로그를 만들고 싶거나, git command 공부도 하면서 블로그를 운영해볼 사람들은 해당 글을 천천히 따라오면 좋을것 같다.&lt;/p>
&lt;h3 id="hexo-시작하기">hexo 시작하기&lt;/h3>
&lt;p>hexo 라는걸 시작하기 위해 몇가지 준비물이 있다.&lt;/p>
&lt;ol>
&lt;li>&lt;a href="http://nodejs.org" target="_blank" rel="noopener noreffer ">node 설치&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://git-scm.com" target="_blank" rel="noopener noreffer ">git 설치&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://github.com" target="_blank" rel="noopener noreffer ">github&lt;/a>에 블로그로 사용할 빈 repository 생성&lt;/li>
&lt;li>&lt;a href="http://github.com" target="_blank" rel="noopener noreffer ">github&lt;/a>에 hexo 설정을 저장할 빈 repository 생성&lt;/li>
&lt;/ol>
&lt;p>위 4가지(?!)가 전부 설치 되었다고 가정을 하고 시작을 해보겠다.&lt;/p>
&lt;h3 id="hexo-설치">hexo 설치&lt;/h3>
&lt;p>간단하다. &lt;a href="http://hexo.io" target="_blank" rel="noopener noreffer ">hexo&lt;/a> 페이지에도 나와있는것처럼 아래 명령어를 실행해주면 된다.&lt;/p>
&lt;pre tabindex="0">&lt;code>$ npm install -g hexo-cli
&lt;/code>&lt;/pre>&lt;h3 id="블로그로-운영할-폴더-hexo-초기화">블로그로 운영할 폴더 hexo 초기화&lt;/h3>
&lt;p>폴더 구조로 구성이 되기 때문에 임의의 폴더를 하나 만들고 해당 폴더를 hexo 명령어로 초기화 시켜준다.&lt;/p>
&lt;pre tabindex="0">&lt;code>$ mkdir &amp;lt;디렉토리명&amp;gt;
$ hexo init &amp;lt;디렉토리명&amp;gt;
&lt;/code>&lt;/pre>&lt;h3 id="로컬서버-띄워보기">로컬서버 띄워보기&lt;/h3>
&lt;p>이제 로컬에서 서버를 띄워서 블로그가 어떻게 나오는지 확인을 해보면 된다.&lt;/p>
&lt;pre tabindex="0">&lt;code>$ hexo s (or server)
&lt;/code>&lt;/pre>&lt;p>간혹 서버가 실행이 안되거나 오류가 발생, 수정한 부분이 반영이 안된다면 clean 명령어를 한번 해준 다음에 다시 서버를 실행해주면 되는 경우도 있다.&lt;/p>
&lt;pre tabindex="0">&lt;code>$ hexo clean
$ hexo s (or server)
&lt;/code>&lt;/pre>&lt;p>http://localhost:4000 을 접속해서 정상적으로 페이지가 나오는지 확인을 해보자.
페이지가 정상적으로 나온다면 성공!&lt;/p>
&lt;h3 id="글-작성">글 작성&lt;/h3>
&lt;p>아래 명령어를 실행하면 /source/_post/ 아래에 .md 파일이 생성이 된다.&lt;/p>
&lt;pre tabindex="0">&lt;code>$ hexo new &amp;lt;글 제목&amp;gt;
&lt;/code>&lt;/pre>&lt;p>해당 파일을 사용하기 편한 에디터로 열어서 마크다운 문법에 맞추어 수정을 하면 끝!&lt;/p>
&lt;h3 id="왜-두개의-repository가-필요한가">왜 두개의 repository가 필요한가&lt;/h3>
&lt;p>아래에서 이야기 하겠지만, 하나는 실제 블로그 내용이 올라갈 저장소이고 다른 하나는 블로그를 운영하고 있는 hexo 자체를 저장할 저장소이다. hexo 정보를 가지고 있지 않을꺼라면&lt;code>(필자처럼 다양한 PC에서 업로드 환경을 구축하지 않을꺼라면)&lt;/code> 하나의 레파지토리만 필요할수도 있다.&lt;/p>
&lt;h3 id="github-셋팅">github 셋팅&lt;/h3>
&lt;blockquote>
&lt;p>지금부터가 알짜배기다. 즉 이글을 포스팅 하는 의미. 다른 글들에서도 hexo 사용법을 친절하게 알려 주셨으나 github와의 연동, 그리고 어떤식으로 운영해야할지는 찾기 힘들었다. 필자는 감으로 그런가보다(?)하고서 터득한 바를 공유하려한다. (이게 정답은 아니지만, 나는 이렇게 사용하는게 맞겠다 싶어..)&lt;/p>&lt;/blockquote>
&lt;p>일반적으로 github에서 블로그로 사용할 repository를 만들게 되면 http://(github아이디).github.io/(repository이름) 으로 블로그가 만들어 지는데 뭔가 조금 이상해서 &lt;del>간지가 안나서&lt;/del> 찾고 찾아서 아래와 같은 방식으로 하게 되었다.
필자의 github 아이디는 taetaetae 이고 도메인은 아이디 그대로를 사용하여 &lt;a href="http://taetaetae.github.io" target="_blank" rel="noopener noreffer ">http://taetaetae.github.io&lt;/a> 으로 사용하고 싶었다. 따라서 github에 repository이름을 taetaetae.github.io로 만들어야 한다. 여기까지만 하면 일단 github에 배포할수 있는 준비가 되어있는 상태&lt;/p>
&lt;h3 id="hexo로-배포하기">hexo로 배포하기&lt;/h3>
&lt;p>포스팅한 글이 정상적으로 등록이 된 것을 로컬서버에서 확인이 되었으면 이 상태를 조금전 만든 github repository으로 배포(정확히 말하면 git push)해줘야 한다. 그전에 최상위 폴더에 있는 _config.yml 파일을 열어서 github 정보를 입력해 줘야 한다.
하단 영역 Deployment 부분에 다음과 같이 작성하고 저장한다.&lt;/p>
&lt;pre tabindex="0">&lt;code># Deployment
deploy:
 type: git
 repo: https://github.com/taetaetae/taetaetae.github.io
 branch: master
&lt;/code>&lt;/pre>&lt;p>그 다음 hexo 에서 github로 배포할수있는 플러그인을 설치해준다.&lt;/p>
&lt;pre tabindex="0">&lt;code>$ npm install hexo-deployer-git --save
&lt;/code>&lt;/pre>&lt;p>이제 설정한 github에 배포를 하면 끝!&lt;/p>
&lt;pre tabindex="0">&lt;code>$ hexo deploy
&lt;/code>&lt;/pre>&lt;p>1분~3분 뒤에 도메인을 접속하여 정상적으로 페이지가 나오는지 확인하고, github에 파일들이 push가 잘 되었는지를 확인한다.&lt;/p>
&lt;h3 id="향후-관리-hexo-정보-저장">향후 관리 hexo 정보 저장&lt;/h3>
&lt;p>나중에 다른 PC에서도 블로그를 포스팅 할 경우가 있으니 hexo를 이용하여 포스팅 한 환경 자체를 저장 해야할 필요가 생겼다. 따라서 만들었던 폴더 또한 github에 업로드를 해놓는게 좋을것 같다 (지극히 개인적인 생각)
&lt;code>git command 설명은 따로 정리하지 않겠다. &lt;/code>&lt;/p></description></item><item><title>첫번째 포스팅</title><link>https://taetaetae.github.io/2016/09/18/first/</link><pubDate>Sun, 18 Sep 2016 00:34:23 +0000</pubDate><guid>https://taetaetae.github.io/2016/09/18/first/</guid><description>&lt;p>시작은 언제든지 새롭고 떨리고 가슴벅차는 순간이다.
과연 이 블로그를 잘 운영할수 있을런지..
제대로 한번 관리 해보고, 나만의 공간으로 꾸며보자!&lt;/p></description></item></channel></rss>