<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발냥발</title>
    <link>https://coding-nyan.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 4 Aug 2026 00:16:19 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>moongomi</managingEditor>
    <item>
      <title>[TypeScript] 정적 타입과 동적 타입</title>
      <link>https://coding-nyan.tistory.com/167</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;자바스크립트를 사용할 때는 딱히 변수의 타입을 고려하지 않고 코드를 작성해도 괜찮습니다. 그러나 개발자가 타입을 신경쓰지 않을 뿐이지. 실제로는 타입이 존재합니다. 타입은 타입이 결정되는 시점에 따라서 정적 타입과 동적 타입으로 분류됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정적 타입(Static Type)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 타입에서는 모든 변수의 타입이 컴파일 시점에 결정됩니다. 자바에서 흔히 String str = &quot;Hi&quot; 라고 선언해주듯이. 개발할때 대놓고 타입을 명시하는 애들이 정적 타입 언어에 속합니다. 타입스크립트에서도 정적 타입을 제공해주고 있구요. 타입을 명시해줘야 된다는 귀찮음이 있지만 컴파일 시점에 타입 에러를 발견할 수 있기 때문에&lt;b&gt; 프로그램의 안정성을 보장&lt;/b&gt;할 수 있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;타입 안정성 &lt;/b&gt;&lt;/span&gt;: 변수의 타입이 명시되어 있기 때문에 예기치 않은 타입 변환 오류를 줄일 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;가독성 향상&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 타입을 명시함으로 코드의 가독성을 높여 유지보수가 용이해집니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;타입스크립트 정적 타입 예시 코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1711871623859&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 정적 타입을 사용한 예시 코드

// 변수의 타입을 명시적으로 선언
let userName: string = &quot;John&quot;;
let userAge: number = 30;
let isAdmin: boolean = false;

// 함수의 매개변수와 반환값의 타입을 명시적으로 선언
function greet(name: string): string {
    return &quot;Hello, &quot; + name;
}

// 잘못된 타입 사용 시 컴파일러가 오류를 발생시킴
// userAge = &quot;30&quot;; // 에러: Type '&quot;30&quot;' is not assignable to type 'number'.

console.log(greet(userName)); // &quot;Hello, John&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;동적 타입(Dynamic Type)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 타입이 런타임에 결정됩니다. 파이썬과 자바스크립트가 여기에 해당됩니다. 개발자가 하나하나 타입을 정의해줄 필요가 없죠. 다만 프로그램을 실행할 때 타입 에러가 발견될 위험이 있기에 안정적이지 못합니다. 예를 들어서 아래와 같은 add 메서드가 있다고 생각해보죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1711871081842&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function add(a,b){
    return a+b;
}

add(3,4) //7
add(&quot;Hello&quot;,&quot; world&quot;) //Hello World&lt;/code&gt;&lt;/pre&gt;
&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;개발자는 Number 타입의 매개변수가 들어올 것을 가정하고 코드를 작성했는데 실제로 런타임에는 String형이 들어갈 수 있습니다. 그러면 예상치 못한 결과를 반환하게 됩니다. 지금은 문자열이 Hello 와 world였지만 만약 숫자 3과 4를 서버에서 문자 타입으로 받았다면 어떻게 됐을까요?? &lt;b&gt;&quot;34&quot;&lt;/b&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;&amp;nbsp;&lt;/p&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;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;유연성 &lt;/b&gt;&lt;/span&gt;: 변수의 타입을 명시적으로 선언하지 않기에 자유롭게 타입의 변경이 가능합니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;빠른 개발&lt;/b&gt;&lt;/span&gt; : 코드 작성이 더 간편하고 간단하고 빨라지죠.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;자바스크립트 동적 타입 예시 코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1711871652475&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 동적 타입을 사용한 예시 코드

// 변수의 타입을 명시적으로 선언하지 않음
let userName = &quot;John&quot;;
let userAge = 30;
let isAdmin = false;

// 함수의 매개변수와 반환값의 타입을 명시적으로 선언하지 않음
function greet(name) {
    return &quot;Hello, &quot; + name;
}

// 변수의 타입이 런타임 시점에 결정됨
userName = 42; // 유효함
userAge = &quot;30&quot;; // 유효함
isAdmin = &quot;true&quot;; // 유효함

console.log(greet(userName)); // &quot;Hello, 42&quot;&lt;/code&gt;&lt;/pre&gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;모든 타입을 허용하는 any&lt;/b&gt;&lt;/h4&gt;
&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;b&gt;any&lt;/b&gt;라는 타입을 통해서 모든 타입을 허용이 가능하고 이로 인해 number형 string형 boolean형 다양한 형태로 사용이 가능합니다. 물론 any를 쓰면 정적 타입의 장점을 잃어버리기는 하나. 타입스크립트에서도 동적 타입을 사용하는 방법을 알려드리고자 소개했습니다.&lt;/p&gt;</description>
      <category>web/Typescript</category>
      <category>javascript</category>
      <category>js</category>
      <category>TS</category>
      <category>Typescript</category>
      <category>변수</category>
      <category>자바스크립트</category>
      <category>타입</category>
      <category>타입스크립트</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/167</guid>
      <comments>https://coding-nyan.tistory.com/167#entry167comment</comments>
      <pubDate>Sun, 31 Mar 2024 16:58:31 +0900</pubDate>
    </item>
    <item>
      <title>자바스크립트 폴리필과 트랜스파일</title>
      <link>https://coding-nyan.tistory.com/166</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;폴리필(Polyfill)이란?&lt;/span&gt;&lt;/h3&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;폴리필은 기본적으로 지원하지 않는 &lt;b&gt;이전 브라우저에서 최신 기능을 제공하는 데 필요한 코드&lt;/b&gt;를 의미합니다. 웹 환경을 빠르게 변화하고 있습니다. ES6 문법이 나오고 TypeScript가 나오고 계속해서 다양한 기술들이 나오겠죠. 이 기술들은 각각의 디바이스와 브라우저를 통해 클라이언트에 전달이 됩니다. 그렇지만 과연 브라우저에 내장된 자바스크립트 엔진이 항상 최신화된 코드를 읽을 수 있을까요?? 실제로 지원이 중단된 internet explorer의 경우 최신 코드를 읽지 못합니다. 이러한 문제를 해결하기 위해 폴리필이 사용됩니다. 폴리필을 사용하면 제가 사용하려는 기능을 지원하지 않는 브라우저에서도 그 기능을 쓸 수 있게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;트랜스파일(Transpile)이란?&lt;/span&gt;&lt;/h3&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;트랜스파일은 한 프로그래밍 언어로 작성된 소스코드를 읽어서 동일하거나 다른 프로그래밍 언어로 동일한 결과를 도출하는 소스코드를 생성하는 과정을 의미합니다. 자바스크립트에서는 주로 &lt;b&gt;최신 버전의 언어로 작성된 코드를 이전 버전의 언어로 변환&lt;/b&gt;할때 사용됩니다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어서 ES6+로 작성된 JavaScript 코드를 ES5로 간단히 트랜스파일할 수 있다고 합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;폴리필과 트랜스파일의 관계&lt;/span&gt;&lt;/h3&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;폴리필과 트랜스파일은 자바스크립트에서 서로 보완적인 역할을 하빈다. 트랜스파일이 최신 자바스크립트 문법을 이전 버전의 자바스크립트로 변환을 해준다면, 폴리필은 옛날 브라우저에서도 최신 자바스크립트 기능을 사용할 수 있게 하죠. 이 둘을 함께 사용해서 최신 자바스크립트 기능을 자유롭게 사용하면서도, 다양한 브라우저와 환경에서 원활하게 동작할 수 있도록 유도가 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;대표적인 폴리필과 트랜스파일&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;대표적인 폴리필 라이브러리로는 core.js와 polyfill.io가 있습니다.&amp;nbsp;&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;트랜스파일의 가장 대표적인 예시는 Babel입니다.&amp;nbsp;&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리액트에서 자주 문법 오류를 보여주던 바로 그 라이브러리입니다. 그동안 Babel이 대체 뭔데 날 이렇게 귀찮게 만드나 했는데 트랜스파일이라는 것을 오늘 처음 알게 되었네요.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Babel은 .babelrc 파일을 통해서 코드를 어떻게 변환할건지 세팅을 해줘야 하구요. npx bable &amp;lt;파일명/디렉터리명&amp;gt; 을 입력하면 터미널에 변환 결과가 출력된다고 합니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>web/javascript</category>
      <category>javascript</category>
      <category>js</category>
      <category>polyfill</category>
      <category>transpile</category>
      <category>자바스크립트</category>
      <category>트랜스파일</category>
      <category>폴리필</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/166</guid>
      <comments>https://coding-nyan.tistory.com/166#entry166comment</comments>
      <pubDate>Sat, 30 Mar 2024 22:18:52 +0900</pubDate>
    </item>
    <item>
      <title>[Spring boot] 포트 변경 방법</title>
      <link>https://coding-nyan.tistory.com/165</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;기본적으로 Spring boot 내장 톰캣을 실행하면 8080포트로 서버가 올라갑니다. 서버 포트를 간단하게 바꾸는 다양한 방법에 대해서 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. application.properties 수정하기&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1709128281132&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=9999&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. vm option 변경하기&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1709128488332&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-Dserver.port=9999&lt;/code&gt;&lt;/pre&gt;
