<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>minnidev 님의 블로그</title>
    <link>https://minnidev.tistory.com/</link>
    <description>ㅤ개발일지 &amp;amp; 일상 공간입니다.ㅤ  
&amp;ldquo;Shoot for the moon. Even if you miss, you'll land among the stars.&amp;rdquo;</description>
    <language>ko</language>
    <pubDate>Wed, 5 Aug 2026 21:18:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>minnidev</managingEditor>
    <image>
      <title>minnidev 님의 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/8944307/attach/641e5d2f77bb48c9b43a126d0cb0026f</url>
      <link>https://minnidev.tistory.com</link>
    </image>
    <item>
      <title>Velog에서 블로그 이전중입니다</title>
      <link>https://minnidev.tistory.com/notice/4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;블로그 이전중이라 글들이 다소 난잡하거나 지금과는 내용이 다를 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@coom1222/posts&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@coom1222/posts&lt;/a&gt;&lt;/p&gt;</description>
      <author>minnidev</author>
      <guid isPermaLink="true">https://minnidev.tistory.com/notice/4</guid>
      <pubDate>Mon, 3 Aug 2026 00:39:16 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] AOP, Filter, Interceptor</title>
      <link>https://minnidev.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;*토비의&amp;nbsp;스프링&amp;nbsp;3.1을&amp;nbsp;참고하여&amp;nbsp;정리한&amp;nbsp;자료입니다*&lt;/i&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;1. AOP (관점 지향 프로그래밍)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;개념(Aspect-Oriented Programming): 애플리케이션의 핵심 비즈니스 로직과 공통 기능(부가 기능)을 &lt;b&gt;분리&lt;/b&gt;하여 &lt;b&gt;모듈화&lt;/b&gt;하는 프로그래밍 패러다임.&lt;br /&gt;기존의 OOP(Object-Oriented Programming)과는 구분되는 새로운 특성&lt;br /&gt;&lt;b&gt;Why?&lt;/b&gt; 로깅, 트랜잭션, 보안과 같은 기능들은 여러 비즈니스 로직(Service의 여러 메서드)에 걸쳐 반복적으로 등장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1785684595453&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void upgradeLevels() throws Exception{
