<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Java on My Life</title><link>https://dig06161.github.io/tags/java/</link><description>Recent content in Java on My Life</description><generator>Hugo -- 0.145.0</generator><language>ko-kr</language><lastBuildDate>Wed, 06 Apr 2022 16:30:00 +0900</lastBuildDate><atom:link href="https://dig06161.github.io/tags/java/index.xml" rel="self" type="application/rss+xml"/><item><title>Spring Framework AOP(Aspect Oriented Programming)이란?</title><link>https://dig06161.github.io/2022/04/06/Spring-AOP/</link><pubDate>Wed, 06 Apr 2022 16:30:00 +0900</pubDate><guid>https://dig06161.github.io/2022/04/06/Spring-AOP/</guid><description>&lt;p>스프링은 코드의 반복 사용을 줄이고 효율적이며 결합도가 낮은 유연한 코드를 작성하길 원한다.&lt;/p>
&lt;p>우리는 코드를 작성할때 크게 중요한 부분은 아니지만 어떤 값을 확인하는 등 여러 부분에서 중복으로 쓰이는 코드가 있을 수 있다. 예를 들면 로그인 세션이 남아 있는지, 또는 어떤 로직에서의 에러에 대한 로그를 핸들링 할때 등등 상황은 매우 다양하다.&lt;/p>
&lt;p>OOP는 코드의 재활용성을 높이고 객체지향을 통해 코드 개발을 더 쉽게, 유지보수하기 편하게 하기 위해 시작되었다. 여기서 더 나아가 Spring에서는 AOP를 통해 비즈니스 로직 상에 중복적이지만 꼭 필요한 코드를 따로 묶어 외부로 분리해 메인 코드에 집중할 수 있게 해주는 기법이다.&lt;/p></description><content:encoded><![CDATA[<p>스프링은 코드의 반복 사용을 줄이고 효율적이며 결합도가 낮은 유연한 코드를 작성하길 원한다.</p>
<p>우리는 코드를 작성할때 크게 중요한 부분은 아니지만 어떤 값을 확인하는 등 여러 부분에서 중복으로 쓰이는 코드가 있을 수 있다. 예를 들면 로그인 세션이 남아 있는지, 또는 어떤 로직에서의 에러에 대한 로그를 핸들링 할때 등등 상황은 매우 다양하다.</p>
<p>OOP는 코드의 재활용성을 높이고 객체지향을 통해 코드 개발을 더 쉽게, 유지보수하기 편하게 하기 위해 시작되었다. 여기서 더 나아가 Spring에서는 AOP를 통해 비즈니스 로직 상에 중복적이지만 꼭 필요한 코드를 따로 묶어 외부로 분리해 메인 코드에 집중할 수 있게 해주는 기법이다.</p>
<p>여기서 AOP는 따로 분리된 Aspect를 모아 모듈화 하는 기법이라고 보면 편할 것이다.</p>
<p><br><br></p>
<h2 id="위빙weaving">위빙(Weaving)</h2>
<p>AOP에서 공통적으로 실행되는 기능을 직접적으로 호출하지 않고 위빙이라는 작업을 통해 호출하게 된다. 이런 위빙을 사용하기 위해서는 공통적으로 쓰이는 코드가 언제, 어디서 적용할 것인지 명시해야 한다. 어디서 적용할 것인지에 대한 설정을 Pointcut이라고 하고, 언제 적용할 것인지에 대해 Advice라 한다. 이 Pointcut과 Advice의 조합을 Aspect라고 한다.</p>
<p><br><br></p>
<p>우선 진행하기 전에 필요한 사전 설정을 마무리 해보자.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl">    <span class="nt">&lt;properties&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;java-version&gt;</span>11<span class="nt">&lt;/java-version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;org.springframework-version&gt;</span>5.3.17<span class="nt">&lt;/org.springframework-version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;org.aspectj-version&gt;</span>1.9.9.1<span class="nt">&lt;/org.aspectj-version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;org.slf4j-version&gt;</span>1.6.6<span class="nt">&lt;/org.slf4j-version&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/properties&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.aspectj<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>aspectjrt<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.aspectj-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.aspectj<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>aspectjweaver<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.aspectj-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span></code></pre></div><p>위와 같이 aop사용을 위해 maven버전을 맞춰준다. 이후 servlet-context.xml에 다음과 같은 구문을 추가한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl">xmlns:aop=&#34;http://www.springframework.org/schema/aop&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">xsi:schemaLocation 에 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd&#34; 추가
</span></span></code></pre></div><p><br><br></p>
<h2 id="pointcut어디에">Pointcut(어디에)</h2>
<p>어디에 공통관심 코드를 적용할 것인지에 대한 설정을 진행한다. 하나의 @Aspect 안에 여러개의 포인트 컷 설정이 가능하다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Pointcut</span><span class="p">(</span><span class="s">&#34;execution(com.test.test..)&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">private</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">all</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span><span class="w">
</span></span></span></code></pre></div><p>위와 같이 포인트 컷이 적용될 위치를 지정해 주는데 지시자로 주로 많이 사용하는 excution 타입에 대해 간략하게 적어본다.</p>
<ol>
<li>
<p>리턴타입 지정
말 그대로 지정한 리턴타입에 적용한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="o">*</span><span class="w">       </span><span class="c1">//모든 리턴타입 혀용</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kt">void</span><span class="w">    </span><span class="c1">//리턴타입이 void인 메소드</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">!</span><span class="kt">void</span><span class="w">   </span><span class="c1">//리턴타입이 void가 아닌 메소드</span><span class="w">
</span></span></span></code></pre></div></li>
<li>
<p>패키지 지정
Aspect 코드를 적용할 패키지를 지정한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="w"> </span><span class="n">com</span><span class="p">.</span><span class="na">test</span><span class="p">.</span><span class="na">domain</span><span class="w">     </span><span class="c1">//com.test.domain 패키지만 선택</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">com</span><span class="p">.</span><span class="na">test</span><span class="p">.</span><span class="na">domain</span><span class="p">..</span><span class="w">   </span><span class="c1">//com.test.domain으로 시작하는 패키지 선택</span><span class="w">
</span></span></span></code></pre></div></li>
<li>
<p>클래스 지정</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="n">userVO</span><span class="w">      </span><span class="c1">//userVO 클래스만 선택</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="o">*</span><span class="n">VO</span><span class="w">         </span><span class="c1">//VO로 끝나는 클래스</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">testClass</span><span class="w">   </span><span class="c1">//클래스 이름 뒤에 +가 붙으면 해장 클래스로 부터 파생된 모든 자식 클래스까지 선택, 인터페이스 이름 뒤에 +가 붙으면 해당 인터페이스를 구현한 모든 클래스 선택</span><span class="w">
</span></span></span></code></pre></div></li>
<li>
<p>메소드 지정</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="p">(..)</span><span class="w">       </span><span class="c1">//모든 메소드 선택</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">update</span><span class="p">(..)</span><span class="w"> </span><span class="c1">//메소드명이 update로 시작하는 모든 메소드</span><span class="w">
</span></span></span></code></pre></div></li>
</ol>
<p>조금 다르게 응용하자면 Advice어노테이션에 적용도 가능하다
예를 들면 @Around(value=&ldquo;execution(* com.test.test.<em>.</em>(..))&rdquo;) 형식이다.</p>
<p><br><br></p>
<h2 id="5가지의-advice언제">5가지의 Advice(언제)</h2>
<p>Advice는 다섯가지 상황으로 적용할 수 있다. 각각 어노테이션으로 적용이 가능하며 그 목록은 다음과 같다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Before</span><span class="w">             </span><span class="c1">//메서드 실행 전</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@After</span><span class="w">              </span><span class="c1">//메서드 실행 후</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@AfterRunning</span><span class="w">       </span><span class="c1">//실행 뒤 반환 후</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@AfterThrowing</span><span class="w">      </span><span class="c1">//예외가 던져지는 시점</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@Around</span><span class="w">             </span><span class="c1">//메서드 호출 전</span><span class="w">
</span></span></span></code></pre></div><p>Advice를 작성할떄 반드시 하나 이상의 Pointcut을 명시해야 한다.</p>
<p>여기서 당면한 상황에 맞게 사용하면 될것 같다. 기본적인 예를 들어보면 다음과 같은 코드로 사용이 가능하다.</p>
<h3 id="aoptestaspect">AopTestAspect</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Component</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@Aspect</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">AopTestAspect</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="n">Logger</span><span class="w"> </span><span class="n">logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LoggerFactory</span><span class="p">.</span><span class="na">getLogger</span><span class="p">(</span><span class="n">AopTestAspect</span><span class="p">.</span><span class="na">class</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@Around</span><span class="p">(</span><span class="s">&#34;all()&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">Object</span><span class="w"> </span><span class="nf">AopTest</span><span class="p">(</span><span class="n">ProceedingJoinPoint</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Throwable</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Date</span><span class="w"> </span><span class="n">date</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Date</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">date</span><span class="p">.</span><span class="na">getTime</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Object</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">.</span><span class="na">proceed</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">logger</span><span class="p">.</span><span class="na">info</span><span class="p">(</span><span class="s">&#34;AOP start - &#34;</span><span class="o">+</span><span class="n">date</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@Pointcut</span><span class="p">(</span><span class="s">&#34;@annotation(AopTest)&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">private</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">all</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="aoptest">AopTest</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Target</span><span class="p">(</span><span class="n">ElementType</span><span class="p">.</span><span class="na">METHOD</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@Retention</span><span class="p">(</span><span class="n">RetentionPolicy</span><span class="p">.</span><span class="na">RUNTIME</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="nd">@interface</span><span class="w"> </span><span class="n">AopTest</span><span class="w"> </span><span class="p">{}</span><span class="w">
</span></span></span></code></pre></div><h3 id="homecontoller-aop-어노테이션-적용-부분">HomeContoller (AOP 어노테이션 적용 부분)</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@AopTest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@RequestMapping</span><span class="p">(</span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;/aop&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RequestMethod</span><span class="p">.</span><span class="na">GET</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">aop</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">logger</span><span class="p">.</span><span class="na">info</span><span class="p">(</span><span class="s">&#34;aop controller start&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="s">&#34;home&#34;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>여기서 AopTestAspect 부분은 이렇게 사용이 가능하다.</p>
<h3 id="aoptestaspect-1">AopTestAspect</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Component</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@Aspect</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">AopTestAspect</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="n">Logger</span><span class="w"> </span><span class="n">logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LoggerFactory</span><span class="p">.</span><span class="na">getLogger</span><span class="p">(</span><span class="n">AopTestAspect</span><span class="p">.</span><span class="na">class</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@Around</span><span class="p">(</span><span class="s">&#34;@annotation(AopTest)&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">Object</span><span class="w"> </span><span class="nf">AopTest</span><span class="p">(</span><span class="n">ProceedingJoinPoint</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Throwable</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Date</span><span class="w"> </span><span class="n">date</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Date</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">date</span><span class="p">.</span><span class="na">getTime</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Object</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">.</span><span class="na">proceed</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">logger</span><span class="p">.</span><span class="na">info</span><span class="p">(</span><span class="s">&#34;AOP start - &#34;</span><span class="o">+</span><span class="n">date</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>위 코드는 @AopTest 어노테이션이 쓰인 곳에 시간을 로그로 찍는 AOP를 작성했다. 아래는 AOP 사용의 또다른 예제이다.</p>
<h3 id="aoptestaspect-2">AopTestAspect</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Component</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@Aspect</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">AopTestAspect</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Logger</span><span class="w"> </span><span class="n">logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LoggerFactory</span><span class="p">.</span><span class="na">getLogger</span><span class="p">(</span><span class="n">AopTestAspect</span><span class="p">.</span><span class="na">class</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@Around</span><span class="p">(</span><span class="s">&#34;all()&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">Object</span><span class="w"> </span><span class="nf">AopTest</span><span class="p">(</span><span class="n">ProceedingJoinPoint</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Throwable</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Date</span><span class="w"> </span><span class="n">date</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Date</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">date</span><span class="p">.</span><span class="na">getTime</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Object</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">.</span><span class="na">proceed</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">logger</span><span class="p">.</span><span class="na">info</span><span class="p">(</span><span class="s">&#34;AOP start - &#34;</span><span class="o">+</span><span class="n">date</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@Pointcut</span><span class="p">(</span><span class="s">&#34;execution(* com.test.test.HomeController.*(..))&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">private</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">all</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>위 코드는 com.test.test.HomeController 아래의 모든 메소드에 AOP를 적용한 코드이다. execution을 설명하자면 앞의 <em>는 리턴타입 설정 부분인데 이는 모든 리턴타입을 의미한다. 띄어쓰기 후 com.test.test.HomeController.</em>(..)은 com.test.test.Homcontroller의 위치에 모든 메소드에 AOP를 적용했다는 의미가 된다.</p>
<p>위 코드는 역시 다음과 같이 간략하게 작성이 가능하다.</p>
<h3 id="aoptestaspect-3">AopTestAspect</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Component</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@Aspect</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">AopTestAspect</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Logger</span><span class="w"> </span><span class="n">logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LoggerFactory</span><span class="p">.</span><span class="na">getLogger</span><span class="p">(</span><span class="n">AopTestAspect</span><span class="p">.</span><span class="na">class</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@Around</span><span class="p">(</span><span class="n">value</span><span class="o">=</span><span class="s">&#34;execution(* com.test.test.HomeController.*(..))&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">Object</span><span class="w"> </span><span class="nf">AopTest</span><span class="p">(</span><span class="n">ProceedingJoinPoint</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Throwable</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Date</span><span class="w"> </span><span class="n">date</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Date</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">date</span><span class="p">.</span><span class="na">getTime</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Object</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">joinPoint</span><span class="p">.</span><span class="na">proceed</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">logger</span><span class="p">.</span><span class="na">info</span><span class="p">(</span><span class="s">&#34;AOP start - &#34;</span><span class="o">+</span><span class="n">date</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Spring Framework DI(Dependency Injection)이란?</title><link>https://dig06161.github.io/2022/04/04/Spring-DI/</link><pubDate>Mon, 04 Apr 2022 16:30:00 +0900</pubDate><guid>https://dig06161.github.io/2022/04/04/Spring-DI/</guid><description>&lt;p>스프링 프레임워크에서는 DI, IOC, AOP 등이 사용되고 있다. 이번에는 스프링 프레임워크에서 사용하는 DI Dependency Injection, 의존주입에 대해서 포스팅 해보려 한다.&lt;/p>
&lt;p>의존 주입이라고 하면 영어를 직역한 표현같이 뭔가 잘 이해가 되질 않는다. 자바에서는 객체를 사용하고 이 객체를 다른 클레스에서 사용하려면 객체를 new 클레스이름 을 통해 생성해서 사용해야 한다.&lt;/p>
&lt;p>DI는 이 new를 통해 생성하는 부분을 자동으로 해준다 생각하면 편할 것 같다. 기본적인 개념은 객체를 직접 생성하는 것이 아니라 자동으로 생성되는 것이다.&lt;/p>
&lt;p>&lt;br>&lt;br>&lt;/p></description><content:encoded><![CDATA[<p>스프링 프레임워크에서는 DI, IOC, AOP 등이 사용되고 있다. 이번에는 스프링 프레임워크에서 사용하는 DI Dependency Injection, 의존주입에 대해서 포스팅 해보려 한다.</p>
<p>의존 주입이라고 하면 영어를 직역한 표현같이 뭔가 잘 이해가 되질 않는다. 자바에서는 객체를 사용하고 이 객체를 다른 클레스에서 사용하려면 객체를 new 클레스이름 을 통해 생성해서 사용해야 한다.</p>
<p>DI는 이 new를 통해 생성하는 부분을 자동으로 해준다 생각하면 편할 것 같다. 기본적인 개념은 객체를 직접 생성하는 것이 아니라 자동으로 생성되는 것이다.</p>
<p><br><br></p>
<p>예를 들어 A라는 객체는 B, C클레스에서 사용된다 했을 때 B, C클레스는 A 객체를 받아와 사용하게 된다.</p>
<center><img src="/img/spring-di/new-class.png" width="80%" height="80%"></center>
<p>여기서 우리가 JAVA를 사용할때 객체를 외부에서 사용할때 new 키워드를 사용하게 된다. 스프링에서는 DI를 이용해 객체를 주입 받는데 이것을 오늘 알아보자.</p>
<p>스프링은 코드의 수정을 최소화 하고 유연한 사용을 위해 강한 결합을 피하고 느슨한 결합을 지향한다. 스프링은 class와 class간의 관계를 지양하려 한다. 객체와 객체간의 관계를 권장하며 상속의 경우 코드 작성의 제약이 많고 확장성을 떨어트려 피하는 것이 좋다. 그걸 위한 기법이 DI이다.</p>
<p>DI를 사용하기 위한 기법은 3가지가 있다. 생성자 주입, 필드 주입, 수정자 주입이다.</p>
<p><br><br></p>
<h3 id="필드-주입">필드 주입</h3>
<p>필드 주입은 빈으로 등록하는 객체를 다음과 같은 코드를 통해 주입해 사용한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">Controller</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@Autowired</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">private</span><span class="w"> </span><span class="n">Service</span><span class="w"> </span><span class="n">service</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@RequestMapping</span><span class="p">(</span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;/&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RequestMethod</span><span class="p">.</span><span class="na">GET</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">home</span><span class="p">(</span><span class="n">Locale</span><span class="w"> </span><span class="n">locale</span><span class="p">,</span><span class="w"> </span><span class="n">Model</span><span class="w"> </span><span class="n">model</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">service</span><span class="p">.</span><span class="na">services</span><span class="w"> </span><span class="p">.....</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>위의 코드를 보면 Service 객체를 @Autowired를 통해 주입받아 사용한다. 이처럼 엄청난 코드 간결성과 편의성 때문에 필자 뿐만 아니라 다른 회사에서도 많이 썼던 기법이라고 한다.</p>
<p>필자는 코드의 간결성과 유연성을 위해 필드 주입을 주로 사용했는데, 스프링에서는 필드주입을 권장하지 않는다. 그 이유는 개발을 진행하다 보면 여러 서비스 객체들이 생기는데 이러한 객체들이 필드 주입으로 인해 순환 참조될 수 있기 때문이다. 예를 들어 A는 B를 참조하고 B는 C를 참조하는데 C가 A를 참조할 경우 계속적으로 참조를 위해 사이클을 돌다가 스텍 에러를 띄우게 된다. 필자는 아직 경험해 본적이 없지만 이러한 문제를 아직 직면하지 않았지만 5버전 스프링에서는 이러한 문제 때문에 생성자 주입을 권장한다.</p>
<p><br><br></p>
<h3 id="수정자-주입">수정자 주입</h3>
<p>수정자 주입방법은 setter를 이용한다. 예시는 다음과 같다</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">Controller</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">private</span><span class="w"> </span><span class="n">Service</span><span class="w"> </span><span class="n">service</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@Autowired</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">setService</span><span class="p">(</span><span class="n">Service</span><span class="w"> </span><span class="n">service</span><span class="p">){</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">this</span><span class="p">.</span><span class="na">service</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">service</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@RequestMapping</span><span class="p">(</span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;/&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RequestMethod</span><span class="p">.</span><span class="na">GET</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">home</span><span class="p">(</span><span class="n">Locale</span><span class="w"> </span><span class="n">locale</span><span class="p">,</span><span class="w"> </span><span class="n">Model</span><span class="w"> </span><span class="n">model</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">service</span><span class="p">.</span><span class="na">services</span><span class="w"> </span><span class="p">.....</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>위와같이 Setter 수정자를 통해 사용하고자 하는 클레스에 객체를 주입 받았다. 이러한 방법은 의존관계 불변성을 위반할 수 있고, putlic 키워드로 메서드를 열어두기 때문에 좋은 방법이 아니다.</p>
<p><br><br></p>
<h3 id="생성자-주입">생성자 주입</h3>
<p>생성자 주입 기법은 스프링에서 가장 권장하고 있는 DI 방법이다. Lombok 라이브러리와 사용성이 용이하고 생성자 호출 시점에서 딱 1번 호출하고 final 키워드 사용이 가능해 불변성을 만족한다. 또한 주입할 데이터가 누락되어있을 경우 컴파일 오류를 띄워준다.</p>
<p>예제는 다음과 같다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">Controller</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">private</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Service</span><span class="w"> </span><span class="n">service</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@Autowired</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="nf">Controller</span><span class="p">(</span><span class="n">Service</span><span class="w"> </span><span class="n">service</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">this</span><span class="p">.</span><span class="na">service</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">service</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@RequestMapping</span><span class="p">(</span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;/&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RequestMethod</span><span class="p">.</span><span class="na">GET</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">home</span><span class="p">(</span><span class="n">Locale</span><span class="w"> </span><span class="n">locale</span><span class="p">,</span><span class="w"> </span><span class="n">Model</span><span class="w"> </span><span class="n">model</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">service</span><span class="p">.</span><span class="na">services</span><span class="w"> </span><span class="p">.....</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Spring Framework STS로 스프링 MVC 프레임워크 프로젝트 만들기</title><link>https://dig06161.github.io/2022/03/28/make-spring-project/</link><pubDate>Mon, 28 Mar 2022 00:30:00 +0900</pubDate><guid>https://dig06161.github.io/2022/03/28/make-spring-project/</guid><description>&lt;ul>
&lt;li>
&lt;h1>스프링 부트&lt;/h1>
&lt;/li>
&lt;/ul>
&lt;p>스프링 부트의 경우 프로젝트 생성이 매우 쉬운 편이다.&lt;/p>
&lt;p>&lt;a href="https://start.spring.io/">https://start.spring.io/&lt;/a> 에 들어가면 spring initializr에서 프로젝트 설정을 할 수 있고 프로젝트 이름, 패키징 방식, 자바 버전, 여러 의존성 등 여러가지 설정을 추가 한 후에 프로젝트 파일을 다운 받을 수 있다.&lt;/p>
&lt;center>&lt;img src="https://dig06161.github.io/img/make-spring-project/spring-boot-initializr.png" width="80%" height="80%">&lt;/center>
&lt;br>&lt;br>
&lt;p>스프링 부트에 관해서는 다른 글로 다시 정리해 보겠다.&lt;/p>
&lt;p>&lt;br>&lt;br>&lt;/p>
&lt;ul>
&lt;li>
&lt;h1>스프링 프레임워크&lt;/h1>
&lt;/li>
&lt;/ul>
&lt;p>스프링 프레임워크는 자체 개발도구 IDE를 제공한다. 이는 자바 IDE로 많이 알려진 Eclipse를 기반으로 하여 Spring Tools이라는 플러그인을 설치해 배포하는 방식이다.&lt;/p></description><content:encoded><![CDATA[<ul>
<li>
<h1>스프링 부트</h1>
</li>
</ul>
<p>스프링 부트의 경우 프로젝트 생성이 매우 쉬운 편이다.</p>
<p><a href="https://start.spring.io/">https://start.spring.io/</a> 에 들어가면 spring initializr에서 프로젝트 설정을 할 수 있고 프로젝트 이름, 패키징 방식, 자바 버전, 여러 의존성 등 여러가지 설정을 추가 한 후에 프로젝트 파일을 다운 받을 수 있다.</p>
<center><img src="/img/make-spring-project/spring-boot-initializr.png" width="80%" height="80%"></center>
<br><br>
<p>스프링 부트에 관해서는 다른 글로 다시 정리해 보겠다.</p>
<p><br><br></p>
<ul>
<li>
<h1>스프링 프레임워크</h1>
</li>
</ul>
<p>스프링 프레임워크는 자체 개발도구 IDE를 제공한다. 이는 자바 IDE로 많이 알려진 Eclipse를 기반으로 하여 Spring Tools이라는 플러그인을 설치해 배포하는 방식이다.</p>
<p>Spring Tools를 줄여 STS라 부르며 지금은 버전 4까지 나온 상황이다. 다만 버전 4는 스프링 부트 개발자들을 위해 만들어진 IDE로 스프링 MVC 프레임워크를 사용하려면 내부에서 STS 3 확장 플러그인을 설치해야 한다.</p>
<p><a href="https://spring.io/tools">https://spring.io/tools</a></p>
<p>위 링크에서 STS 최신버전을 다운 받을 수 있다. Eclipse 기반 IDE이므로 자바가 미리 설치되어 있어야 한다.</p>
<p>Eclipse 뿐만 아니라 VScode도 지원하는데 여기는 STS3 플러그인이 없어 STS로 프로젝트를 생성하고 VScode로 편집을 진행한다.</p>
<p>우선 IDE를 다운로드 하고 원하는 위치에 STS4라는 폴더를 만든후 IDE jar파일을 폴더에 넣어준다.</p>
<center><img src="/img/make-spring-project/sts-folder1.png" width="80%" height="80%"></center>
<p>jar파일을 더블클릭 하면 자동으로 압축을 풀고 디렉터리에 STS 폴더를 생성후 IDE 실행에 필요한 파일들을 넣는다. 이후 이 폴더에 들어가면</p>
<center><img src="/img/make-spring-project/sts-folder2.png" width="80%" height="80%"></center>
<p>SpringToolSuite4.exe가 있다. 이 프로그램이 STS IDE이며 이를 더블클릭해 실행시킨다.
그러면 로딩된 후 워크스페이스를 설정하는 창이 뜨고 이를 자기가 개발할 폴더로 지정해준다.
로딩이 완료되면 익숙한 Eclipse와 비슷한 화면이 뜬다.</p>
<center><img src="/img/make-spring-project/sts4-main.png" width="80%" height="80%"></center>
<p>여기서 spring boot는 Create new Spring starter Project 항목을 통해 프로젝트를 만들 수 있지만, Spring mvc 프로젝트는 항목이 보이지 않는다. 이제 STS3 플러그인을 설치해보자.</p>
<p>Help -&gt; marketplace에 들어간 후 STS3을 검색한다.</p>
<p>그럼</p>
<center><img src="/img/make-spring-project/marketplace-sts3.png" width="80%" height="80%"></center>
<p>이렇데 뜨는데 우리가 필요한 건 중간에 Spring Tools 3 add-On for Spring Tools4라는 것이다. Install 버튼을 통해 설치한다.</p>
<p>중간에 라이센스에 동의하는지 확인창이 뜨는데 전부 agreement를 선택해 마무리 버튼을 누른다.</p>
<p>그러면 잠시후에 STS에서 restart 버튼이 뜰것이다. 다시 시작한다.</p>
<p><br><br></p>
<p>다시 시작한 STS에서 좌측 상단의 File -&gt; New -&gt; Other 을 선택하면 다음과 같은 화면이 뜬다.</p>
<center><img src="/img/make-spring-project/sts4-in-sts3-addOn.png" width="80%" height="80%"></center>
<p>중간에 보면 Spring Legacy Project라는 항목이 있는데 이것이 Spring MVC 프로젝트이다.</p>
<p>이것을 클릭하고 프로젝트 생성으로 들어가면 프로젝트 이름과 상세설정을 볼수 있다.</p>
<center><img src="/img/make-spring-project/sts4-select-spring-mvc.png" width="80%" height="80%"></center>
<p>맨 아래쪽의 Spring MVC Project를 클릭하고 프로젝트 생성을 누르면, maven에서 자동으로 필요한 의존성 파일들을 다운받고 프로젝트 빌드를 한다.</p>
<p><br><br>
필자의 환경은 OpenJDK 11 LTS를 사용했고 현 시점 STS에서 권장하는 버전으로 17에서 테스트 했을 때는 버전 오류가 발생해 다운그레이드 했다. 프로젝트 이름은 com.test.test로 설정했다</p>
<br>
<p>다른 설명에 앞서 톰켓을 알맞는 버전으로 다운받아 STS4 폴더에 같이 넣어준다. 이후 STS4에서 File -&gt; New -&gt; Other 의 Server를 클릭해 다운로드한 톰켓의 버전에 맞에 셋팅을 해줘야 한다.</p>
<p>그 다음, Window -&gt; preferences -&gt; JAVA -&gt; Installed JREs 에서 설치한 자바 jdk를 로드 해준다.</p>
<p>이후 General -&gt; Workspace에서 인코딩 설정을 UTF-8로 바꿔준다. 그리고 General -&gt; Context Type에서 text를 클릭한 후 인코딩 항목에 utf-8을 입력후 적용한다. 이후 WEB -&gt; html, css 에서 인코딩 설정을 동일하게 utf-8로 바꿔준다.</p>
<p>인코딩으로 생기는 문제를 최소한으로 하기 위해 미리 설정을 바꿔주겠다.</p>
<br>
<p>다음은 Spring MVC의 기본 파일 구성이다.</p>
<center><img src="/img/make-spring-project/spring-mvc-structure.png" width="80%" height="80%"></center>
<p>여기서 중점으로 보는 부분들은 src/main/java 아래에 있는 자바 코드와 src/main/webapp 하위 디렉터리 폴더와 파일들, pom.xml이 될것이다.</p>
<p>기본적인 코드 작성은 com.test.test 에 작성하게 된다. 기본적으로 보이는 HomeController.java 의 코드는 다음과 같다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">com.test.test</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">java.text.DateFormat</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">java.util.Date</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">java.util.Locale</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">org.slf4j.Logger</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">org.slf4j.LoggerFactory</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">org.springframework.stereotype.Controller</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">org.springframework.ui.Model</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">org.springframework.web.bind.annotation.RequestMapping</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">org.springframework.web.bind.annotation.RequestMethod</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Handles requests for the application home page.
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nd">@Controller</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">HomeController</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Logger</span><span class="w"> </span><span class="n">logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">LoggerFactory</span><span class="p">.</span><span class="na">getLogger</span><span class="p">(</span><span class="n">HomeController</span><span class="p">.</span><span class="na">class</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm">	 * Simply selects the home view to render by returning its name.
</span></span></span><span class="line"><span class="cl"><span class="cm">	 */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nd">@RequestMapping</span><span class="p">(</span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;/&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RequestMethod</span><span class="p">.</span><span class="na">GET</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">home</span><span class="p">(</span><span class="n">Locale</span><span class="w"> </span><span class="n">locale</span><span class="p">,</span><span class="w"> </span><span class="n">Model</span><span class="w"> </span><span class="n">model</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">logger</span><span class="p">.</span><span class="na">info</span><span class="p">(</span><span class="s">&#34;Welcome home! The client locale is {}.&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">locale</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">Date</span><span class="w"> </span><span class="n">date</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Date</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">DateFormat</span><span class="w"> </span><span class="n">dateFormat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">DateFormat</span><span class="p">.</span><span class="na">getDateTimeInstance</span><span class="p">(</span><span class="n">DateFormat</span><span class="p">.</span><span class="na">LONG</span><span class="p">,</span><span class="w"> </span><span class="n">DateFormat</span><span class="p">.</span><span class="na">LONG</span><span class="p">,</span><span class="w"> </span><span class="n">locale</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">String</span><span class="w"> </span><span class="n">formattedDate</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dateFormat</span><span class="p">.</span><span class="na">format</span><span class="p">(</span><span class="n">date</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="n">model</span><span class="p">.</span><span class="na">addAttribute</span><span class="p">(</span><span class="s">&#34;serverTime&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">formattedDate</span><span class="w"> </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="s">&#34;home&#34;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>위와 같이 @Controller 어노테이션과 @RequestMapping 어노테이션으로 URL 요청을 처리하는 코드이다. 이러한 코드를 바탕으로 비즈니스 로직을 구성하고 사용자 요청에 따른 DB조회 처리구문을 작성하면 웹서버로 동작하게 될것이다.</p>
<br>
<p>src/main/webapp 아래에 resources폴더는 우리가 웹 서버를 프로그래밍 하면서 정적 링크를 사용할 경로이다. 예를 들어 이미지 파일들이 될 것이다.</p>
<br>
<p>WEB-INF -&gt; spring 아래의 파일과 폴더들은 웹 서버 상에서는 접근이 불가능한 부분이다. 스프링의 기본적인 설정파일들이 담겨있다. WEB-INF 내부 파일들에 대해서 알아보자.</p>
<p>appServlet -&gt; servlet-context.xml에는 다음과 같은 내용의 코드가 들어있다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;beans:beans</span> <span class="na">xmlns=</span><span class="s">&#34;http://www.springframework.org/schema/mvc&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xmlns:beans=</span><span class="s">&#34;http://www.springframework.org/schema/beans&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xmlns:context=</span><span class="s">&#34;http://www.springframework.org/schema/context&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
</span></span></span><span class="line"><span class="cl"><span class="s">		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
</span></span></span><span class="line"><span class="cl"><span class="s">		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- DispatcherServlet Context: defines this servlet&#39;s request-processing infrastructure --&gt;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- Enables the Spring MVC @Controller programming model --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;annotation-driven</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;resources</span> <span class="na">mapping=</span><span class="s">&#34;/resources/**&#34;</span> <span class="na">location=</span><span class="s">&#34;/resources/&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;beans:bean</span> <span class="na">class=</span><span class="s">&#34;org.springframework.web.servlet.view.InternalResourceViewResolver&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;beans:property</span> <span class="na">name=</span><span class="s">&#34;prefix&#34;</span> <span class="na">value=</span><span class="s">&#34;/WEB-INF/views/&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;beans:property</span> <span class="na">name=</span><span class="s">&#34;suffix&#34;</span> <span class="na">value=</span><span class="s">&#34;.jsp&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/beans:bean&gt;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;context:component-scan</span> <span class="na">base-package=</span><span class="s">&#34;com.test.test&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/beans:beans&gt;</span>
</span></span></code></pre></div><p>살펴보면 jsp 서블릿 처리에 관한 내용들이 보이고 MVC의 V에 해당하는 view에 해당하는 bean을 생성해 컨트롤러는 url요청에 대한 응답으로 /WEB-INF/views/에서 .jsp파일을 리턴하는 구조로 보인다.</p>
<p>또 js, css, img 등을 위한 /resources/**구분도 보인다.</p>
<br>
<p>root-context.xml에는 다음과 같은 내용이 들어있다</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;beans</span> <span class="na">xmlns=</span><span class="s">&#34;http://www.springframework.org/schema/beans&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- Root Context: defines shared resources visible to all other web components --&gt;</span>
</span></span><span class="line"><span class="cl">		
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/beans&gt;</span>
</span></span></code></pre></div><p>bean 선언에 관한 내용 말고는 추가된 내용은 없어보인다.</p>
<p>그럴수 밖에 없는것이 root-context.xml는 DAO(Data Access Object), VO(Value Object)등 DB연동 관련 서비스에 관한 설정이 적용되는 부분으로 지금은 mybatis나 mariaDB 같이 외부 데이터베이스에 대해 설정을 한것이 없기 떄문이다.</p>
<br>
<p>view -&gt; home.jsp는 servlet-context.xml에서 설정한것 같이, 컨트롤러에 URL 요청이 들어오면 리턴되는 jsp 파일들이 저장되는 곳이다. MVC의 V인 view에서는 jsp를 통해 렌더링 된 화면을 서블릿을 통해 반환한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="err">&lt;</span>%@ taglib uri=&#34;http://java.sun.com/jsp/jstl/core&#34; prefix=&#34;c&#34; %&gt;
</span></span><span class="line"><span class="cl"><span class="err">&lt;</span>%@ page session=&#34;false&#34; %&gt;
</span></span><span class="line"><span class="cl"><span class="nt">&lt;html&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;head&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;title&gt;</span>Home<span class="nt">&lt;/title&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/head&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;body&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;h1&gt;</span>
</span></span><span class="line"><span class="cl">	Hello world!  
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/h1&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nt">&lt;P&gt;</span>  The time on the server is ${serverTime}. <span class="nt">&lt;/P&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/body&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/html&gt;</span>
</span></span></code></pre></div><br>
<p>이런 코드를 가지고 있으며 이 상태로 프로젝트를 돌리면 아마 화면에서 인코딩 에러가 날 것이다. 따라서 개발중 생성되는 jsp파일들의 첫번째 줄에는</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="err">&lt;</span>%@ page language=&#34;java&#34; contentType=&#34;text/html; charset=utf-8&#34; pageEncoding=&#34;utf-8&#34;%&gt;
</span></span></code></pre></div><p>을 붙여 개발한다.</p>
<br>
<p>다음 web.xml을 살펴보자.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;web-app</span> <span class="na">version=</span><span class="s">&#34;2.5&#34;</span> <span class="na">xmlns=</span><span class="s">&#34;http://java.sun.com/xml/ns/javaee&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://JAVA.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- The definition of the Root Spring Container shared by all Servlets and Filters --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;context-param&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;param-name&gt;</span>contextConfigLocation<span class="nt">&lt;/param-name&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;param-value&gt;</span>/WEB-INF/spring/root-context.xml<span class="nt">&lt;/param-value&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/context-param&gt;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- Creates the Spring Container shared by all Servlets and Filters --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;listener&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;listener-class&gt;</span>org.springframework.web.context.ContextLoaderListener<span class="nt">&lt;/listener-class&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/listener&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">&lt;!-- Processes application requests --&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;servlet&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;servlet-name&gt;</span>appServlet<span class="nt">&lt;/servlet-name&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;servlet-class&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="nt">&lt;/servlet-class&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;init-param&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;param-name&gt;</span>contextConfigLocation<span class="nt">&lt;/param-name&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;param-value&gt;</span>/WEB-INF/spring/appServlet/servlet-context.xml<span class="nt">&lt;/param-value&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/init-param&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;load-on-startup&gt;</span>1<span class="nt">&lt;/load-on-startup&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/servlet&gt;</span>
</span></span><span class="line"><span class="cl">		
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;servlet-mapping&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;servlet-name&gt;</span>appServlet<span class="nt">&lt;/servlet-name&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;url-pattern&gt;</span>/<span class="nt">&lt;/url-pattern&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/servlet-mapping&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/web-app&gt;</span>
</span></span></code></pre></div><p>코드를 살펴보면 서블릿 설정과 컨텍스트관련 경로 설정을 잡아준다. WAS에서 필요한 Servlet설정들을 명시해주는 부분이다.</p>
<br>
<p>프로젝트 이름이 test라 햇갈릴수 있지만&hellip;. test 키워드로 /src/test 등 폴더들은 JUnit test에 사용된 코드와 class들이 저장되는 곳이다.</p>
<br>
<p>마지막으로 pom.xml을 살펴보자. Spring은 Maven의 의존성을 통해 버전관리를 하고 원하는 라이브러리를 편하게 다운받을 수 있다. 이런 Maven의 설정에 관한 코드를 pom.xml에 작성한다. 스프링 버전, 자바 버전, 기타 라이브러리 등 모든 버전과 관련된 설정파일은 전부 여기에 작성된다.</p>
<p>코드를 살펴보자.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;project</span> <span class="na">xmlns=</span><span class="s">&#34;http://maven.apache.org/POM/4.0.0&#34;</span> <span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;modelVersion&gt;</span>4.0.0<span class="nt">&lt;/modelVersion&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;groupId&gt;</span>com.test<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;artifactId&gt;</span>test<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;name&gt;</span>test<span class="nt">&lt;/name&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;packaging&gt;</span>war<span class="nt">&lt;/packaging&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;version&gt;</span>1.0.0-BUILD-SNAPSHOT<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;properties&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;java-version&gt;</span>11<span class="nt">&lt;/java-version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;org.springframework-version&gt;</span>5.3.17<span class="nt">&lt;/org.springframework-version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;org.aspectj-version&gt;</span>1.6.10<span class="nt">&lt;/org.aspectj-version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;org.slf4j-version&gt;</span>1.6.6<span class="nt">&lt;/org.slf4j-version&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/properties&gt;</span>
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;dependencies&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="c">&lt;!-- Spring --&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>spring-context<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.springframework-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;exclusions&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="c">&lt;!-- Exclude Commons Logging in favor of SLF4j --&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;exclusion&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;groupId&gt;</span>commons-logging<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;artifactId&gt;</span>commons-logging<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">				 <span class="nt">&lt;/exclusion&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;/exclusions&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>spring-webmvc<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.springframework-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">				
</span></span><span class="line"><span class="cl">		<span class="c">&lt;!-- AspectJ --&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.aspectj<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>aspectjrt<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.aspectj-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>	
</span></span><span class="line"><span class="cl">		
</span></span><span class="line"><span class="cl">		<span class="c">&lt;!-- Logging --&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.slf4j<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>slf4j-api<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.slf4j-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.slf4j<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>jcl-over-slf4j<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.slf4j-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;scope&gt;</span>runtime<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>org.slf4j<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>slf4j-log4j12<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>${org.slf4j-version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;scope&gt;</span>runtime<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>log4j<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>log4j<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>1.2.15<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;exclusions&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;exclusion&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;groupId&gt;</span>javax.mail<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;artifactId&gt;</span>mail<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;/exclusion&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;exclusion&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;groupId&gt;</span>javax.jms<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;artifactId&gt;</span>jms<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;/exclusion&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;exclusion&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;groupId&gt;</span>com.sun.jdmk<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;artifactId&gt;</span>jmxtools<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;/exclusion&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;exclusion&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;groupId&gt;</span>com.sun.jmx<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">					<span class="nt">&lt;artifactId&gt;</span>jmxri<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&lt;/exclusion&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;/exclusions&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;scope&gt;</span>runtime<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="c">&lt;!-- @Inject --&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>javax.inject<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>javax.inject<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>1<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">				
</span></span><span class="line"><span class="cl">		<span class="c">&lt;!-- Servlet --&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>javax.servlet<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>servlet-api<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>2.5<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;scope&gt;</span>provided<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>javax.servlet.jsp<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>jsp-api<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>2.1<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;scope&gt;</span>provided<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>javax.servlet<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>jstl<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>1.2<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">		<span class="c">&lt;!-- Test --&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;groupId&gt;</span>junit<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;artifactId&gt;</span>junit<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;version&gt;</span>4.7<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl">		<span class="nt">&lt;/dependency&gt;</span>        
</span></span><span class="line"><span class="cl">	<span class="nt">&lt;/dependencies&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;build&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&lt;plugins&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&lt;plugin&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;artifactId&gt;</span>maven-eclipse-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;version&gt;</span>2.9<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;additionalProjectnatures&gt;</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&lt;projectnature&gt;</span>org.springframework.ide.eclipse.core.springnature<span class="nt">&lt;/projectnature&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;/additionalProjectnatures&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;additionalBuildcommands&gt;</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&lt;buildcommand&gt;</span>org.springframework.ide.eclipse.core.springbuilder<span class="nt">&lt;/buildcommand&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;/additionalBuildcommands&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;downloadSources&gt;</span>true<span class="nt">&lt;/downloadSources&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;downloadJavadocs&gt;</span>true<span class="nt">&lt;/downloadJavadocs&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;/configuration&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&lt;/plugin&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&lt;plugin&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;artifactId&gt;</span>maven-compiler-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;version&gt;</span>2.5.1<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;source&gt;</span>1.6<span class="nt">&lt;/source&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;target&gt;</span>1.6<span class="nt">&lt;/target&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;compilerArgument&gt;</span>-Xlint:all<span class="nt">&lt;/compilerArgument&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;showWarnings&gt;</span>true<span class="nt">&lt;/showWarnings&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;showDeprecation&gt;</span>true<span class="nt">&lt;/showDeprecation&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;/configuration&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&lt;/plugin&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&lt;plugin&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;groupId&gt;</span>org.codehaus.mojo<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;artifactId&gt;</span>exec-maven-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;version&gt;</span>1.2.1<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">                    <span class="nt">&lt;mainClass&gt;</span>org.test.int1.Main<span class="nt">&lt;/mainClass&gt;</span>
</span></span><span class="line"><span class="cl">                <span class="nt">&lt;/configuration&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&lt;/plugin&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&lt;/plugins&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&lt;pluginManagement&gt;</span>
</span></span><span class="line"><span class="cl">        	<span class="nt">&lt;plugins&gt;</span>
</span></span><span class="line"><span class="cl">        		<span class="c">&lt;!--This plugin&#39;s configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--&gt;</span>
</span></span><span class="line"><span class="cl">        		<span class="nt">&lt;plugin&gt;</span>
</span></span><span class="line"><span class="cl">        			<span class="nt">&lt;groupId&gt;</span>org.eclipse.m2e<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">        			<span class="nt">&lt;artifactId&gt;</span>lifecycle-mapping<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">        			<span class="nt">&lt;version&gt;</span>1.0.0<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">        			<span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">        				<span class="nt">&lt;lifecycleMappingMetadata&gt;</span>
</span></span><span class="line"><span class="cl">        					<span class="nt">&lt;pluginExecutions&gt;</span>
</span></span><span class="line"><span class="cl">        						<span class="nt">&lt;pluginExecution&gt;</span>
</span></span><span class="line"><span class="cl">        							<span class="nt">&lt;pluginExecutionFilter&gt;</span>
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;groupId&gt;</span>
</span></span><span class="line"><span class="cl">        									org.apache.maven.plugins
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;artifactId&gt;</span>
</span></span><span class="line"><span class="cl">        									maven-compiler-plugin
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;versionRange&gt;</span>
</span></span><span class="line"><span class="cl">        									[2.5.1,)
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;/versionRange&gt;</span>
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;goals&gt;</span>
</span></span><span class="line"><span class="cl">        									<span class="nt">&lt;goal&gt;</span>testCompile<span class="nt">&lt;/goal&gt;</span>
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;/goals&gt;</span>
</span></span><span class="line"><span class="cl">        							<span class="nt">&lt;/pluginExecutionFilter&gt;</span>
</span></span><span class="line"><span class="cl">        							<span class="nt">&lt;action&gt;</span>
</span></span><span class="line"><span class="cl">        								<span class="nt">&lt;ignore&gt;&lt;/ignore&gt;</span>
</span></span><span class="line"><span class="cl">        							<span class="nt">&lt;/action&gt;</span>
</span></span><span class="line"><span class="cl">        						<span class="nt">&lt;/pluginExecution&gt;</span>
</span></span><span class="line"><span class="cl">        					<span class="nt">&lt;/pluginExecutions&gt;</span>
</span></span><span class="line"><span class="cl">        				<span class="nt">&lt;/lifecycleMappingMetadata&gt;</span>
</span></span><span class="line"><span class="cl">        			<span class="nt">&lt;/configuration&gt;</span>
</span></span><span class="line"><span class="cl">        		<span class="nt">&lt;/plugin&gt;</span>
</span></span><span class="line"><span class="cl">        	<span class="nt">&lt;/plugins&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&lt;/pluginManagement&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;/build&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/project&gt;</span>
</span></span></code></pre></div><p>pom.xml에 정의되어 있는 의존성에 대한 버전정보는 <a href="https://mvnrepository.com/">https://mvnrepository.com/</a> 에서 확인이 가능하고 원하는 버전을 사용할 수 있다. 다만 주의해야 할 점이 Spring 버전과 openjdk 버전 등 여러 라이브러리의 버전을 맞춰줘야 한다. jdk와 spring 버전이 특정 라이브러리 버전을 지원한다고 해도 다른 라이브러리와 버전 충돌로 인해 사용이 불가 할수도 있다. 이러한 버전관리에서 발생하는 복잡성 때문에 gradle이라는 기술이 등장해 Spring Boot에 적용되었다.</p>
<p>다만 개인적으로 필자는 아직도 Maven이 익숙해 종종 사용하고 있다.</p>
<p>위 xml을 보면 자바 버전이 11이고 스프링 버전에 5.3.17인 것을 볼수 있다. 기본 프로젝트를 생성하면 자바 1.6버전에 스프링 3.X버전이 기본으로 설정되어 있을것이다. 이 부분을 사용자가 자바 버전과 호환이 되는 버전인지를 확인하고 직접 전부 원하는 버전으로 수정을 해줘야 한다. 필자는 자바 11, 스프링 5.3.17버전으로 설정해 주었다.</p>
<p>버전 설정은 자유지만 버전을 설정 한 후 기본적인 워크스페이스 JRE 버전 셋팅, 프로젝트 라이브러리 버전들을 잘 확인해 줘야 한다.</p>
<p><br><br></p>
<p>이제 테스트 프로젝트를 실행해보자.</p>
<p>위의 Tomcat 설정을 진행하면서 프로젝트 모듈을 Tomcat에 임포트 하는 과정이 있을 것이다. Window -&gt; Show View -&gt; Other 에서 Server를 클릭하면 Server 탭이 하나 열리고 추가된 서버가 보일 것이다.</p>
<center><img src="/img/make-spring-project/sts4-server-window.png" width="80%" height="80%"></center>
<p>필자는 톰켓 9.0버전을 사용한다.</p>
<p>Tomcat v9.0 Server at localhost 부분을 더블클릭하면 다음과 같은 화면을 볼수 있다.</p>
<center><img src="/img/make-spring-project/sts4-server-webModules.png" width="80%" height="80%"></center>
<p>여기서 추가된 프로젝트 웹 모듈을 확인할 수 있고, 혹시라도 추가되어 있지 않으면 Add Web Module을 클릭해 프로젝트를 추가해준다.</p>
<p>이후 톰켓을 실행시키면 프로젝트 기본 페이지를 볼수 있다.</p>
<center><img src="/img/make-spring-project/spring-mvc-running.png" width="80%" height="80%"></center>]]></content:encoded></item><item><title>Spring Framework 스프링 프레임워크란?</title><link>https://dig06161.github.io/2022/03/23/what-is-spring/</link><pubDate>Wed, 23 Mar 2022 23:30:00 +0900</pubDate><guid>https://dig06161.github.io/2022/03/23/what-is-spring/</guid><description>&lt;p>스프링 프레임워크란 무엇일까?&lt;/p>
&lt;p>스프링 프레임워크는 JAVA, Groovy, Kotlin으로 웹을 쉽게 개발할 수 있게 한 프레임워크이다. 기본언어로 JAVA를 지원하며, Groovy, kotlin을 지원한다.
&lt;br>&lt;br>&lt;/p>
&lt;center>&lt;img src="https://spring.io/images/spring-logo-9146a4d3298760c2e7e49595184e1975.svg" width="80%" height="80%">&lt;/center>
&lt;br>&lt;br>
스프링의 공식 사이트는 https://spring.io/ 이며 기본적인 개발 가이드와 다양한 프로젝트들이 기술되어 있다.
&lt;p>스프링의 대표적인 프로젝트로 스프링 프레임워크, 스프링 부트, 스프링 시큐리티가 있다.&lt;/p>
&lt;p>스프링 프레임워크는 Spring MVC로 MVC패턴을 이용해 Maven을 통한 의존성을 가지고 개발할수 있는 장점이 있고 상당히 오래 사용되어 오면서 5.대 버전까지 출시를 했다. 다만 단점으로 Maven을 통한 의존성을 사용할떄 버전에 대한 호환성을 장담할 수 없고 이를 개발자가 일일이 확인하고 적용하여야 했다. 또한 많은 부가 기능을 지원하는 대신 많은 설정이 필요해 초기 개발시간을 늘린다. 그리고 WAS를 링크시켜 운용해야 하는 문제가 있다.&lt;/p></description><content:encoded><![CDATA[<p>스프링 프레임워크란 무엇일까?</p>
<p>스프링 프레임워크는 JAVA, Groovy, Kotlin으로 웹을 쉽게 개발할 수 있게 한 프레임워크이다. 기본언어로 JAVA를 지원하며, Groovy, kotlin을 지원한다.
<br><br></p>
<center><img src="https://spring.io/images/spring-logo-9146a4d3298760c2e7e49595184e1975.svg" width="80%" height="80%"></center>
<br><br>
스프링의 공식 사이트는 https://spring.io/ 이며 기본적인 개발 가이드와 다양한 프로젝트들이 기술되어 있다.
<p>스프링의 대표적인 프로젝트로 스프링 프레임워크, 스프링 부트, 스프링 시큐리티가 있다.</p>
<p>스프링 프레임워크는 Spring MVC로 MVC패턴을 이용해 Maven을 통한 의존성을 가지고 개발할수 있는 장점이 있고 상당히 오래 사용되어 오면서 5.대 버전까지 출시를 했다. 다만 단점으로 Maven을 통한 의존성을 사용할떄 버전에 대한 호환성을 장담할 수 없고 이를 개발자가 일일이 확인하고 적용하여야 했다. 또한 많은 부가 기능을 지원하는 대신 많은 설정이 필요해 초기 개발시간을 늘린다. 그리고 WAS를 링크시켜 운용해야 하는 문제가 있다.</p>
<p>스프링 부트는 스프링 프레임워크의 초기 개발셋팅이 오래걸린다는 단점과 WAS를 사용해야 한다는 문제점을 해결해 나온 경량화 버전이라고 생각하면 좋을것 같다. 기본적으로 스프링 프레임워크를 기반으로 만들어진 프레임워크이다. 임베디드 톰켓이 내장되어 있고 초기 개발을 빠르게 진행할수 있게 해준다. 또 Gradle을 통해 기존에 사용하는 라이브러리 버전들과 호환되는 라이브러리를 자동으로 찾아줘 버전에 따른 충돌을 피할 수 있다. 다만 스프링 프레임워크와는 조금 다르다.</p>
<p>스프링 시큐리티는 스프링 프레임워크, 스프링 부트에서 사용할 수 있는 보안 프레임워크이다. 기본적인 로그인 로직과 세션제어, XSRF 방지 토큰, 암호화 로직 등을 지원한다. 스프링 필터 레이어에서 동작하면서 비인가 사용자의 접근에는 에러 페이지를 띄워주는 등 다양한 기능을 제공한다.</p>
<p><br><br></p>
<p>spring을 개발하기에 앞서서 자바와 톰켓이 설치되어 있어야 하며, 스프링 부트 프로젝트 사용 시에는 자바만 있으면 기본적인 구동이 가능하다.</p>
<p>자세한 것은 이후 포스팅을 통해 따로 정리해 보도록 하겠다.</p>
]]></content:encoded></item></channel></rss>