&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;두 가지 방식 중에서 편한 방식으로 사용하면 간단하게 톰캣의 서버 포트를 수정할 수 있습니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&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-origin-width=&quot;1188&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G5uJg/btsFqZztB7u/STis77QYPX7jOI0TQnoJEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G5uJg/btsFqZztB7u/STis77QYPX7jOI0TQnoJEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G5uJg/btsFqZztB7u/STis77QYPX7jOI0TQnoJEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG5uJg%2FbtsFqZztB7u%2FSTis77QYPX7jOI0TQnoJEK%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;1188&quot; height=&quot;592&quot; data-origin-width=&quot;1188&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;추가적으로 공식 문서에 따르면 server.port=-1로 설정하는 방식을 언급합니다.&amp;nbsp;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;WebApplicationContext의 생성을 허용하되 내장된 톰캣 서버의 HTTP endpoint를 비활성화하는 옵션입니다. 이렇게 되면 웹 서버를 시작하지 않고 application context가 초기화하는 시나리오를 테스트하는데 유용합니다.&amp;nbsp;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;예를 들어서 테스트 환경에서 application context 컴포넌트나 서비스나 기타 등등의 빈을 웹 서버를 키기 않고 로딩시키고 싶을 때가 있습니다. 이럴때 쓰면 좋은 옵션이라고 하네요.&lt;/span&gt;&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;단위 테스트 코드를 작성할때 단순히 서비스 로직만 테스트 하고 싶은 경우 제가 원하는 빈만 초기화할 수 있으니 쓸모있겠네요.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>web/spring&amp;amp;spring boot</category>
      <category>PORT</category>
      <category>spring</category>
      <category>spring boot</category>
      <category>spring boot port</category>
      <category>스프링부트</category>
      <category>스프링부트포트</category>
      <category>스프링붙</category>
      <category>포트</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/165</guid>
      <comments>https://coding-nyan.tistory.com/165#entry165comment</comments>
      <pubDate>Wed, 28 Feb 2024 23:07:25 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] HTTPS 활성화</title>
      <link>https://coding-nyan.tistory.com/164</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Spring Boot 애플리케이션에서 &lt;b&gt;Self-Signed SSL&lt;/b&gt; 인증서를 사용해 HTTPS를 설정하는 방법에 대해 알아보겠습니다. Self-Signed SSL 인증서는 테스트 환경이나 개발 환경에서 테스트할때 쓰입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Self-Signed SSL 인증서 발급 받기&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Self-Signed SSL 인증서는 PKCS12(Public Key Cryprographic Standards) 와 Java KeyStore 방식을 많이 사용합니다. 둘다 비슷합니다. 다만 Java KeyStore는 자바 언어에만 국한되서 사용할 수 있습니다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;PKCS12로 발급&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1707743231695&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;keytool -genkeypair -alias test -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore 
test.p12 -validity 3650&lt;/code&gt;&lt;/pre&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;JKS로 발급&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1707743278595&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;keytool -genkeypair -alias test -keyalg RSA -keysize 2048 
-keystore test.jks -validity 3650&lt;/code&gt;&lt;/pre&gt;
&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;저 명령어를 입력하고 나면 이름이라던가 사는 지역 등 다양하게 물어보는데 저는 로컬이라서 다 그냥 대충 답변했습니다.&lt;/span&gt;&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;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;대부분의 블로그 글을 보니까 PKCS12가 업계 표준이기에 &lt;b&gt;PKCS12&lt;/b&gt; 방식을 사용하기를 권장하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Spring Boot 프로젝트에 인증서 추가하기&lt;/span&gt;&lt;/h3&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;앞서 발급 받은 인증서를 애플리케이션에 추가해줘야 쓸 수 있겠죠. Spring Boot의 경우 간단한 설정을 통해서 인증서를 바로 프로젝트에 적용시킬 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1707743437837&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Spring Boot Reference Documentation&quot; data-og-description=&quot;This section goes into more detail about how you should use Spring Boot. It covers topics such as build systems, auto-configuration, and how to run your applications. We also cover some Spring Boot best practices. Although there is nothing particularly spe&quot; data-og-host=&quot;docs.spring.io&quot; data-og-source-url=&quot;https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-ssl&quot; data-og-url=&quot;https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-ssl&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-ssl&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-ssl&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot Reference Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This section goes into more detail about how you should use Spring Boot. It covers topics such as build systems, auto-configuration, and how to run your applications. We also cover some Spring Boot best practices. Although there is nothing particularly spe&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.spring.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;제 경우에는 제가 만든 test.p12를 src/main/resources/keystore 아래에 두었습니다&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 다음으로는 &lt;b&gt;application.properties&lt;/b&gt; 파일을 수정해주면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707743557059&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server.port=8443
server.ssl.enabled=true #Spring Security를 사용하는 경우 HTTPS 요청만 허용하도록 해주는 설정
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore/test.p12
server.ssl.key-store-password=password
server.ssl.key-alias=test&lt;/code&gt;&lt;/pre&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비밀번호의 경우 인증서 발급 시에 적어둔 그 비밀번호를 적어주셔야합니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이렇게만 해주면 &lt;b&gt;http://localhost:8080&lt;/b&gt; 에 접근하면 &lt;b&gt;Bad Request&lt;/b&gt;가 뜨게 됩니다.다음으로 &lt;b&gt;https://localhost:8443&lt;/b&gt; 으로 접근하면 로컬에서 만든 인증서라서 &lt;b&gt;안전하지 않다&lt;/b&gt;고는 뜨는데 이런 방식으로 HTTPS를 연결하면 되는구나~를 파악할 수 있습니다. &lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반적으로는 공식 SSL 인증서의 경우 다 공개되어 있어서 앵간한 브라우저들은 기본적으로 알고 있는데 로컬에서 만든건 인지하지 못해서 뜨는 현상입니다. &lt;b&gt;실제 운영에서는 공인된 인증서를 발급받아서 사용하시면 됩니다.&lt;/b&gt;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>web/spring&amp;amp;spring boot</category>
      <category>https</category>
      <category>spring</category>
      <category>spring boot</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/164</guid>
      <comments>https://coding-nyan.tistory.com/164#entry164comment</comments>
      <pubDate>Mon, 12 Feb 2024 22:23:22 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Mybatis의 snake case를 camel case로 자동 변환하기</title>
      <link>https://coding-nyan.tistory.com/163</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;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;회사에서 Mybatis를 사용하고 있습니다. DataBase에서는 컬럼명을 snake case로 쓰고 자바에서는 camel case로 필드 이름을 정해주고 있어요. 객체에 값을 제대로 매핑해주기 위해서 쿼리 조회 시 일일이 Alias로 camel case를 적어주고 있었습니다. 그런데 알고보니 몇 가지 세팅만 해주면 이런 노가다는 필요없다는 사실 알고 계셨나요?? 충격을 먹어서 바로 찾아봤습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;문제 상황&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우선, 왜 이러한 설정이 필요한지에 대해 이해해봅시다. 이미 서론에서 언급하긴 했는데 더 자세하게 알아볼게요. &lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;보통 자바에서는 변수명을 camel case로 표현합니다. 예를 들어, userName, userEmail과 같이 말이죠. 반면에, 데이터베이스에서는 snake case를 흔히 사용합니다. 예를 들면, user_name, user_email 등입니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;따라서 자바 객체와 데이터베이스 간에 자료형을 변환할 때, 이 두 가지 스타일의 차이점이 종종 문제가 될 수 있습니다. 이를 해결하기 위한 가장 간단한 방법은 컬럼명을 직접 매핑하는 것입니다. 하지만 이는 코드의 중복을 증가시키며, 유지 보수를 어렵게 만듭니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해결 방법&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 문제를 해결하기 위해 MyBatis는 mybatis.configuration.map-underscore-to-camel-case라는 설정을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Spring Boot의 application.properties 또는 application.yml 파일에 다음과 같이 설정을 추가하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;application.properties의 경우&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;mybatis.configuration.map-underscore-to-camel-case=true&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;application.yml의 경우&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;mybatis:
  configuration:
    map-underscore-to-camel-case: true&lt;/code&gt;&lt;/pre&gt;