TransactionStatus status = this.transactionManager
    .getTransaction(new DefaultTransactionDefinition());
    try {
     // 트랜잭션 경계
     // 비즈니스 로직
     List&amp;lt;User&amp;gt; users = userDao.getAll();
        for (User user : users) {
         if (canUpgradeLevel(user)){
             upgradeLevel(user);
            }
        }
// 비즈니스 로직
        // 트랜잭션 경계
     this.transactionManager.commit(status);    
    } catch (Exception e){
     this.transactionManager.rollback(status);
        throw e;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;&amp;nbsp;기능을 반복해서 작성해야 한다면, 중복된 코드가 많아지게 되고,&amp;nbsp;&amp;nbsp;유지보수가 힘들어지며 소스관리가 되지 않는다.&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;전통적인&amp;nbsp;객체지향&amp;nbsp;기술의&amp;nbsp;설계&amp;nbsp;방법으로는&amp;nbsp;독립적인&amp;nbsp;모듈화가&amp;nbsp;불가능한&amp;nbsp;트랜잭션&amp;nbsp;경계설정과&amp;nbsp;같은&amp;nbsp;부가기능을&amp;nbsp;어떻게&amp;nbsp;모듈화&amp;nbsp;할것인가를&amp;nbsp;연구해온&amp;nbsp;사람들은&amp;nbsp;이런&amp;nbsp;문제를&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;`Aspect`라는&amp;nbsp;특별한&amp;nbsp;이름으로&amp;nbsp;정의했다.&lt;br /&gt;- 'Aspect'란 그 자체로 애플리케이션의 핵심 기능을 담고 있지는 않지만, 애플리케이션을 구성하는 중요한 한 가지 요소이고, 핵심기능에 부가되어 의미를 가지는 특별한 모듈을 가리킨다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp;즉,&amp;nbsp;애플리케이션의&amp;nbsp;핵심적인&amp;nbsp;기능에서&amp;nbsp;부가적인&amp;nbsp;기능을&amp;nbsp;분리해&amp;nbsp;애스펙트라는&amp;nbsp;독특한&amp;nbsp;모듈로&amp;nbsp;만들어&amp;nbsp;설계하고&amp;nbsp;개발하는&amp;nbsp;방법을&amp;nbsp;AOP라&amp;nbsp;부른다.&amp;nbsp;&lt;br /&gt;이를&amp;nbsp;통해&amp;nbsp;핵심기능을&amp;nbsp;설계하고&amp;nbsp;구현할&amp;nbsp;때&amp;nbsp;객체지향적인&amp;nbsp;가치를&amp;nbsp;지킬&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;돕는다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AOP의 용어:&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Target : 부가기능을 부여할 대상. 핵심기능을 담은 클래스일 수도 있지만, 경우에 따라서는 다른 부가기능을 제공하는 프록시 오브젝트일 수도 있다.&lt;/li&gt;
&lt;li&gt;Advice :타깃에게 제공할 부가기능을 담은 모듈이다. 어드바이스는 오브젝트로 정의하기도 하지만, 메소드 레벨에서 정의할 수도 있다.&lt;/li&gt;
&lt;li&gt;Join Point : Advice가 적용될 수 있는 시점을 말한다. 스프링의 프록시 AOP에서 조인 포인트는 메소드의 실행 단계뿐이지만, 타깃 오브젝트가 구현한 인터페이스의 모든 메소드는 조인 포인트가 된다.&lt;/li&gt;
&lt;li&gt;Pointcut : Advice를 적용할 조인 포인트를 선별하는 작업 또는 그 기능을 정의한 모듈을 말한다. &lt;br /&gt;스프링 AOP의 조인 포인트는 메소드의 실행이므로 스프링의 포인트컷은 메소드를 선정하는 기능을 갖는다. 그래서 포인트컷 표현식은 메소드의 실행이라는 의미인 execution으로 시작하고, 메소드의 시그니처를 비교하는 방법을 주로 이용한다. &lt;br /&gt;메소드는 결국 클래스 안에 존재하기에, 메소드 선정이란 작업은 결국 클래스를 선정하고 그 안의 메소드를 선정하는 과정이다.&lt;/li&gt;
&lt;li&gt;Proxy : 우리가 흔히 말하는 프록시와 디자인 패턴에서 말하는 Proxy는 의미가 조금 다르다. 디자인 패턴에서 프록시는 클라이언트와 타깃 사이에 투명하게 존재하며, 부가기능을 제공하는 오브젝트다. &lt;br /&gt;DI를 통해 타깃 대신 클라이언트에 주입되며, 클라이언트의 메소드 호출을 대신 받아 타깃에 위임해주고 그 과정에서 부가기능을 부여한다.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;타깃 오브젝트를 생성하기가 복잡하거나 당장 필요하지 않은 경우에는 꼭 필요한 시점까지 오브젝트를 생성하지 않는것이 좋을 것이다.&lt;br /&gt;그러나 타깃 오브젝트에 대한 레퍼런스는 미리 필요할 수 있는데, 이 때 프록시 패턴이 적용된다.&lt;br /&gt;클라이언트에게 타깃에 대한 레퍼런스를 넘길 때 실제 타깃 오브젝트를 만드는 대신 프록시를 넘긴다.&amp;nbsp;&lt;br /&gt;그리고 프록시의 메소드를 통해 타깃을 사용하려 하면, 그때 프록시가 타깃 오브젝트를 생성, 요청을 위임해준다.&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;Adviser : 포인트컷과 어드바이스를 하나씩 가지고 있는 오브젝트다. 어떤 부가기능(어드바이스)을 어디에(포인트컷) 전달할 것인가를 알고 있는 AOP의 가장 기본이 되는 모듈이다.&lt;/li&gt;
&lt;li&gt;Aspect : 마찬가지로 AOP의 기본 모듈이며 한 개 또는 그 이상의 포인트컷과 어드바이스의 조합으로 만들어진다.&amp;nbsp; 보통 싱글톤 형태의 오브젝트로 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&amp;nbsp;2. Interceptor&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;요청에 대한 작업을 DispatcherServlet과 Handler(Controller)사이에서 전/ 후로 인터셉트,&amp;nbsp;&amp;nbsp;말 그대로 낚아챌 수 있다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;서버에 들어온 Request 객체를 컨트롤러의 핸들러로 도달하기 전에 낚아채서 부가적인 기능이 실행되게끔 만들어준다.&lt;/li&gt;
&lt;li&gt;Interceptor는 여러 개를 등록할 수 있으며, 순차적으로 인터셉터를 거친 후 Controller를 실행한다.&lt;/li&gt;
&lt;li&gt;인터셉터 또한 스프링의 기술이며 Controller 동작 전 후로 동작한다. 스프링의 기술이기에 모든 @Bean에 접근이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 아래와 같은 작업에 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.&amp;nbsp;세부적인&amp;nbsp;보안&amp;nbsp;및&amp;nbsp;인증/인가&amp;nbsp;작업&lt;br /&gt;2.&amp;nbsp;API&amp;nbsp;호출에&amp;nbsp;대한&amp;nbsp;로깅&amp;nbsp;또는&amp;nbsp;검증&lt;br /&gt;3.&amp;nbsp;Controller로&amp;nbsp;넘겨주는&amp;nbsp;정보의&amp;nbsp;가공&lt;br /&gt;&lt;br /&gt;Interceptor는 3개의 메소드(preHandle, postHandle, afterCompletion)를 가지고 있다.&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;preHandle : 핸들러 매핑에서 적절한 핸들러 객체를 결정한 후 핸들러 어댑터가 핸들러를 호출하기 전에 호출된다.(컨트롤러에 들어가기 전이다.)&lt;/li&gt;
&lt;li&gt;postHandle : 핸들러 어댑터가 실제로 핸들러를 호출한 후 Dispatcher Servlet이 view를 렌더링하기 전에 호출된다.&amp;nbsp;&lt;br /&gt;이 메소드를 사용할 땐 각 인터셉터는 실행 체인의 역순으로 실행을 처리한다.&lt;/li&gt;
&lt;li&gt;afterCompletion : 요청 처리가 완료된 후, 즉 Interceptor의 preHandle 메소드가 성공적으로 완료되고 true가 반환된 경우(view 페이지가 렌더링 되고 난 후)에만 호출된다. postHandle과&amp;nbsp;마찬가지로&amp;nbsp;실행&amp;nbsp;체인의&amp;nbsp;역순으로&amp;nbsp;실행을&amp;nbsp;처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Filter&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Filter는 스프링 컨텍스트 외부에 존재하여 스프링에 무관한 자원에 대해 동작 HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 처리 한다.(톰캣과 같은 WAS(웹 애플리케이션 서버)에서 처리해준다.)&lt;/li&gt;
&lt;li&gt;따라서 Request에 대한 조작이 가능하다. Interceptor와 AOP는 모두 Request의 내용을 가지고 추가적인 작업 하지만, Filter는 그 요청 자체를 조작할 수 있다.&lt;/li&gt;
&lt;li&gt;Dispatcher&amp;nbsp;Servlet&amp;nbsp;영역에&amp;nbsp;들어가기&amp;nbsp;전인&amp;nbsp;Front&amp;nbsp;Controller&amp;nbsp;앞&amp;nbsp;범위에서&amp;nbsp;수행되고,&amp;nbsp;필터&amp;nbsp;적용시&amp;nbsp;필터가&amp;nbsp;호출된&amp;nbsp;후에&amp;nbsp;서블릿이&amp;nbsp;호출된다.&lt;br /&gt;&lt;br /&gt;Dispatcher Servlet은 따로 정리해 두었다.(&lt;a href=&quot;https://velog.io/@coom1222/Spring-Dispatcher-Servlet)_&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@coom1222/Spring-Dispatcher-Servlet)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. AOP, Filter, Interceptor 차이와 호출 순서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이 셋은 모두 '중간에 무언가를 처리'하지만, 동작하는 계층(Layer)과 범위가 다르다.&lt;br /&gt;&lt;br /&gt;요청(Request)이&amp;nbsp;들어왔을&amp;nbsp;때의&amp;nbsp;일반적인&amp;nbsp;호출&amp;nbsp;순서는&amp;nbsp;다음과&amp;nbsp;같다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-08-03 오전 12.37.24.png&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxZjbg/dJMcahyAPWu/gGLLiWtViCpxJvRCVZUIAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxZjbg/dJMcahyAPWu/gGLLiWtViCpxJvRCVZUIAk/img.png&quot; data-alt=&quot;Filter&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;Dispatcher&amp;amp;nbsp;Servlet&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;Interceptor&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;AOP&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;Controller&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;AOP&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;Interceptor&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;Dispatcher&amp;amp;nbsp;Servlet&amp;amp;nbsp;-&amp;amp;gt;&amp;amp;nbsp;Filter&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxZjbg/dJMcahyAPWu/gGLLiWtViCpxJvRCVZUIAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxZjbg%2FdJMcahyAPWu%2FgGLLiWtViCpxJvRCVZUIAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;211&quot; data-filename=&quot;스크린샷 2026-08-03 오전 12.37.24.png&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Filter&amp;nbsp;-&amp;gt;&amp;nbsp;Dispatcher&amp;nbsp;Servlet&amp;nbsp;-&amp;gt;&amp;nbsp;Interceptor&amp;nbsp;-&amp;gt;&amp;nbsp;AOP&amp;nbsp;-&amp;gt;&amp;nbsp;Controller&amp;nbsp;-&amp;gt;&amp;nbsp;AOP&amp;nbsp;-&amp;gt;&amp;nbsp;Interceptor&amp;nbsp;-&amp;gt;&amp;nbsp;Dispatcher&amp;nbsp;Servlet&amp;nbsp;-&amp;gt;&amp;nbsp;Filter&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Backend</category>
      <author>minnidev</author>
      <guid isPermaLink="true">https://minnidev.tistory.com/3</guid>
      <comments>https://minnidev.tistory.com/3#entry3comment</comments>
      <pubDate>Mon, 3 Aug 2026 00:37:54 +0900</pubDate>
    </item>
    <item>
      <title>[Java] valueOf() 와 parseInt()</title>
      <link>https://minnidev.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Wrapper&amp;nbsp;클래스를&amp;nbsp;공부하던&amp;nbsp;중,&amp;nbsp;parseInt,&amp;nbsp;valueOf&amp;nbsp;둘&amp;nbsp;다&amp;nbsp;같은&amp;nbsp;정수로&amp;nbsp;출력이&amp;nbsp;되더란다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;무슨&amp;nbsp;차이가&amp;nbsp;있을까?&amp;nbsp;싶어&amp;nbsp;간략하게&amp;nbsp;정리해봤다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;parseInt()&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;먼저 pareInt()를 사용해 String 타입에서 int로 끄집어내 더해보는 예제를 살펴보자.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1785684287848&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//import static java.lang.Integer.parseInt;

public static void main(String[] args) {
        String str1 = &quot;10&quot;;
        String str2 = &quot;20&quot;;

        // 스태틱 import를 사용하는 경우
        // int result = parseInt(str1) + parseInt(str2);

        int result = Integer.parseInt(str1) + Integer.parseInt(str2);

        System.out.println(&quot;result = &quot; + result);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-08-03 오전 12.25.27.png&quot; data-origin-width=&quot;549&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vO5Gy/dJMcahekgmu/6yYvSStkPKlDtNKKHIkgUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vO5Gy/dJMcahekgmu/6yYvSStkPKlDtNKKHIkgUK/img.png&quot; data-alt=&quot;IntelliJ에서&amp;amp;nbsp;parseInt()의&amp;amp;nbsp;정의를&amp;amp;nbsp;찾아봤다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vO5Gy/dJMcahekgmu/6yYvSStkPKlDtNKKHIkgUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvO5Gy%2FdJMcahekgmu%2F6yYvSStkPKlDtNKKHIkgUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;549&quot; height=&quot;270&quot; data-filename=&quot;스크린샷 2026-08-03 오전 12.25.27.png&quot; data-origin-width=&quot;549&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;IntelliJ에서&amp;nbsp;parseInt()의&amp;nbsp;정의를&amp;nbsp;찾아봤다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;이처럼&amp;nbsp;parseInt()는&amp;nbsp;정수&amp;nbsp;표현을&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;문자열을&amp;nbsp;매개변수로&amp;nbsp;넣으면&amp;nbsp;기본&amp;nbsp;자료형(Primitive&amp;nbsp;Type)인&amp;nbsp;int&amp;nbsp;로&amp;nbsp;정수&amp;nbsp;값이&amp;nbsp;반환된다.&lt;br /&gt;&lt;br /&gt;하지만&amp;nbsp;정수&amp;nbsp;표현을&amp;nbsp;할&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;문자열을&amp;nbsp;넣는다면&amp;nbsp;NumberFormatException을&amp;nbsp;발생시킨다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;valueOf&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저&amp;nbsp;정의를&amp;nbsp;보면,&amp;nbsp;반환값이&amp;nbsp;int가&amp;nbsp;아닌&amp;nbsp;Integer라는&amp;nbsp;래퍼&amp;nbsp;클래스인것을&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;즉&amp;nbsp;valueOf는&amp;nbsp;문자열의&amp;nbsp;값을&amp;nbsp;정수형으로&amp;nbsp;반환하지만,참조&amp;nbsp;자료형(Reference&amp;nbsp;Type)인&amp;nbsp;Integer&amp;nbsp;객체로&amp;nbsp;만들어서&amp;nbsp;반환한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-08-03 오전 12.26.02.png&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HeTOP/dJMcafHA56p/EmhKF1vGvgnRueEgfKL5Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HeTOP/dJMcafHA56p/EmhKF1vGvgnRueEgfKL5Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HeTOP/dJMcafHA56p/EmhKF1vGvgnRueEgfKL5Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHeTOP%2FdJMcafHA56p%2FEmhKF1vGvgnRueEgfKL5Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;543&quot; height=&quot;308&quot; data-filename=&quot;스크린샷 2026-08-03 오전 12.26.02.png&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;Integer.valueOf()는&amp;nbsp;문자열의&amp;nbsp;값을&amp;nbsp;정수형으로&amp;nbsp;변환한&amp;nbsp;뒤&amp;nbsp;참조&amp;nbsp;자료형(Reference&amp;nbsp;Type)인&amp;nbsp;Integer&amp;nbsp;객체로&amp;nbsp;만들어서&amp;nbsp;반환합니다.&lt;br /&gt;&lt;br /&gt;그럼 누군가 여기서 의문을 제기할 것이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;??? : 객체로 반환한다구요? 그럼 new Intger() 방식을 사용하여 객체를 생성해야 사용할 수 있지 않나요?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;맞다.&amp;nbsp;원래대로라면&amp;nbsp;객체를&amp;nbsp;생성하여야&amp;nbsp;한다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;하지만&amp;nbsp;자바는&amp;nbsp;Integer.valueOf()를&amp;nbsp;자주&amp;nbsp;사용되는&amp;nbsp;숫자&amp;nbsp;범위(-128~127)의&amp;nbsp;객체를&amp;nbsp;미리&amp;nbsp;만들어&amp;nbsp;재사용(캐싱)하는&amp;nbsp;등&amp;nbsp;성능&amp;nbsp;최적화가&amp;nbsp;되어&amp;nbsp;있다&amp;nbsp;`new&amp;nbsp;Integer()`는&amp;nbsp;사용&amp;nbsp;중단&amp;nbsp;예정이기도&amp;nbsp;하고&amp;nbsp;~~(언제&amp;nbsp;중단&amp;nbsp;예정인지는&amp;nbsp;아무도&amp;nbsp;모른다)~~,&amp;nbsp;성능&amp;nbsp;최적화&amp;nbsp;관점에서&amp;nbsp;&amp;nbsp;`Integer.valueOf(10)`&amp;nbsp;방식을&amp;nbsp;더&amp;nbsp;권장하고&amp;nbsp;있다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;별첨&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;valueOf(),&amp;nbsp;intValue()&amp;nbsp;메서드는&amp;nbsp;추가적으로&amp;nbsp;int를&amp;nbsp;Integer로&amp;nbsp;변환하거나,&amp;nbsp;Integer를&amp;nbsp;int로&amp;nbsp;변환할&amp;nbsp;때&amp;nbsp;사용한다.&amp;nbsp;값을&amp;nbsp;뽑거나(언박싱),&amp;nbsp;값을&amp;nbsp;포장하거나(박싱).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1785684417064&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; public static void main(String[] args) {
        // Primitive -&amp;gt; Wrapper
        int value = 7;
        Integer boxedValue = value;    // 오토 박싱(Auto-boxing) 
        Integer boxedValue =  Integer.valueOf(value)  // 컴파일 단계에서 추가
        
        // Wrapper -&amp;gt; Primitive
        int unboxedValue = boxedValue;   // 오토 언박싱(Auto-unboxing)
        int unboxedValue =  boxedValue.intValue()   // 컴파일 단계에서 추가 
        
        System.out.println(&quot;boxedValue = &quot; + boxedValue);
        System.out.println(&quot;unboxedValue = &quot; + unboxedValue);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language</category>
      <author>minnidev</author>
      <guid isPermaLink="true">https://minnidev.tistory.com/2</guid>
      <comments>https://minnidev.tistory.com/2#entry2comment</comments>
      <pubDate>Mon, 3 Aug 2026 00:27:52 +0900</pubDate>
    </item>
    <item>
      <title>데이터 조회해 출력하기</title>
      <link>https://minnidev.tistory.com/1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Spring CRUD 복습 겸 개념 정리 회고록.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 페이지에서 게시글을 등록하면 서버를 통해 DB에 저장된다. DB에 저장된 데이터를 웹 페이지에 출력하는 과정은 다양한 요소 간 상호 작용으로 이루어진다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등록은 했으니, 조회의 타임라인을 알아보자.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자가 데이터를 조회해 달라고 웹페이지에 URL 요청을 보낸다.(GetMapping)&lt;/li&gt;
&lt;li&gt;서버의 컨트롤러가 요청을 받아 해당 URL에서 찾으려는 데이터 정보를 레포지토리에 전달한다.&lt;/li&gt;
&lt;li&gt;헤포지토리는 정보를 가지고 DB에 데이터 조회를 요청한다.&lt;/li&gt;
&lt;li&gt;DB는 해당 데이터를 찾아 이를 엔티티로 반환한다&lt;/li&gt;
&lt;li&gt;반환된 엔티티는 모델을 통해 뷰 템플리승로 전달된다&lt;/li&gt;
&lt;li&gt;최종 뷰 페이지 완성, 사용자의 화면에 출력된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 흐름이 흘러가고, 이제 실습해보자&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. URL 요청받기&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;@GetMapping()&lt;/b&gt; :특정 url로부터 요청을 받으면 어떤 Controller에서 처리할 지 알아야 한다.&lt;br /&gt;이 때, 특정 url을 요청을 수행할 Controller과 매핑하여 지정하는 어노테이션&lt;br /&gt;여기서는 @GetMapping(&quot;/articles/{id}&quot;)로 지정&lt;/li&gt;
&lt;li&gt;@GetMapping() 어노테이션을 통해 URL요청을 받는다. 이 요청을 받아 수행할 show()메서드를 생성하고, 매개변수로 &lt;b&gt;@PathVariable 어노테이션&lt;/b&gt;을 붙인다.&lt;br /&gt;-&amp;gt; &lt;code&gt;show(@PathVariable Long id)&lt;/code&gt; 이런식으로 경로 변수를 사용해 매핑되는 부분을 편리하게 조회할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 하면 서버의 컨트롤러가 URL 요청을 받는 것까지 작업하였다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 데이터 조회해 출력하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;show() 메서드에서 할 일은 크게 3가지다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;id를 조회해 DB에서 해당 데이터 가져오기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리파지터리에서 DB에 저장된 데이터를 id로 조회할 때 &lt;b&gt;findById()메서드&lt;/b&gt;를 사용한다.&lt;br /&gt;특별히 조회된 데이터가 없는 경우도 처리해야 하므로 &lt;b&gt;orElse()메서드&lt;/b&gt;로 null이 반환되도록 한다&lt;br /&gt;&lt;code&gt;Article articleEntity = articleRepository.findById(id).orElse(null)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;가져온 데이터를 모델에 등록하기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;id로 DB에서 조회한 데이터는 모델에 article이라는 이름으로 등록한다.&lt;br /&gt;&lt;code&gt;model.addAttribute(&quot;article&quot;, articleEntity)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;조회한 데이터를 사용자에게 보여 주기 위한 뷰 페이지 만들고 반환하기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델에 등록한 데이터를 뷰 페이지에서 사용할 수 있게 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;id 를 조회해 데이터 가져오기&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB에서 데이터를 가져오는 주체는 레포지토리이다.&lt;br /&gt;리파지토리의 구현 객체는 @Autowired 어노테이션으로 주입받았었다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 데이터 목록 조회하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단일 데이터&lt;/b&gt;를 조회할 때 엔티티를 반환했다면, 이제 엔티티의 묶음인 리스트를 반환해보자.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;URL 요청받고 데이터 조회해 출력하기&lt;/h3&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;@GetMapping(&quot;/articles&quot;)  // 데이터 목록 요청 접수  
public String index(){  
    // 1. 모든 데이터 가져오기  
    // 2. 모델에 데이터 등록하기  
    // 3. 뷰 페이지 반환하기  
    return &quot;&quot;;  
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;데이터 조회 과정&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자가 웹 페이지에서 데이터를 조회해 달라고 URL요청을 보낸다&lt;/li&gt;
&lt;li&gt;서버의 컨트롤러가 이 요청을 받아 해당 URL에서 찾으려는 데이터 정보(여기서는 id)를 리파지토리에 전달한다&lt;/li&gt;
&lt;li&gt;리파지터리는 정보(id)를 가지고 DB에 데이터 조회를 요청한다.&lt;/li&gt;
&lt;li&gt;DB는 해당 데이터를 찾아 이를 엔티티로 반환한다.&lt;/li&gt;
&lt;li&gt;반환된 엔티티는 모델을 통해 뷰 템플릿으로 전달된다.&lt;/li&gt;
&lt;li&gt;최종적으로 결과 뷰 페이지가 완성돼 사용자 화면에 출력한다&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;@GetMapping(&quot;/articles&quot;)  // 데이터 목록 요청 접수  
public String index(Model model){  
    // 1. 모든 데이터 가져오기  
    List&amp;lt;Article&amp;gt; articleEntityList = articleRepository.findAll();  
    // 2. 모델에 데이터 등록하기  
    model.addAttribute(&quot;articleList&quot;, articleEntityList);  
    // 3. 뷰 페이지 반환하기  
    return &quot;articles/index&quot;;  
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;List&amp;lt;Article&amp;gt; articleEntityList = articleRepository.findAll();&lt;/code&gt;의 경우, ArticleRepository에서 ArticleRepository가 CrudRepository를 상속받고 있다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;여기서 CrudRepository의 메서드를 오버라이딩해주자.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;findAll() 메서드의 반환값은 기본적으로 &lt;code&gt;Article&lt;/code&gt;의 Iterable 타입으로 반환하게 되어 있다. 이를 ArrayList로 바꾸어 타입 불일치 문제를 해결할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@PathVariable : URL 요청으로 들어온 전달값을 컨트롤러의 매개변수로 가져오는 어노테이션&lt;/li&gt;
&lt;li&gt;@findById() : JPA의 CrudRepository가 제공하는 메서드로, 특정 엔티티의 id값을 기준으로 데이터를 찾아 Optional 타입으로 변환한다.&lt;/li&gt;
&lt;li&gt;@findAll() : JPA의 CrudRepository가 제공하는 메서드로, 특정 엔티티를 모두 가져와 Iterable 타입으로 반환한다&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복습하면서 JPA와 타입변환, 인터페이스에 대한 개념도 다시금 들춰보게 되었다.&lt;/p&gt;</description>
      <category>Backend</category>
      <author>minnidev</author>
      <guid isPermaLink="true">https://minnidev.tistory.com/1</guid>
      <comments>https://minnidev.tistory.com/1#entry1comment</comments>
      <pubDate>Fri, 31 Jul 2026 11:49:39 +0900</pubDate>
    </item>
  </channel>
</rss>