&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 설정을 추가하면, MyBatis는 자동으로 snake case 컬럼명을 camel case 필드명으로 매핑해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;mybatis-config.xml 사용&lt;/span&gt;&lt;/h3&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;혹은 위의 경우로 해결되지 않는다면 mybatis-config.xml을 추가하는 방법을 사용하시면 됩니다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;같은 위치에(src/main/resources/mybatis-config.xml) 새 파일을 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1706362637300&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE configuration PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot; &quot;http://mybatis.org/dtd/mybatis-3-config.dtd&quot;&amp;gt;

&amp;lt;configuration&amp;gt;
	&amp;lt;settings&amp;gt;
    	&amp;lt;!-- snake to camel --&amp;gt;
		&amp;lt;setting name=&quot;mapUnderscoreToCamelCase&quot; value=&quot;true&quot;/&amp;gt;
        &amp;lt;!-- 쿼리 결과가 null인 경우 누락되지 않도록 --&amp;gt;
		&amp;lt;setting name=&quot;callSettersOnNulls&quot; value=&quot;true&quot;/&amp;gt;
        &amp;lt;!-- 쿼리에 보내는 파라미터가 null인 경우 에러 발생 방지 --&amp;gt;
		&amp;lt;setting name=&quot;jdbcTypeForNull&quot; value=&quot;NULL&quot;/&amp;gt;
	&amp;lt;/settings&amp;gt;
&amp;lt;/configuration&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;저는 여기서 mapUnderscoreToCamelCase만 사용중입니다. 그 외의 설정은 필요하신 분들만 쓰시면 됩니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다음으로는 DB관련 Config 클래스에서 mybatis-config.xml 경로를 추가해주면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706363227255&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class DatabaseConfig {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setConfigLocation(applicationContext.getResource(&quot;classpath:mybatis-config.xml&quot;));
        sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources(&quot;classpath:mappers/*Mapper.xml&quot;));

        return sqlSessionFactoryBean.getObject();
    }
}&lt;/code&gt;&lt;/pre&gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;주의 사항&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 설정은 대부분의 경우에서 잘 동작하지만, 모든 상황에서 완벽하게 동작하는 것은 아닙니다. 예를 들어, user_name과 userName은 잘 매핑되지만, user_Name과 같은 경우에는 예상대로 동작하지 않을 수 있습니다.(애초에 이런 케이스가 있는게 이상하지만) 이러한 상황에서는 직접 매핑을 해주어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이렇게 Spring Boot와 MyBatis에서 snake case를 camel case로 자동 변환하는 방법에 대해 알아보았습니다. 이 설정을 통해 코드의 중복을 줄이고 유지 보수를 용이하게 할 수 있습니다. 다만, 꼭 모든 상황을 완벽하게 커버하지는 못하니, 특정 상황에 따라 직접 매핑이 필요할 수 있음을 기억해주세요.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다음 시간에는 또 다른 유용한 팁으로 찾아뵙겠습니다. 그럼, 행복한 코딩 시간 되세요!&lt;/span&gt;&lt;/p&gt;</description>
      <category>web/spring&amp;amp;spring boot</category>
      <category>camel</category>
      <category>mybatis</category>
      <category>SNAKE</category>
      <category>spring</category>
      <category>spring boot</category>
      <category>xml</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/163</guid>
      <comments>https://coding-nyan.tistory.com/163#entry163comment</comments>
      <pubDate>Sat, 27 Jan 2024 22:50:49 +0900</pubDate>
    </item>
    <item>
      <title>CDN(Content Delivery Network) 이해하기</title>
      <link>https://coding-nyan.tistory.com/162</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;lambda-with-ts_복사본-001.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b99AoH/btsDHq8wdDt/VJzYCiUN0hL2jHZ5vDIuA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b99AoH/btsDHq8wdDt/VJzYCiUN0hL2jHZ5vDIuA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b99AoH/btsDHq8wdDt/VJzYCiUN0hL2jHZ5vDIuA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb99AoH%2FbtsDHq8wdDt%2FVJzYCiUN0hL2jHZ5vDIuA1%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;500&quot; height=&quot;500&quot; data-filename=&quot;lambda-with-ts_복사본-001.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN이란 무엇인가?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN은&amp;nbsp;Content&amp;nbsp;Delivery&amp;nbsp;Network의&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;시스템입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN의 작동 원리&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN은&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;줄여줍니다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용자가 웹사이트에 접속하려고 요청을 보내면, CDN 으로 배치된 가장 가까운 캐시 서버에서 해당 콘텐츠를 찾아 사용자에게 전송합니다. 이렇게 하면 콘텐츠를 전달하는 시간이 줄어들어 웹사이트의 로딩 시간이 단축됩니다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;또한, CDN 캐시 서버가 콘텐츠를 복제하고 분산하여 콘텐츠를 제공하고 있습니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CDN-설명용-그림-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VaaIM/btsDIw1HM7q/UL2XzbrWCJZt2VGxK1U4FK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VaaIM/btsDIw1HM7q/UL2XzbrWCJZt2VGxK1U4FK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VaaIM/btsDIw1HM7q/UL2XzbrWCJZt2VGxK1U4FK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVaaIM%2FbtsDIw1HM7q%2FUL2XzbrWCJZt2VGxK1U4FK%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;1260&quot; height=&quot;891&quot; data-filename=&quot;CDN-설명용-그림-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN의 장점&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;성능&amp;nbsp;개선&lt;/b&gt;:&amp;nbsp;사용자에게&amp;nbsp;가까운&amp;nbsp;곳에서&amp;nbsp;콘텐츠를&amp;nbsp;제공함으로써&amp;nbsp;웹페이지의&amp;nbsp;로딩&amp;nbsp;시간을&amp;nbsp;줄여줍니다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;스케일링&lt;/b&gt;:&amp;nbsp;CDN은&amp;nbsp;사용자&amp;nbsp;수가&amp;nbsp;증가하더라도&amp;nbsp;안정적인&amp;nbsp;서비스를&amp;nbsp;제공할&amp;nbsp;수&amp;nbsp;있습니다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;보안&amp;nbsp;강화&lt;/b&gt;:&amp;nbsp;DDoS&amp;nbsp;공격과&amp;nbsp;같은&amp;nbsp;보안&amp;nbsp;위협으로부터&amp;nbsp;웹사이트를&amp;nbsp;보호할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;대역폭 최적화&lt;/b&gt;: 사용자가 콘텐츠를 요청할 때, CDN은 최적의 서버에서 제공함으로 대역폭을 효율적으로 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;서버 부하 분산&lt;/b&gt;: CDN은 원본 서버에 가해지는 부하를 줄일 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN의 핵심 구성 요소&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Edge Servers&lt;/b&gt;: CDN의 핵심 구성 요소로, 전 세계 여러 지역에 위치한 Edge Server는 콘텐츠를 저장하고 사용자에게 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Origin Servers&lt;/b&gt;: 실제 콘텐츠가 저장되어 있는 서버&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Cache Control&lt;/b&gt;: CDN은 HTTP 헤더를 통해 어떤 콘첸츠를 캐싱하고 얼마나 오랫동안 유지할지 제어합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Anycast Routing&lt;/b&gt;: Anycast 기술을 사용하여 사용자의 요청을 가장 가까운 에지 서버로 라우팅합니다.&lt;/span&gt;&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;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN은&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;가지고&amp;nbsp;있습니다. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이&amp;nbsp;글이&amp;nbsp;CDN에&amp;nbsp;대한&amp;nbsp;이해에&amp;nbsp;도움이&amp;nbsp;되었기를&amp;nbsp;바랍니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;* 사용한 이모티콘&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://www.flaticon.com/kr/free-icon/cdn_10988189?term=cdn&amp;amp;page=1&amp;amp;position=3&amp;amp;origin=search&amp;amp;related_id=10988189&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.flaticon.com/kr/free-icon/cdn_10988189?term=cdn&amp;amp;page=1&amp;amp;position=3&amp;amp;origin=search&amp;amp;related_id=10988189&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://www.flaticon.com/kr/free-icon/servers_622397?term=%EC%84%9C%EB%B2%84&amp;amp;page=1&amp;amp;position=2&amp;amp;origin=search&amp;amp;related_id=622397&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.flaticon.com/kr/free-icon/servers_622397?term=%EC%84%9C%EB%B2%84&amp;amp;page=1&amp;amp;position=2&amp;amp;origin=search&amp;amp;related_id=622397&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://www.flaticon.com/kr/free-icon/user_747376?term=%EC%82%AC%EC%9A%A9%EC%9E%90&amp;amp;page=1&amp;amp;position=1&amp;amp;origin=search&amp;amp;related_id=747376&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.flaticon.com/kr/free-icon/user_747376?term=%EC%82%AC%EC%9A%A9%EC%9E%90&amp;amp;page=1&amp;amp;position=1&amp;amp;origin=search&amp;amp;related_id=747376&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>TechTalk</category>
      <category>cache</category>
      <category>CDN</category>
      <category>서버</category>
      <category>캐시</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/162</guid>
      <comments>https://coding-nyan.tistory.com/162#entry162comment</comments>
      <pubDate>Sun, 21 Jan 2024 16:07:06 +0900</pubDate>
    </item>
    <item>
      <title>추상클래스의 객체 생성</title>
      <link>https://coding-nyan.tistory.com/161</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 자바 이론 공부를 하다보면 추상클래스는 객체 생성이 불가능하다고 설명합니다. 오늘은 이와 관련해서 개인적으로 궁금했던 몇 가지를 정리했습니다.&lt;/p&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;스프링 부트 시리즈_복사본 (1)-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjAMQc/btszklXw1OU/5KF1Gy50EKwk1YiJCHHukK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjAMQc/btszklXw1OU/5KF1Gy50EKwk1YiJCHHukK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjAMQc/btszklXw1OU/5KF1Gy50EKwk1YiJCHHukK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjAMQc%2FbtszklXw1OU%2F5KF1Gy50EKwk1YiJCHHukK%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;1260&quot; height=&quot;891&quot; data-filename=&quot;스프링 부트 시리즈_복사본 (1)-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;관련 키워드 : 참조 배열, 익명 클래스&lt;/i&gt; &lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;추상 클래스 Animal&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1698543947443&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract class Animal {
    abstract void bark();
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구현 클래스 Cat&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1698543983565&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Cat extends Animal{
    @Override
    void bark() {
        System.out.println(&quot;냥냥&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구현 클래스 Dog&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1698544021564&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Dog extends Animal{

    @Override
    void bark() {
        System.out.println(&quot;멍멍&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&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;오늘 다뤄볼 예제 클래스들 입니다. 복잡한 기능은 없고 간단하게 추상 메서드를 Override를 하고 있습니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;main 메서드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1698544071060&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) {
    Animal[] animals = new Animal[2];
    animals[0] = new Dog();
    animals[1] = new Cat();
    Animal animal = new Animal() {
        @Override
        void bark() {
            System.out.println(&quot;이게 뭐야&quot;);
        }
    };

    animals[0].bark();
    animals[1].bark();
    animal.bark();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main에서는 추상 클래스인 Animal의 참조 배열인 animals를 선언합니다. 그리고 animals 배열 각각에 Dog나 Cat 객체를 생성해주죠.&lt;/p&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-origin-width=&quot;480&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu2JGV/btszj8YaGFj/cJZDp9R2zYzCdwwr7TolNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu2JGV/btszj8YaGFj/cJZDp9R2zYzCdwwr7TolNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu2JGV/btszj8YaGFj/cJZDp9R2zYzCdwwr7TolNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu2JGV%2Fbtszj8YaGFj%2FcJZDp9R2zYzCdwwr7TolNK%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;480&quot; height=&quot;220&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;참조 배열?? 추상 클래스의 객체??&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 첫 번째 의문이 들었던 점은. 추상 클래스는 new 키워드를 못쓴다고 들었는데 저기서는 쓸 수 있다는 점이 궁금했습니다. 위에서도 언급했지만 animals는 참조 배열입니다. Animal 클래스의 객체를 직접 생성하는 것이 아니라 그 클래스의 객체를 저장할 수 있게 하는 배열이에요.&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;b&gt;참조 배열&lt;/b&gt;이란 객체의 주소를 저장하는 배열입니다. 예시에서는 Animal 객체의 주소를 저장하기 위한 배열이 되겠군요. &lt;b&gt;객체&lt;/b&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;결론을 말씀드리면 추상 클래스에 무조건 new 키워드를 쓰지 못하는 것은 아닙니다. 그게 참조 배열인 경우에는 객체 생성과는 달리 제대로 쓸 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;추상 클래스는 언제나 객체 생성을 못하는가??&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 쓴 예제 코드에서 Animal animal = new Animal() 부분을 봐주세요. 원래는 메서드의 구현체가 존재하지 않기에 에러가 생기게 됩니다. 그러나 제가 작성한 코드에서는 객체 생성과 동시에 메서드를 구현하고 있죠?? 이런 경우에는 에러가 발생하지 않습니다.&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;b&gt;익명 클래스&lt;/b&gt;를 제공하고 있습니다. 추상 클래스로 익명 객체를 생성하면서 동시에 메서드를 오버라이딩해준다면 이때는 객체로 만들 수 있습니다. 따라서 현재 animal은 Animal 클래스의 익명 클래스 객체가 됩니다. 이런 방식으로 익명 클래스를 활용하면 추상 클래스도 인스턴스화가 가능해집니다.&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <category>익명 객체</category>
      <category>익명 클래스</category>
      <category>인스턴스</category>
      <category>자바</category>
      <category>참조 배열</category>
      <category>추상클래스</category>
      <category>추상화</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/161</guid>
      <comments>https://coding-nyan.tistory.com/161#entry161comment</comments>
      <pubDate>Sun, 29 Oct 2023 11:08:42 +0900</pubDate>
    </item>
    <item>
      <title>컨테이너 기술이란?</title>
      <link>https://coding-nyan.tistory.com/160</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;WSL2-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oBCga/btspXl5ihhM/SJPdtJKHV1qYfWKYz6HXXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oBCga/btspXl5ihhM/SJPdtJKHV1qYfWKYz6HXXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oBCga/btspXl5ihhM/SJPdtJKHV1qYfWKYz6HXXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoBCga%2FbtspXl5ihhM%2FSJPdtJKHV1qYfWKYz6HXXk%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;1260&quot; height=&quot;891&quot; data-filename=&quot;WSL2-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너 기술은 최근 몇 년 간 빠르게 성장하고 있는 혁신적인 기술로, 개발자와 운영팀에게 애플리케이션 배포와 관리를 획기적으로 단순화하고 효율화하는 도구입니다. 이 기술은 가상화 기술을 기반으로 하며, 애플리케이션과 그에 필요한 모든 종속성을 격리된 환경에 포장하는 것을 목표로 합니다. 이러한 접근 방식은 시스템 구축, 확장성, 유지보수 및 보안에 큰 이점을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;1. 컨테이너란 무엇인가?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;개발자로 일하게 되면서 고객사 서버에 저희 서비스를 구동하기 위한 환경 설정을 하는 일을 맡은 적이 있습니다. 웹서버를 위한 환경을 구축을 하거나 데이터베이스 서버를 위한 설치를 해야합니다. 그런데 이런 고객사가 과연 하나일까요? 고객사가 많아질수록 이런 설치 과정을 여러 번 반복해야겠죠. 또한, DB용과 웹서버용을 따로 묶어서 관리를 하고 싶어요. 이런 여러 고민들을 컨테이너 기술이 해결해줄 수 있습니다.&lt;/span&gt;&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;&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;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너는 애플리케이션과 그에 필요한 모든 종속성(라이브러리, 환경 변수 등)을 포함하는 런타임 환경을 구축하는 기술입니다. 이러한 컨테이너는 호스트 시스템과 격리되어 실행되며, 특정 운영 체제(OS)나 인프라스트럭처에 종속되지 않고 이식성과 일관성을 보장합니다. 가상화 기술을 사용하지만 가상 머신보다 경량적이고 빠르며, 여러 개의 컨테이너를 한 호스트에서 실행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너&amp;nbsp; vs 가상 머신&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZbDOH/btspK2UgJwD/bgBjDlAAUAl8TockjFdEh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZbDOH/btspK2UgJwD/bgBjDlAAUAl8TockjFdEh1/img.png&quot; data-alt=&quot;출처 : Docker 공식 홈페이지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZbDOH/btspK2UgJwD/bgBjDlAAUAl8TockjFdEh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZbDOH%2FbtspK2UgJwD%2FbgBjDlAAUAl8TockjFdEh1%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;1914&quot; height=&quot;816&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Docker 공식 홈페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너(Container)와 가상 머신(Virtual Machine)은 모두 가상화 기술을 사용하여 서로 다른 애플리케이션과 환경을 격리시키고 실행시키는 기술입니다. 하지만 그들 사이에는 중요한 차이점이 있습니다. 아래는 컨테이너와 가상 머신의 주요 차이점을 비교한 것입니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;구조적인 측면&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너: 컨테이너는 호스트 운영 체제 위에 작동하는 하나의 프로세스를 격리하는 방식으로 동작합니다. 각 컨테이너는 공유되는 커널을 사용하며, 애플리케이션과 그에 필요한 모든 종속성을 포함하여 실행됩니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;가상 머신: 가상 머신은 호스트 운영 체제 위에 하이퍼바이저를 통해 완전한 운영 체제를 가상화하는 방식으로 동작합니다. 각 가상 머신은 독립된 운영 체제와 커널을 가지고 있으며, 가상 머신을 호스트 시스템에서 구동하는 데 필요한 모든 리소스를 갖추고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;리소스&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너: 컨테이너는 호스트 시스템의 커널을 공유하기 때문에 가상 머신보다 훨씬 적은 리소스를 소비합니다. 따라서 컨테이너는 가볍고 빠르며, 빠른 시작과 정지가 가능합니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;가상 머신: 가상 머신은 완전한 운영 체제를 가상화하므로 더 많은 리소스를 필요로 합니다. 따라서 가상 머신은 더 무거우며 시작과 종료에 시간이 더 소요됩니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;이식성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너: 컨테이너는 애플리케이션과 종속성을 포함하고 있으므로, 호스트 시스템의 운영 체제 버전과는 독립적으로 동작할 수 있습니다. 이식성이 뛰어나며, 다양한 환경에서 일관성 있게 실행될 수 있습니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;가상 머신: 가상 머신은 완전한 운영 체제를 가상화하기 때문에 호스트 시스템의 운영 체제에 의존적입니다. 따라서 이식성이 상대적으로 떨어지며, 호스트 시스템과 동일한 운영 체제 버전이 필요합니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;보안&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너: 컨테이너는 호스트 시스템의 커널을 공유하므로, 적절한 격리와 보안 설정을 갖추어야 합니다. 일반적으로 컨테이너 환경은 가상 머신보다 공격 표면이 더 큽니다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;가상 머신: 가상 머신은 완전한 운영 체제를 가상화하여 컨테이너보다 격리된 환경을 제공합니다. 따라서 가상 머신은 더 강력한 격리와 보안을 제공하는 경향이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;2. 컨테이너의 장점&lt;/span&gt;&lt;/b&gt;&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: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;빠른 배포 : 컨테이너는 애플리케이션과 모든 종속성을 포함하므로, 환경에 대한 의존성을 제거하고 빠르게 배포할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;확장성 : 컨테이너는 가벼워서 여러 개의 인스턴스를 간단하게 생성하여 애플리케이션을 확장할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;유지보수 용이성 : 컨테이너는 이미지로 구성되어 있으며, 이러한 이미지는 버전 관리를 통해 쉽게 업데이트 및 롤백이 가능합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;일관성 : 개발 환경, 테스트 환경, 운영 환경에서 동일한 컨테이너 이미지를 사용하여 일관성을 유지할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;3. 주요 컨테이너 기술&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;도커(Docker): 도커는 현재 가장 인기 있는 컨테이너 플랫폼 중 하나입니다. 도커는 컨테이너 이미지를 빌드, 배포, 실행하는 간편한 CLI(Command Line Interface)를 제공하며, 컨테이너의 관리 및 네트워킹을 자동화합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;쿠버네티스(Kubernetes): 쿠버네티스는 컨테이너 오케스트레이션(관리) 플랫폼으로, 여러 개의 컨테이너화된 애플리케이션을 효율적으로 관리하기 위해 설계되었습니다. 쿠버네티스는 애플리케이션의 자동 배포, 확장, 로드 밸런싱, 롤링 업데이트 등을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;결론&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너 기술은 &lt;span style=&quot;text-align: start;&quot;&gt;논리적인 공간인 컨테이너를 만들어 다양한 어플리케이션을 설치해 하나의 서버처럼 사용할 수 있는 패키지입니다. &lt;/span&gt;&lt;span style=&quot;text-align: start;&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;있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;컨테이너 기술은 애플리케이션 배포와 관리를 혁신적으로 변화시키고 있습니다. 도커와 쿠버네티스를 비롯한 컨테이너 관련 도구들은 개발자와 운영팀에게 빠른 개발과 운영의 유연성을 제공합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>TechTalk</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/160</guid>
      <comments>https://coding-nyan.tistory.com/160#entry160comment</comments>
      <pubDate>Wed, 2 Aug 2023 22:58:49 +0900</pubDate>
    </item>
    <item>
      <title>API 호출을 위한 RestTemplate, WebClient 및 Feign 비교</title>
      <link>https://coding-nyan.tistory.com/159</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;API 호출은 대부분의 애플리케이션 개발에 기본이 되는 작업입니다. 실제로 업무에서 RestTemplate을 사용한 경험이 있는데요. 요새는 다른 방식도 이용한다고 해서 경험해볼 겸 이렇게 글을 작성해봤습니다. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 게시글에서는, 스프링 부트 프로젝트에서 API 호출을 할 때 사용하는 RestTemplate, WebClient, 그리고 Feign을 비교하고 간단한 예제 코드를 제공합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;스프링 부트 시리즈_복사본-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMuw2P/btseVMTBGw5/75MS5pk5Cv9HQKBk5Etcc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMuw2P/btseVMTBGw5/75MS5pk5Cv9HQKBk5Etcc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMuw2P/btseVMTBGw5/75MS5pk5Cv9HQKBk5Etcc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMuw2P%2FbtseVMTBGw5%2F75MS5pk5Cv9HQKBk5Etcc1%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;1260&quot; height=&quot;891&quot; data-filename=&quot;스프링 부트 시리즈_복사본-001.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;본 글에서는 &lt;a href=&quot;https://open.er-api.com/v6/latest&quot;&gt;https://open.er-api.com/v6/latest&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;에서 한국의 환율을 조회하는 방식으로 예제 코드를 작성했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;1. RestTemplate&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;RestTemplate는 스프링 프레임워크에서 HTTP 요청을 손쉽게 수행할 수 있는 도구입니다. RestTemplate은 동기식 호출을 사용하며, 아래에 예제 코드를 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683814894357&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RestTemplate rt = new RestTemplate();
Map&amp;lt;String, Map&amp;lt;String, Double&amp;gt;&amp;gt; res = rt.getForObject(&quot;https://open.er-api.com/v6/latest&quot;, Map.class);
System.out.println(res.get(&quot;rates&quot;).get(&quot;KRW&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;저는 업무에서 API를 호출할때 Basic Auth 가 필요한 경우가 꽤 있었어요. 따라서 그때의 기억을 되살려서 임의의 코드를 작성해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683815972762&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String url = &quot;localhost:8080&quot;
String auth = &quot;id:password&quot;;
String base64Creds = Base64.getEncoder().encodeToString(auth.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.add(&quot;Authorization&quot;, &quot;Basic &quot; + base64Creds);
HttpEntity request = new HttpEntity(headers);
ResponseEntity&amp;lt;ResponseDTO&amp;gt; response = new RestTemplate().exchange(url, HttpMethod.GET, request, ResponseDTO.class);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;Basic Auth 자체가 Basic Base64Encode(id:password) 의 형태이기에 그에 맞춰서 문자열을 생성해주는 부분이 필요합니다. 저도 그렇고 대부분의 분들이 이런 방식으로 RestTemplate에서 Basic Auth 정보를 넘겨주고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;참고로 RestTemplate에서 헤더 정보를 편집해서 API 호출을 해야되는 경우에는 exchange 메서드를 사용해주셔야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;2. WebClient&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;WebClient는 리액티브 프로그래밍에 기반한 스프링 5에서 새롭게 도입된 비동기 네트워크 통신 클라이언트입니다. 이를 사용하면 비동기 방식으로 API 호출을 할 수 있습니다. WebClient를 사용하기 위해서는 &lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;spring-boot-starter-webflux&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt; 의존성을 추가해줘야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683814938508&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WebClient client = WebClient.create(&quot;https://open.er-api.com&quot;);
Map&amp;lt;String, Map&amp;lt;String, Double&amp;gt;&amp;gt; res2 = client.get().uri(&quot;/v6/latest&quot;)
.retrieve().bodyToMono(Map.class).block();
System.out.println(res2.get(&quot;rates&quot;).get(&quot;KRW&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;그렇다면 WebClient 에서는 Basic Auth를 어떻게 구현할까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683816144624&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WebClient client2 = WebClient.builder().baseUrl(&quot;https://open.er-api.com&quot;)
.defaultHeaders(header -&amp;gt; header.setBasicAuth(id, password)).build();
Map&amp;lt;String, Map&amp;lt;String, Double&amp;gt;&amp;gt; res3 = client2.get().uri(&quot;/v6/latest&quot;).retrieve().bodyToMono(Map.class)
			.block();
System.out.println(res3.get(&quot;rates&quot;).get(&quot;KRW&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반 API 호출 예시에서는 create 메서드를 사용했습니다. create() 는 builder().baseUrl().build()랑 동일합니다. Header의 편집이 필요해서 이렇게 전개된 방식으로 접근했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그렇다면 create()를 쓸때는 Basic Auth 정보를 추가해줄 수 없을까요??&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683816498071&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WebClient client2 = WebClient.builder().baseUrl(&quot;https://open.er-api.com&quot;).defaultHeaders(null).build();
Map&amp;lt;String, Map&amp;lt;String, Double&amp;gt;&amp;gt; res3 = client2.get().uri(&quot;/v6/latest&quot;)
     .headers(headers -&amp;gt; headers.setBasicAuth(id, password))
     .retrieve().bodyToMono(Map.class).block();
System.out.println(res3.get(&quot;rates&quot;).get(&quot;KRW&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;retrive로 값을 가져오기 전에 header를 붙여줄 수 있다고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;조금 더 편한 방식으로 사용하시면 되겠네요 :)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;3. Feign&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;Feign은 선언적 HTTP 클라이언트로, API 호출에 사용 가능한 또 다른 유용한 도구입니다. Feign은 인터페이스를 사용하여 API 연결을 추상화하고 읽기 쉽게 만듭니다. &lt;span style=&quot;text-align: start;&quot;&gt;spring-cloud-starter-openfeign 의 의존성을 추가해줘야 사용이 가능합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683815244164&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;implementation platform(&quot;org.springframework.cloud:spring-cloud-dependencies:2022.0.2&quot;)
implementation &quot;org.springframework.cloud:spring-cloud-starter-openfeign&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;저는 위처럼 gradle에 추가해줬습니다. 그냥 spring-cloud-starter-openfeign 만 쓰면 디펜던시를 찾아오지 못하더라구요. 본인의 spring boot 버전에 맞춰서 환경을 세팅해주셔야 됩니다. Release 버전은 아래 사진을 참고해주세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1583&quot; data-origin-height=&quot;1018&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cS0z64/btseP5VafwG/qnswJEkMWV0KBwvsR8avs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cS0z64/btseP5VafwG/qnswJEkMWV0KBwvsR8avs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cS0z64/btseP5VafwG/qnswJEkMWV0KBwvsR8avs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcS0z64%2FbtseP5VafwG%2FqnswJEkMWV0KBwvsR8avs1%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;1583&quot; height=&quot;1018&quot; data-origin-width=&quot;1583&quot; data-origin-height=&quot;1018&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;Feign을 사용하기 위해서는 추가 설정이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683815060259&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@SpringBootApplication
@EnableFeignClients&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;root 프로젝트 main 클래스에 @EnableFeignClients 를 추가해줘야합니다. 이게 있어야 &lt;span style=&quot;color: #212121; text-align: left;&quot;&gt;@FeignClient 를 찾아 구현체를 만들어 줍니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #212121;&quot;&gt;RateClient.java&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683815506900&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@FeignClient(name = &quot;rateClient&quot;, url = &quot;https://open.er-api.com&quot;)
public interface RateClient {
    @GetMapping(value = &quot;/v6/latest&quot;)
    ApiResponse getExchangeRates();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;ApiResponse.java&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683815597466&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ApiResponse {
    private String result;
    private Map&amp;lt;String,Double&amp;gt; rates;

    public Map&amp;lt;String, Double&amp;gt; getRates() {
        return rates;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Controller나 서비스에서 호출&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683815627819&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;System.out.println(rClient.getExchangeRates().getRates().get(&quot;KRW&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;이런 구성으로 작성하시면 됩니다. 제가 위에서 RestTemplate이나 WebClient를 사용할때는 Response 로 넘어온 JSON 데이터를 객체에 담지 않고 바로 사용했습니다. 그래서 비교적 구현하는 코드가 더 짧아보이네요. 쟤네도 동일하게 설정해주시면 Feign쪽이 더 직관적으로 다가올 수 있습니다. Feign도 Map에 담아서 바로 쓰고 싶었는데 마땅한 방법을 찾지 못했습니다...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;Feign를 이용할때는 Basic Auth를 어떻게 구현할까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;아래와 같이 Configuration을 등록해주면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1683816644565&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class BasicAuthConfiguration {

    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor(&quot;id&quot;, &quot;password&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;그러고 FeignClient에 configuration 정보를 등록해주면 Basic Auth를 정상적으로 쓸 수 있습니다.&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683816724621&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@FeignClient(name = &quot;rateClient&quot;, url = &quot;https://open.er-api.com&quot;, configuration = BasicAuthConfiguration.class)
public interface RateClient {

    @GetMapping(value = &quot;/v6/latest&quot;)
    ApiResponse getExchangeRates();
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;4. 결론&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;Spring Boot에서 API 호출을 할 때 사용하는 RestTemplate, WebClient, 그리고 OpenFeign 중 어떤 것을 선택할까요? &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;몇 가지 고려 사항들이 있습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;- RestTemplate: 동기식 호출에 적합한 클래식한 방법을 선호하는 경우 사용하세요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;- WebClient: 리액티브 프로그래밍에 적합합니다. Spring 에서 권장하는 모던한 방식이라고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;- Feign: 코드 가독성이 중요하거나, 선언적 방식의 인터페이스를 사용하는 것이 편리하다고 생각하는 경우 사용하세요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;프로젝트의 요구사항, 성능 요구 사항 및 개발자의 선호도에 따라 여러 방법 중 하나를 선택하여 적용할 수 있습니다. 각 방법의 장단점을 잘 이해하고, 프로젝트에 가장 적합한 도구를 사용하시길 바랍니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;이 글이 도움이 되셨길 바랍니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>web/spring&amp;amp;spring boot</category>
      <category>Feign</category>
      <category>Rest</category>
      <category>REST API 호출</category>
      <category>resttemplate</category>
      <category>spring</category>
      <category>WebClient</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/159</guid>
      <comments>https://coding-nyan.tistory.com/159#entry159comment</comments>
      <pubDate>Thu, 11 May 2023 23:59:31 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot] @Component에 대한 이해</title>
      <link>https://coding-nyan.tistory.com/158</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우리가 Spring을 사용하는 수 많은 이유중에 대표적인 장점을 꼽으라면 의존성 주입 컨테이너에 관한 내용을 빼놓을 수 없다. 스프링은 자바 빈을 찾아서 ApplicationContext라고 하는 의존성 주입 컨테이너 오브젝트에 등록을 한다. 그리고 애플리케이션이 돌다가 어떤 오브젝트가 필요하다면 의존하는 오브젝트를 찾아서 연결해준다. &lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그렇다면 스프링은 어떻게 자바 빈을 찾아가지고 의존성 주입 컨테이너에 등록하는걸까?? @Component 어노테이션으로 이 클래스를 자바 빈으로 등록하라고 알려줄 수 있다. 이번 포스팅에서는 이 @Component에 대해서 알아보려고 한다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tEwtv/btr7Qn1xUKd/bekp34cqlaZMr2LHEHx7FK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tEwtv/btr7Qn1xUKd/bekp34cqlaZMr2LHEHx7FK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tEwtv/btr7Qn1xUKd/bekp34cqlaZMr2LHEHx7FK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtEwtv%2Fbtr7Qn1xUKd%2Fbekp34cqlaZMr2LHEHx7FK%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;1260&quot; height=&quot;891&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;891&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Component&lt;/span&gt;&lt;/b&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Component 어노테이션을 붙이면 이 클래스를 자바 빈으로 등록시키라고 알려줄 수 있다. 해당 어노테이션이 명시되어 있으면 Spring이 자동으로 클래스의 인스턴스를 생성하고 종속성을 포함하여 각종 lifecycle을 관리해준다. 이를 통해 개발자는 오브젝트 생성 및 관리에 대한 걱정보다 비즈니스 로직 자체에 집중할 수 있다고 한다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1680503765924&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class MyComponent {
  // ...
}&lt;/code&gt;&lt;/pre&gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위의 예시처럼 MyComponent에 @Component 어노테이션을 붙여준다. 그러면 앞으로 MyComponent는 Spring에서 자동으로 관리해준다.&lt;/span&gt;&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;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단, 모든 경우에 @Component를 클래스 앞에 붙여준다고 스프링이 자동으로 알아서 등록해줄까?? 이건 또 아니다. @ComponentScan이라는 어노테이션이 존재해야만 한다. &lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그러나 이걸 구현한 기억이 없어도 Spring은 마법처럼 알아서 빈을 관리해줬을 것이다. 왜냐하면 Spring boot 프로젝트를 생성하면 기본적으로 존재하는 @SpringBootApplication이라는 어노테이션 안에 명시되어 있기 때문이다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;435&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdZ8R0/btr7OPiZ05y/VGC2yRHkNbVoZavTHobX1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdZ8R0/btr7OPiZ05y/VGC2yRHkNbVoZavTHobX1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdZ8R0/btr7OPiZ05y/VGC2yRHkNbVoZavTHobX1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdZ8R0%2Fbtr7OPiZ05y%2FVGC2yRHkNbVoZavTHobX1k%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;1002&quot; height=&quot;435&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;435&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;745&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjUnQ5/btr7HgIxUrZ/o4NSqufua1PdEuKThJVaeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjUnQ5/btr7HgIxUrZ/o4NSqufua1PdEuKThJVaeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjUnQ5/btr7HgIxUrZ/o4NSqufua1PdEuKThJVaeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjUnQ5%2Fbtr7HgIxUrZ%2Fo4NSqufua1PdEuKThJVaeK%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;1273&quot; height=&quot;745&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;745&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;+ 이전에 @SpringBootApplication 에 대해서 정리한 적이 있으니 필요한 분들은 참고해주세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1680504018780&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[spring boot] @SpringBootApplication 정리&quot; data-og-description=&quot;Spring Initializr를 이용해서 프로젝트를 만들면 프로젝트명Application이 자동으로 생성됩니다. 메서드 선언부에는 main 메서드 하나만 선언되어 있고 SpringApplication.run 메서드를 호출해서 웹 애플리케&quot; data-og-host=&quot;coding-nyan.tistory.com&quot; data-og-source-url=&quot;https://coding-nyan.tistory.com/84&quot; data-og-url=&quot;https://coding-nyan.tistory.com/84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/PsN5E/hyR9H0AFag/RWpUeXUVnBygzvwpJwYKNK/img.png?width=800&amp;amp;height=659&amp;amp;face=0_0_800_659,https://scrap.kakaocdn.net/dn/b6JJ5O/hyR7xk0RfA/AMUuebZX9GSSwZIPwCCRvk/img.png?width=800&amp;amp;height=659&amp;amp;face=0_0_800_659,https://scrap.kakaocdn.net/dn/DZ1Hp/hyR9HM25YY/SMm7n5F0eJog0k8kudsuf1/img.png?width=1005&amp;amp;height=828&amp;amp;face=0_0_1005_828&quot;&gt;&lt;a href=&quot;https://coding-nyan.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://coding-nyan.tistory.com/84&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/PsN5E/hyR9H0AFag/RWpUeXUVnBygzvwpJwYKNK/img.png?width=800&amp;amp;height=659&amp;amp;face=0_0_800_659,https://scrap.kakaocdn.net/dn/b6JJ5O/hyR7xk0RfA/AMUuebZX9GSSwZIPwCCRvk/img.png?width=800&amp;amp;height=659&amp;amp;face=0_0_800_659,https://scrap.kakaocdn.net/dn/DZ1Hp/hyR9HM25YY/SMm7n5F0eJog0k8kudsuf1/img.png?width=1005&amp;amp;height=828&amp;amp;face=0_0_1005_828');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[spring boot] @SpringBootApplication 정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spring Initializr를 이용해서 프로젝트를 만들면 프로젝트명Application이 자동으로 생성됩니다. 메서드 선언부에는 main 메서드 하나만 선언되어 있고 SpringApplication.run 메서드를 호출해서 웹 애플리케&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;coding-nyan.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&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;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Autowired&lt;/span&gt;&lt;/b&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Autowired는 어노테이션을 @Component와 함께 사용된다. 이 어노테이션을 달면 ApplicationContext에 종속성을 주입할 수 있다. 클래스에 @Autowired를 달았다? 그러면 Spring에서 필요한 종속성의 인스턴스를 자동으로 주입한다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1680504234518&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class MyComponent {
  private MyService myService;

  @Autowired
  public MyComponent(MyService myService) {
    this.myService = myService;
  }

  // ...
}&lt;/code&gt;&lt;/pre&gt;
&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #374151;&quot;&gt;위의 예제에서는 @Autowired를 사용해 MyService 인스턴스를 MyComponent에 주입한다. MyComponent가 생성되면 Spring은 자동으로 MyService의 인스턴스를 생성하고 MyComponent의 생성자에 주입까지 해준다.&lt;/span&gt;&lt;/span&gt;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Service,&amp;nbsp;@Controller,&amp;nbsp;@Repository&lt;/span&gt;&lt;/b&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Component는 클래스를 Spring 관리 빈으로 표시하기 위한 범용 어노테이션이지만, Spring은 @Service, @Controller 및 @Repository라는 보다 구체적인 어노테이션들을 제공한다. 이러한 주석은 모두 @Component의 메타 어노테이션이다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;뭔가 말이 복잡한데 @Component의 모든 기능을 상속하고 일부 추가적인 기능들이 들어간 어노테이션들이라고 보면 된다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;따라서 위의 어노테이션들을 사용하면 Spring이 자동으로 자바 빈을 찾아서 관리해줄 뿐만 아니라 이것이 Service인지 Controller인지에 따라 추가적인 기능들을 제공한다.&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Bean&lt;/span&gt;&lt;/b&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 @Bean 어노테이션은 뭘까? @Component는 클래스를 Spring에서 알아서 관리해주는 자바 빈으로 표시하는 데 사용되는 반면 @Bean은 Spring에서 관리할 Bean을 명시적으로 선언하는 데 사용된다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;처음 들을 때는 그게 그거 아닌가 싶은 문장이었는데 굳이 해석해보자면 이렇다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;@Component와 달리 @Bean은 개발자가 Bean의 생성 및 구성을 사용자 정의할 수 있도록 한다. 그러니 @Bean을 이용해 우리는 Spring에게 이 오브젝트는 언제 어떻게 생성이 되어야하고 매개변수는 무엇이 필요해를 직접 지시할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1680504934700&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class WebConfig implements WebMvcConfigurer {
  
  @Bean
  public LocaleResolver localeResolver() {
    SessionLocaleResolver resolver = new SessionLocaleResolver();
    resolver.setDefaultLocale(Locale.US);
    return resolver;
  }
  
  // ...
  
}&lt;/code&gt;&lt;/pre&gt;
&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 예제에서는 Locale.US의 기본 로케일로 SessionLocaleResolver의 인스턴스를 반환하는 LocaleResolver 빈을 정의했다. 이 빈은 Spring MVC 애플리케이션에서 사용자의 로케일을 해결하는 데 사용된다.&amp;nbsp;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 글에서는 Spring Boot에서 @Component 어노테이션의 개념을 살펴봤다. 간단하게 @Component 동작 방식에 대해서 정리하며 글을 마무리한다.&lt;/span&gt;&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; @ComponentScan 어노테이션이 있는 경우, 베이스 패키지와 그 하위 패키지들을 돌면서 @Component가 명시된 클래스들을 찾아서 스프링이 관리하는 자바 빈에 등록한다. 필요에 따라서 @Component가 적힌 클래스 오브젝트를 생성한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이때 다른 오브젝트에 의존하고 있다면 그 오브젝트도 같이 찾아줘야 한다. @Autowired가 명시된 경우 Spring이 알아서 찾고 오브젝트를 생성해서 관리해준다. 만약 @Bean으로 명시된 오브젝트라면 @Bean이 달린 메서드를 불러서 오브젝트를 생성해준다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>web/spring&amp;amp;spring boot</category>
      <category>@Component</category>
      <category>Di</category>
      <category>spring</category>
      <category>spring boot</category>
      <category>웹 개발</category>
      <category>의존성 주입</category>
      <author>moongomi</author>
      <guid isPermaLink="true">https://coding-nyan.tistory.com/158</guid>
      <comments>https://coding-nyan.tistory.com/158#entry158comment</comments>
      <pubDate>Mon, 3 Apr 2023 16:04:00 +0900</pubDate>
    </item>
  </channel>
</rss>