<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>레퍼런스 마이닝</title>
    <link>https://reference-m1.tistory.com/</link>
    <description>탄광에서 금맥 찾는 Reference 빌더 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Wed, 20 May 2026 05:11:36 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Reference M1</managingEditor>
    <image>
      <title>레퍼런스 마이닝</title>
      <url>https://tistory1.daumcdn.net/tistory/3042147/attach/af4b3f25ee834b8b8b55132daa2b3bac</url>
      <link>https://reference-m1.tistory.com</link>
    </image>
    <item>
      <title>[Etc] Sonarqube 코드 품질 향상</title>
      <link>https://reference-m1.tistory.com/418</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;sonarqube.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAYtu/btsINdIJzWf/eOK3o2MMUwm7lDerFS81f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAYtu/btsINdIJzWf/eOK3o2MMUwm7lDerFS81f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAYtu/btsINdIJzWf/eOK3o2MMUwm7lDerFS81f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAYtu%2FbtsINdIJzWf%2FeOK3o2MMUwm7lDerFS81f1%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;1400&quot; height=&quot;728&quot; data-filename=&quot;sonarqube.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이슈, 결함, 코드 복잡성등을 분석하여 코드의 품질을 평가하고 개선하여 코드 품질 향상에 목적을 하고 있다.&lt;br /&gt;지속적인 코드 품질 관리를 통해 개발 초기에 코드 문제를 해결하고 자동화된 코드 감사를 통해 최신 상태의&amp;nbsp;코드&amp;nbsp;문제를&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정적 코드 분석&lt;/li&gt;
&lt;li&gt;코드 품질 중앙화 관리&lt;/li&gt;
&lt;li&gt;DevOps 통합&lt;/li&gt;
&lt;li&gt;다중 언어 분석&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데모&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sonarcloud.io/projects&quot;&gt;https://sonarcloud.io/projects&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://next.sonarqube.com/sonarqube/projects&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://next.sonarqube.com/sonarqube/projects&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;품질요소&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Code&amp;nbsp;Smells(Maintainability)&lt;br /&gt;심각한&amp;nbsp;이슈는&amp;nbsp;아니지만&amp;nbsp;사소한&amp;nbsp;이슈들로&amp;nbsp;모듈성(modularity),&amp;nbsp;이해가능성(understandability),&amp;nbsp;변경가능성(changeability),&amp;nbsp;테스트 용의성(testability),&amp;nbsp;재사용성(reusability)&amp;nbsp;등이&amp;nbsp;포함된다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Bugs(Reliability)&lt;br /&gt;일반적으로 잠재적인 버그 혹은 실행시간에 예상되는 동작을 하지 않는 코드를 나타낸다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Vulnerabilities(Security)&lt;br /&gt;해커들에게&amp;nbsp;잠재적인&amp;nbsp;약점이&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;보안상의&amp;nbsp;이슈를&amp;nbsp;말한다.&amp;nbsp;SQL&amp;nbsp;인젝션,&amp;nbsp;크로스&amp;nbsp;사이트&amp;nbsp;스크립팅과&amp;nbsp;같은&amp;nbsp;보안&amp;nbsp;취약성을&amp;nbsp;찾아낸다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Duplications&lt;br /&gt;코드&amp;nbsp;중복은&amp;nbsp;코드의&amp;nbsp;품질을&amp;nbsp;저해시키는&amp;nbsp;가장&amp;nbsp;큰&amp;nbsp;요인&amp;nbsp;중&amp;nbsp;하나이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Unit&amp;nbsp;Tests&lt;br /&gt;단위테스트&amp;nbsp;커버리지를&amp;nbsp;통해&amp;nbsp;단위&amp;nbsp;테스트의&amp;nbsp;수행&amp;nbsp;정도와&amp;nbsp;수행한&amp;nbsp;테스트의&amp;nbsp;성공/실패&amp;nbsp;정보를&amp;nbsp;제공한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Complexity&lt;br /&gt;순환복잡도,&amp;nbsp;인지복잡도&amp;nbsp;측정&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Size&lt;br /&gt;소스코드&amp;nbsp;사이즈와&amp;nbsp;관련된&amp;nbsp;다양한&amp;nbsp;지표를&amp;nbsp;제공한다.&amp;nbsp;(코드&amp;nbsp;라인수,&amp;nbsp;전체&amp;nbsp;라인수,&amp;nbsp;구문,&amp;nbsp;함수,&amp;nbsp;클래스,&amp;nbsp;파일,&amp;nbsp;디렉토리,&amp;nbsp;주석&amp;nbsp;수,&amp;nbsp;코멘트&amp;nbsp;비율)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Clean Code&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어 품질&lt;br /&gt;보안,&amp;nbsp;신뢰성,&amp;nbsp;유지&amp;nbsp;관리성이라는&amp;nbsp;세&amp;nbsp;가지&amp;nbsp;측면을&amp;nbsp;Sonar&amp;nbsp;솔루션에서는&amp;nbsp;소프트웨어&amp;nbsp;품질이라고&amp;nbsp;부르며,&amp;nbsp;이는&amp;nbsp;소프트웨어의&amp;nbsp;장기적인&amp;nbsp;가치에&amp;nbsp;기여한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;보안(Security)&lt;br /&gt;보안은&amp;nbsp;무단&amp;nbsp;액세스,&amp;nbsp;사용&amp;nbsp;또는&amp;nbsp;파괴로부터&amp;nbsp;소프트웨어를&amp;nbsp;보호하는&amp;nbsp;것이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;신뢰성(Reliability)&lt;br /&gt;소프트웨어가&amp;nbsp;명시된&amp;nbsp;기간&amp;nbsp;동안&amp;nbsp;명시된&amp;nbsp;조건에서&amp;nbsp;성능을&amp;nbsp;유지할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;방법을&amp;nbsp;측정하는&amp;nbsp;것이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;유지&amp;nbsp;관리성(Maintainability)&lt;br /&gt;유지&amp;nbsp;관리성은&amp;nbsp;소프트웨어&amp;nbsp;코드를&amp;nbsp;쉽게&amp;nbsp;수정,&amp;nbsp;개선&amp;nbsp;및&amp;nbsp;이해할&amp;nbsp;수&amp;nbsp;있음을&amp;nbsp;의미한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Etc</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/418</guid>
      <comments>https://reference-m1.tistory.com/418#entry418comment</comments>
      <pubDate>Thu, 25 Jul 2024 09:59:44 +0900</pubDate>
    </item>
    <item>
      <title>[Etc] Gradle 버전에 따른 lombok 설정</title>
      <link>https://reference-m1.tistory.com/417</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 이전 작성 했던 코드를 참고해 볼 일이 있어 확인하던 중 Gradle Build가 되지 않아 해결하는 과정에서 알게 된 정보를 공유하고자 한다. 우선&amp;nbsp;현재&amp;nbsp;Gradle&amp;nbsp;버전을&amp;nbsp;확인해&amp;nbsp;보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-04 오전 9.49.35.png&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1Ltk8/btsIlGslSdE/JdLTNlZAzAEglV9KYiFPI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1Ltk8/btsIlGslSdE/JdLTNlZAzAEglV9KYiFPI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1Ltk8/btsIlGslSdE/JdLTNlZAzAEglV9KYiFPI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1Ltk8%2FbtsIlGslSdE%2FJdLTNlZAzAEglV9KYiFPI0%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;561&quot; height=&quot;241&quot; data-filename=&quot;스크린샷 2024-07-04 오전 9.49.35.png&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradle&amp;nbsp;버전을&amp;nbsp;확인&amp;nbsp;했다면&amp;nbsp;5.x&amp;nbsp;버전&amp;nbsp;기준으로&amp;nbsp;의존성&amp;nbsp;주입&amp;nbsp;방법이&amp;nbsp;달라진다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.x 미만&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1720066737299&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
  implementation 'org.projectlombok:lombok'
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.x 이상&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1720066766586&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
  compileOnly 'org.projectlombok:lombok'
  annotationProcessor 'org.projectlombok:lombok'
}&lt;/code&gt;&lt;/pre&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;Gradle Java 호환성&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-04 오전 11.26.42.png&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/na27C/btsIlR1iIMk/qUNGzqA4FKzeg78kaAiJ21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/na27C/btsIlR1iIMk/qUNGzqA4FKzeg78kaAiJ21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/na27C/btsIlR1iIMk/qUNGzqA4FKzeg78kaAiJ21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fna27C%2FbtsIlR1iIMk%2FqUNGzqA4FKzeg78kaAiJ21%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;402&quot; height=&quot;588&quot; data-filename=&quot;스크린샷 2024-07-04 오전 11.26.42.png&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/compatibility.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.gradle.org/current/userguide/compatibility.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1720066826991&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;Compatibility Matrix&quot; data-og-description=&quot;The sections below describe Gradle&amp;rsquo;s compatibility with several integrations. Versions not listed here may or may not work.&quot; data-og-host=&quot;docs.gradle.org&quot; data-og-source-url=&quot;https://docs.gradle.org/current/userguide/compatibility.html&quot; data-og-url=&quot;https://docs.gradle.org/current/userguide/compatibility.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.gradle.org/current/userguide/compatibility.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.gradle.org/current/userguide/compatibility.html&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;Compatibility Matrix&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The sections below describe Gradle&amp;rsquo;s compatibility with several integrations. Versions not listed here may or may not work.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.gradle.org&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;</description>
      <category>프로그래밍/Etc</category>
      <category>gradle</category>
      <category>Lombok</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/417</guid>
      <comments>https://reference-m1.tistory.com/417#entry417comment</comments>
      <pubDate>Mon, 8 Jul 2024 09:40:05 +0900</pubDate>
    </item>
    <item>
      <title>[Etc] Jenkins Spread load evenly by using rather than</title>
      <link>https://reference-m1.tistory.com/416</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Jenkins&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 플러그인을&amp;nbsp;통해&amp;nbsp;지속적으로&amp;nbsp;구축,&amp;nbsp;테스트&amp;nbsp;및&amp;nbsp;배포를&amp;nbsp;목적으로&amp;nbsp;대표적인&amp;nbsp;빌드&amp;nbsp;배포&amp;nbsp;툴이다.&lt;br /&gt;- Jenkins&amp;nbsp;등장&amp;nbsp;이후&amp;nbsp;많은&amp;nbsp;변화가&amp;nbsp;있었지만,&amp;nbsp;핵심적인&amp;nbsp;설정은&amp;nbsp;아직도&amp;nbsp;큰 틀에서&amp;nbsp;유지되고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jenkins 빌드 유발(Build Triggers)을 설정할 때 나타나는 경고 문구에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Build&amp;nbsp;Triggers&amp;nbsp;테스트는&amp;nbsp;Poll&amp;nbsp;SCM,&amp;nbsp;Build&amp;nbsp;Periodically에서&amp;nbsp;확인이&amp;nbsp;가능하다.&lt;br /&gt;- Jenkins는&amp;nbsp;지정된&amp;nbsp;간격으로&amp;nbsp;변경&amp;nbsp;사항을&amp;nbsp;자동으로&amp;nbsp;확인하고&amp;nbsp;감지되면&amp;nbsp;빌드를&amp;nbsp;트리거&amp;nbsp;한다.&lt;br /&gt;- 이때&amp;nbsp;지정된&amp;nbsp;간격을&amp;nbsp;설정하는&amp;nbsp;방법을&amp;nbsp;Cron&amp;nbsp;구문이라고&amp;nbsp;한다.&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;Example&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*/30&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;30분&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-02 오후 4.48.51.png&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q63lf/btsIlytSlRP/4CKrGfQNdJTwAtOouqMHe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q63lf/btsIlytSlRP/4CKrGfQNdJTwAtOouqMHe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q63lf/btsIlytSlRP/4CKrGfQNdJTwAtOouqMHe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ63lf%2FbtsIlytSlRP%2F4CKrGfQNdJTwAtOouqMHe1%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;1001&quot; height=&quot;216&quot; data-filename=&quot;스크린샷 2024-07-02 오후 4.48.51.png&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spread&amp;nbsp;load&amp;nbsp;evenly&amp;nbsp;by&amp;nbsp;using&amp;nbsp;&amp;lsquo;H/30&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;rsquo;&amp;nbsp;rather&amp;nbsp;than&amp;nbsp;&amp;lsquo;*/30&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;rsquo;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 동일한 시간에 크론 작업을 설정하면 동시에 여러 개의 작업이 수행되어 순간적으로 장비의 리소스 사용이 급격히 늘어 부하가 발생한다. 하지만 Jenkins에서는 여러 개의 작업이 꼭 동일한 시간에 작업해야 될 필요가 없을 때에는 Hash 값을 사용하여 작업을 적절하게 분배하여 동작시켜 준다. 그러므로 제한된 리소스를 가진 환경에서 더욱 유용하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;H(1-10)&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;rsquo;&amp;nbsp;와&amp;nbsp;같이&amp;nbsp;해시값에&amp;nbsp;조건을&amp;nbsp;줄&amp;nbsp;수도&amp;nbsp;있습니다.&amp;nbsp;(1&amp;nbsp;~&amp;nbsp;10분&amp;nbsp;사이에서&amp;nbsp;동작)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;H(30-30)&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;nbsp;*&amp;rsquo;&lt;br /&gt;꼭&amp;nbsp;매시&amp;nbsp;30분에&amp;nbsp;동작해야&amp;nbsp;하는&amp;nbsp;경우는&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;설정해&amp;nbsp;준다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p 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>프로그래밍/Etc</category>
      <category>cron</category>
      <category>jenkins</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/416</guid>
      <comments>https://reference-m1.tistory.com/416#entry416comment</comments>
      <pubDate>Thu, 4 Jul 2024 08:19:06 +0900</pubDate>
    </item>
    <item>
      <title>[Etc] 웹훅(Webhook) 알아보기</title>
      <link>https://reference-m1.tistory.com/414</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;what-is-a-webhook.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjTm9x/btsBGXzmTht/ZqExBtmPRmRCrcl2bhX3G0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjTm9x/btsBGXzmTht/ZqExBtmPRmRCrcl2bhX3G0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjTm9x/btsBGXzmTht/ZqExBtmPRmRCrcl2bhX3G0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjTm9x%2FbtsBGXzmTht%2FZqExBtmPRmRCrcl2bhX3G0%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;1200&quot; height=&quot;683&quot; data-filename=&quot;what-is-a-webhook.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;웹훅 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹훅이란&amp;nbsp;웹앱에서&amp;nbsp;발생하는&amp;nbsp;특정&amp;nbsp;이벤트를&amp;nbsp;커스텀&amp;nbsp;콜백으로&amp;nbsp;변환&amp;nbsp;해주는&amp;nbsp;방법이다.&amp;nbsp;쉽게&amp;nbsp;말해&amp;nbsp;데이터가&amp;nbsp;변경되었을&amp;nbsp;때&amp;nbsp;실시간으로&amp;nbsp;알림을&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;기능이다.&amp;nbsp;HTTP&amp;nbsp;기반의&amp;nbsp;웹&amp;nbsp;특징과&amp;nbsp;훅(Hook)&amp;nbsp;기능을&amp;nbsp;합친&amp;nbsp;용어이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;API&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API는&amp;nbsp;클라이언트가&amp;nbsp;요청을&amp;nbsp;한다.&amp;nbsp;필요한&amp;nbsp;데이터를&amp;nbsp;특정한&amp;nbsp;API로&amp;nbsp;호출하고&amp;nbsp;응답을&amp;nbsp;받게&amp;nbsp;된다.&lt;br /&gt;&lt;u&gt;&lt;b&gt;행위의&amp;nbsp;주체가&amp;nbsp;클라이언트가&amp;nbsp;데이터를&amp;nbsp;당겨온다.&amp;nbsp;PULL&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;웹훅&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹훅은&amp;nbsp;클라이언트가&amp;nbsp;데이터를&amp;nbsp;요청하지&amp;nbsp;않아도,&amp;nbsp;필요할&amp;nbsp;때&amp;nbsp;알아서&amp;nbsp;데이터를&amp;nbsp;준다.&amp;nbsp;미리&amp;nbsp;이벤트를&amp;nbsp;지정해두고,&amp;nbsp;해당&amp;nbsp;이벤트가&amp;nbsp;발생되면&lt;br /&gt;나에게 데이터를 보내줘라는 의미이다.&lt;br /&gt;&lt;u&gt;&lt;b&gt;행위의 주체가 웹훅이 데이터를 밀어 준다. PUSH&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹훅을 통해 Gitlab과 Jenkins 사이의 파이프라인 구성도 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;MJ-Webhooks-polling-comparison.png&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAB3Lu/btsBGo5dP2C/fxl0MbQyt35h3sFSVzo1jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAB3Lu/btsBGo5dP2C/fxl0MbQyt35h3sFSVzo1jk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAB3Lu/btsBGo5dP2C/fxl0MbQyt35h3sFSVzo1jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAB3Lu%2FbtsBGo5dP2C%2Ffxl0MbQyt35h3sFSVzo1jk%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;2000&quot; height=&quot;1380&quot; data-filename=&quot;MJ-Webhooks-polling-comparison.png&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API&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;API&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;API와&amp;nbsp;웹훅의&amp;nbsp;특징을&amp;nbsp;파악하여&amp;nbsp;각&amp;nbsp;상황에&amp;nbsp;맞게&amp;nbsp;연동방식을&amp;nbsp;선정하여&amp;nbsp;구현해야&amp;nbsp;한다.&lt;/p&gt;</description>
      <category>프로그래밍/Etc</category>
      <category>웹훅</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/414</guid>
      <comments>https://reference-m1.tistory.com/414#entry414comment</comments>
      <pubDate>Mon, 11 Dec 2023 08:54:41 +0900</pubDate>
    </item>
    <item>
      <title>[오라클] ORA-01795 IN 절에 사용가능한 값의 개수 제한</title>
      <link>https://reference-m1.tistory.com/413</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;List로 주어진 여러 개의 조건 값을 IN 형태로 조건을 경우가 생긴다. 일반적인&amp;nbsp;상황이라면은&amp;nbsp;문제가&amp;nbsp;없지만&amp;nbsp;1000건&amp;nbsp;이상으로&amp;nbsp;IN절을&amp;nbsp;구성할 때는&amp;nbsp;ORA-01795&amp;nbsp;오류를&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ORA-01795:&amp;nbsp;목록에&amp;nbsp;지정&amp;nbsp;가능한&amp;nbsp;식의&amp;nbsp;최대&amp;nbsp;수는&amp;nbsp;1000입니다&amp;nbsp;(maximum&amp;nbsp;number&amp;nbsp;of&amp;nbsp;expressions&amp;nbsp;in&amp;nbsp;a&amp;nbsp;list&amp;nbsp;is&amp;nbsp;1000)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695090917696&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;select id=&quot;selectItems&quot;&amp;gt;
    SELECT *
      FROM TBL
     WHERE CDN IN
        &amp;lt;foreach collection=&quot;items&quot; item=&quot;item&quot; open=&quot;(&quot; close=&quot;)&quot; separator=&quot;, &quot;&amp;gt;
                #{item.val}
        &amp;lt;/foreach&amp;gt;
&amp;lt;/select&amp;gt;&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. OR 연산자 1000건씩 분리&lt;/h4&gt;
&lt;pre id=&quot;code_1695090996533&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;select id=&quot;selectItems&quot;&amp;gt;
    SELECT *
      FROM TBL
     WHERE
        &amp;lt;foreach collection=&quot;partitionedItems&quot; item=&quot;partition&quot; separator=&quot;OR&quot;&amp;gt;
            CDN IN
            &amp;lt;foreach collection=&quot;partition&quot; item=&quot;item&quot; open=&quot;(&quot; close=&quot;)&quot; separator=&quot;, &quot;&amp;gt;
                #{item.val}
            &amp;lt;/foreach&amp;gt;
        &amp;lt;/foreach&amp;gt;
&amp;lt;/select&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1695091029151&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List&amp;lt;List&amp;lt;T&amp;gt;&amp;gt; partitionedItems = new ArrayList&amp;lt;&amp;gt;(
    items.stream()
    .collect(Collectors.groupingBy(item -&amp;gt; item / 1000))
    .values()
);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. IN절 내부 SubQuery&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트&amp;nbsp;파라미터는&amp;nbsp;1000개&amp;nbsp;제한이&amp;nbsp;있지만&amp;nbsp;SubQeury는&amp;nbsp;제한이&amp;nbsp;없다.&lt;/p&gt;
&lt;pre id=&quot;code_1695091056829&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;select id=&quot;selectItems&quot;&amp;gt;
    SELECT *
      FROM TBL
     WHERE CDN IN
        &amp;lt;foreach collection=&quot;items&quot; item=&quot;item&quot; open=&quot;(&quot; close=&quot;)&quot; separator=&quot;UNION ALL&quot;&amp;gt;
                SELECT #{item.val} FROM DUAL
        &amp;lt;/foreach&amp;gt;
&amp;lt;/select&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>데이터베이스/SQL</category>
      <category>ORA-01795</category>
      <category>SQL</category>
      <category>오라클</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/413</guid>
      <comments>https://reference-m1.tistory.com/413#entry413comment</comments>
      <pubDate>Tue, 19 Sep 2023 11:38:48 +0900</pubDate>
    </item>
    <item>
      <title>[SQL] 오라클(Oracle) 성능 개선</title>
      <link>https://reference-m1.tistory.com/412</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.&amp;nbsp;SELECT&amp;nbsp;시에는&amp;nbsp;꼭&amp;nbsp;필요한&amp;nbsp;COLUMN만&amp;nbsp;조회한다.&lt;/h2&gt;
&lt;pre id=&quot;code_1690933606128&quot; class=&quot;sql prettyprint&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- BAD
SELECT *
  FROM TABLE;
-- GOOD
SEELECT COLUMN1
      , COLUMN2
   FROM TABLE;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.&amp;nbsp;WHERE&amp;nbsp;절에는&amp;nbsp;연산을&amp;nbsp;하지&amp;nbsp;않는다.&lt;/h2&gt;
&lt;pre id=&quot;code_1690933621149&quot; class=&quot;sql prettyprint&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- BAD
SEELECT COLUMN1
      , COLUMN2
   FROM TABLE
  WHERE FLOOR(COLUMN3) = 2;
-- GOOD
SEELECT COLUMN1
      , COLUMN2
   FROM TABLE
  WHERE COLUMN3 = BETWEEN 4 AND 5;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.&amp;nbsp;LIKE&amp;nbsp;조회 시&amp;nbsp;와일드카드&amp;nbsp;%는&amp;nbsp;가급적&amp;nbsp;뒤에만&amp;nbsp;사용한다.&lt;/h2&gt;
&lt;pre id=&quot;code_1690933633886&quot; class=&quot;sql prettyprint&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- BAD
SEELECT COLUMN1
      , COLUMN2
   FROM TABLE
  WHERE COLUMN3 LIKE '%DF%';
-- GOOD
SEELECT COLUMN1
      , COLUMN2
   FROM TABLE
  WHERE COLUMN3 LIKE 'DF%';&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. SELECT DISTINCT, UNION 과 같이 중복을 제거하는 연산은 자제한다.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복을 제거하는 연산은 시간이 많이 걸린다. DISTINCT는 원하는 컬럼에 대해서 중복을 제거하는 것이 아니라 SELECT 해온 모든 ROW에서 중복을 제거하므로 속도가 느리다. EXIST,&amp;nbsp;GROUP&amp;nbsp;BY를&amp;nbsp;활용하는게&amp;nbsp;좋다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5.&amp;nbsp;CHAR&amp;nbsp;VS&amp;nbsp;VARCHAR&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4byte&amp;nbsp;이하는&amp;nbsp;CHAR,&amp;nbsp;그&amp;nbsp;이상은&amp;nbsp;VARCHAR로&amp;nbsp;선언한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6.&amp;nbsp;BLOB&amp;nbsp;VS&amp;nbsp;TEXT&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은&amp;nbsp;양의&amp;nbsp;데이터&amp;nbsp;저장,&amp;nbsp;디폴트&amp;nbsp;값&amp;nbsp;지정불가&amp;nbsp;등&amp;nbsp;공통점이&amp;nbsp;있다.&amp;nbsp;차이점으로는&amp;nbsp;BOLB은&amp;nbsp;대소문자&amp;nbsp;구분,&amp;nbsp;TEXT는&amp;nbsp;구분하지&amp;nbsp;않는다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7.&amp;nbsp;PRIMARY&amp;nbsp;KEY,&amp;nbsp;UNIQUE&amp;nbsp;KEY&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동으로&amp;nbsp;인덱스가&amp;nbsp;생성된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8.&amp;nbsp;INNER&amp;nbsp;JOIN&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3개&amp;nbsp;이상의&amp;nbsp;테이블을&amp;nbsp;INNER&amp;nbsp;JOIN&amp;nbsp;할 때&amp;nbsp;크기가&amp;nbsp;가장&amp;nbsp;큰&amp;nbsp;테이블을&amp;nbsp;FROM절에&amp;nbsp;배치하고&amp;nbsp;INNER&amp;nbsp;JOIN&amp;nbsp;절에&amp;nbsp;남은&amp;nbsp;테이블을&amp;nbsp;작은&amp;nbsp;순서대로&amp;nbsp;배치하는&amp;nbsp;것이&amp;nbsp;좋다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;9.&amp;nbsp;EXPLAIN&amp;nbsp;실행&amp;nbsp;계획을&amp;nbsp;확인한다.&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능이&amp;nbsp;낮은&amp;nbsp;것&amp;nbsp;부터&amp;nbsp;높은&amp;nbsp;순으로&amp;nbsp;정렬하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ALL&amp;nbsp;:&amp;nbsp;테이블을&amp;nbsp;처음부터&amp;nbsp;끝까지&amp;nbsp;탐색하여&amp;nbsp;데이터를&amp;nbsp;찾음&amp;nbsp;(TABLE&amp;nbsp;FULL&amp;nbsp;SCAN)&lt;br /&gt;INDEX&amp;nbsp;:&amp;nbsp;인덱스를&amp;nbsp;처음부터&amp;nbsp;끝까지&amp;nbsp;탐색하여&amp;nbsp;데이터를&amp;nbsp;찾는&amp;nbsp;방식&amp;nbsp;(INDEX&amp;nbsp;FULL&amp;nbsp;SCAN)&lt;br /&gt;RANGE&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;(INDEX&amp;nbsp;RANGE&amp;nbsp;SCAN)&lt;br /&gt;REF&amp;nbsp;:&amp;nbsp;조인&amp;nbsp;할&amp;nbsp;때&amp;nbsp;PRIMARY&amp;nbsp;KEY&amp;nbsp;혹은&amp;nbsp;UNIQUE&amp;nbsp;Key&amp;nbsp;가&amp;nbsp;아닌&amp;nbsp;KEY로&amp;nbsp;매칭한&amp;nbsp;경우&lt;br /&gt;EQ_REF&amp;nbsp;:&amp;nbsp;조인&amp;nbsp;할&amp;nbsp;때&amp;nbsp;PRIMARY&amp;nbsp;KEY로&amp;nbsp;매칭&lt;/p&gt;</description>
      <category>데이터베이스/SQL</category>
      <category>오라클 성능</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/412</guid>
      <comments>https://reference-m1.tistory.com/412#entry412comment</comments>
      <pubDate>Wed, 2 Aug 2023 08:50:16 +0900</pubDate>
    </item>
    <item>
      <title>[Etc] 모바일웹, 웹앱, 하이브리드앱, 네이티브앱 차이점</title>
      <link>https://reference-m1.tistory.com/410</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IT_td02200000765-scaled.jpg&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOUL8v/btsl9uSFWkP/L7v3Zzhu6ZEhpUpP6crhSK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOUL8v/btsl9uSFWkP/L7v3Zzhu6ZEhpUpP6crhSK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOUL8v/btsl9uSFWkP/L7v3Zzhu6ZEhpUpP6crhSK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOUL8v%2Fbtsl9uSFWkP%2FL7v3Zzhu6ZEhpUpP6crhSK%2Fimg.jpg&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;2560&quot; height=&quot;2048&quot; data-filename=&quot;IT_td02200000765-scaled.jpg&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 방법과 내부 기능에 따라 다양한 유형의 애플리케이션(앱)이 있다. 개발에 필요한 기본적인 웹 서비스의 종류와 차이점을 알아보자.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 모바일 웹(Moblie Web)&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.627907%;&quot;&gt;개념&lt;/td&gt;
&lt;td style=&quot;width: 88.372093%;&quot;&gt;모바일 화면에 맞게 구성한 웹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.627907%;&quot;&gt;특징&lt;/td&gt;
&lt;td style=&quot;width: 88.372093%;&quot;&gt;단순히 웹 페이지를 모바일 화면에 맞게 줄인 형태&lt;br /&gt;개발(웹 페이지)&lt;br /&gt;실행(웹 브라우저)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.627907%;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 88.372093%;&quot;&gt;유비보수 용이&lt;br /&gt;브라우저 접근&lt;br /&gt;미설치&lt;br /&gt;스토어 심사 불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.627907%;&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;width: 88.372093%;&quot;&gt;네이티브 엑세스 불가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 웹 앱(Web App)&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 162px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; width: 11.860465%;&quot;&gt;개념&lt;/td&gt;
&lt;td style=&quot;height: 18px; width: 88.023256%;&quot;&gt;모바일 웹처럼 보이지만 구동방식이 앱처럼 보이게 한 앱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 54px;&quot;&gt;
&lt;td style=&quot;height: 54px; width: 11.860465%;&quot;&gt;특징&lt;/td&gt;
&lt;td style=&quot;height: 54px; width: 88.023256%;&quot;&gt;겉모습, 구동방식을 네이티브 앱처럼 구성&lt;br /&gt;개발(웹 페이지)&lt;br /&gt;실행(웹 브라우저)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 72px;&quot;&gt;
&lt;td style=&quot;height: 72px; width: 11.860465%;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;height: 72px; width: 88.023256%;&quot;&gt;비용, 시간 절감&lt;br /&gt;스토어 심사 불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; width: 11.860465%;&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;height: 18px; width: 88.023256%;&quot;&gt;네이티브 엑세스 불가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 하이브리드 앱(Hybrid App)&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 126px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; width: 11.976744%;&quot;&gt;개념&lt;/td&gt;
&lt;td style=&quot;height: 18px; width: 87.906977%;&quot;&gt;컨텐츠 영역은 웹 앱으로 개발하고, 앱 배포에 필요한 패키징 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 54px;&quot;&gt;
&lt;td style=&quot;height: 54px; width: 11.976744%;&quot;&gt;특징&lt;/td&gt;
&lt;td style=&quot;height: 54px; width: 87.906977%;&quot;&gt;겉모습, 구동방식을 네이티브 앱처럼 구성&lt;br /&gt;개발(모바일 웹 앱을 모바일 OS로 패키징)&lt;br /&gt;실행(스토어)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px; width: 11.976744%;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 87.906977%;&quot;&gt;&lt;span&gt;네이티브 , 브라우저 API를 사용해 다양한 개발 가능&lt;br /&gt;&lt;/span&gt;이티브 앱 보다 개발 비용, 시간 절감&lt;br /&gt;&lt;span&gt;&lt;span&gt;네이티브 앱 보다 유지보수 용이&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;디바이스 엑세스 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; width: 11.976744%;&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;height: 18px; width: 87.906977%;&quot;&gt;스토어 심사 필요&lt;br /&gt;웹 및 네이티브 개발 지식 모두 필요&lt;br /&gt;브라우저 성능에 따라 앱 성능 영향&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 네이티브 앱(Native App)&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 162px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;개념&lt;/td&gt;
&lt;td&gt;&lt;span&gt;모바일 기기에 최적화된 네이티브 언어로 개발된 앱&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;특징&lt;/td&gt;
&lt;td&gt;개발(OS별 운영체제 언어로 개발)&lt;br /&gt;실행(스토어)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;장점&lt;/td&gt;
&lt;td&gt;&lt;span&gt;디바이스 엑세스 가능&lt;br /&gt;&lt;/span&gt;높은 퍼포먼스&lt;br /&gt;빠른 속도 및 안정성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;단점&lt;/td&gt;
&lt;td&gt;스토어 심사 필요&lt;br /&gt;높은 개발, 운영 비용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;</description>
      <category>프로그래밍/Etc</category>
      <category>네이티브앱</category>
      <category>모바일웹</category>
      <category>웹앱</category>
      <category>하이브리드앱</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/410</guid>
      <comments>https://reference-m1.tistory.com/410#entry410comment</comments>
      <pubDate>Sun, 2 Jul 2023 12:26:31 +0900</pubDate>
    </item>
    <item>
      <title>[Etc] Spring Framework &amp;amp; Spring Boot With Java Support</title>
      <link>https://reference-m1.tistory.com/409</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 포스팅에 brew로 Java를 설치하는 방법에서 Java LTS 버전을 언급한 적이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reference-m1.tistory.com/397&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[프로그래밍/Etc] - [Etc] Mac Java 설치 및 관리 with Brew&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686300095223&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;[Etc] Mac Java 설치 및 관리 with Brew&quot; data-og-description=&quot;Mac에서의 Java 설치 및 여러 가지 Java버전을 관리하는 방법을 알아보자. Java 설치의 일반적인 방법은 직접 다운로드하는 방법이 있지만, Mac에서는 Brew를 통해 손쉽게 설치가 가능하다. Java 외의 모&quot; data-og-host=&quot;reference-m1.tistory.com&quot; data-og-source-url=&quot;https://reference-m1.tistory.com/397&quot; data-og-url=&quot;https://reference-m1.tistory.com/397&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/chDZcy/hySXcE0HvK/2PcTCymkxkeSqqyHDDqHx0/img.png?width=800&amp;amp;height=296&amp;amp;face=0_0_800_296,https://scrap.kakaocdn.net/dn/6Sjnu/hySWnHxplS/KV7mQkkkf2GbddDzgbbjZ0/img.png?width=800&amp;amp;height=296&amp;amp;face=0_0_800_296,https://scrap.kakaocdn.net/dn/bUE6LY/hySVCZPGzP/IjAD2KjJsUGwgzzDgcB5rK/img.png?width=1420&amp;amp;height=526&amp;amp;face=0_0_1420_526&quot;&gt;&lt;a href=&quot;https://reference-m1.tistory.com/397&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://reference-m1.tistory.com/397&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/chDZcy/hySXcE0HvK/2PcTCymkxkeSqqyHDDqHx0/img.png?width=800&amp;amp;height=296&amp;amp;face=0_0_800_296,https://scrap.kakaocdn.net/dn/6Sjnu/hySWnHxplS/KV7mQkkkf2GbddDzgbbjZ0/img.png?width=800&amp;amp;height=296&amp;amp;face=0_0_800_296,https://scrap.kakaocdn.net/dn/bUE6LY/hySVCZPGzP/IjAD2KjJsUGwgzzDgcB5rK/img.png?width=1420&amp;amp;height=526&amp;amp;face=0_0_1420_526');&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;[Etc] Mac Java 설치 및 관리 with Brew&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mac에서의 Java 설치 및 여러 가지 Java버전을 관리하는 방법을 알아보자. Java 설치의 일반적인 방법은 직접 다운로드하는 방법이 있지만, Mac에서는 Brew를 통해 손쉽게 설치가 가능하다. Java 외의 모&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;reference-m1.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;오래된 시스템을 보면 개발, 스테이징, 운영서버 등이 버전이 다른 경우가 있다. 고도화 작업뿐만 아니라 모든 프로젝트가 착수되기 전에 각 버전에 맞는 선정 작업이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 Spring Framework &amp;amp; Spring Boot에 지원되는 Java 버전(LTS)에 대해 확인하고 사용하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-12 오전 10.01.57.png&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;1300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cp9NQd/btsjlFK6Pdv/QUyZr5oeQsuMZ7Mqlr83pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cp9NQd/btsjlFK6Pdv/QUyZr5oeQsuMZ7Mqlr83pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cp9NQd/btsjlFK6Pdv/QUyZr5oeQsuMZ7Mqlr83pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcp9NQd%2FbtsjlFK6Pdv%2FQUyZr5oeQsuMZ7Mqlr83pk%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;1464&quot; height=&quot;1300&quot; data-filename=&quot;스크린샷 2023-06-12 오전 10.01.57.png&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;1300&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;a href=&quot;https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions&quot;&gt;https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686529412647&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Spring Framework Versions&quot; data-og-description=&quot;Spring Framework. Contribute to spring-projects/spring-framework development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions&quot; data-og-url=&quot;https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yBKY6/hySYMl1V7Y/542KpZBmJS83apvTkOszQk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yBKY6/hySYMl1V7Y/542KpZBmJS83apvTkOszQk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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 Framework Versions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spring Framework. Contribute to spring-projects/spring-framework development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/spring-projects/spring-boot/wiki/Supported-Versions&quot;&gt;https://github.com/spring-projects/spring-boot/wiki/Supported-Versions&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686529435930&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Supported Versions&quot; data-og-description=&quot;Spring Boot. Contribute to spring-projects/spring-boot development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/spring-projects/spring-boot/wiki/Supported-Versions&quot; data-og-url=&quot;https://github.com/spring-projects/spring-boot/wiki/Supported-Versions&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmaYul/hySW33YwG9/Hg4I5pLbjOxJUOWRLB4ADK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/spring-projects/spring-boot/wiki/Supported-Versions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/spring-projects/spring-boot/wiki/Supported-Versions&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmaYul/hySW33YwG9/Hg4I5pLbjOxJUOWRLB4ADK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;Supported Versions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot. Contribute to spring-projects/spring-boot development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.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;</description>
      <category>프로그래밍/Etc</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/409</guid>
      <comments>https://reference-m1.tistory.com/409#entry409comment</comments>
      <pubDate>Fri, 9 Jun 2023 17:48:36 +0900</pubDate>
    </item>
    <item>
      <title>[Back end] Spring Boot Quartz Scheduler</title>
      <link>https://reference-m1.tistory.com/408</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Quartz&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Quartz는 미리 결정된 시간 또는 예약된 시간에 작업을 예약하고 실행하는데 사용할 수 있는데 오픈 소스 라이브러리이다. 간단한 interval , Cront 표현식을 사용하여 작업할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;in-Memory, JDBC 방식 제공&lt;/li&gt;
&lt;li&gt;스케줄러 간 클러스터링&lt;/li&gt;
&lt;li&gt;시스템 Fail-over(Random 방식의 로드 분산처리)&lt;/li&gt;
&lt;li&gt;기본 플러그인 제공(ShutdownHookPlugin, LoggingHistoryPlugin)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;완벽한 로드 분산처리 불가(Random 방식)&lt;/li&gt;
&lt;li&gt;GUI 환경 미지원&lt;/li&gt;
&lt;li&gt;스케줄러 실행에 대한 히스토리 보관 미지원&lt;/li&gt;
&lt;li&gt;fixed delay 미지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Quartz Maven Dependency&lt;/h3&gt;
&lt;pre id=&quot;code_1684374471859&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.quartz-scheduler&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;quartz&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.3.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Quartz Gradle Dependency&lt;/h3&gt;
&lt;pre id=&quot;code_1684374484371&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// https://mvnrepository.com/artifact/org.quartz-scheduler/quartz
implementation 'org.quartz-scheduler:quartz:2.3.2'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Quartz&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Scheduler&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스케줄러 관리&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Job&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스케줄러에 의해 실행&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JobDataMap&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Job을 동작시키는데 필요한 Parameter 정보&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JobDetail&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Job을 실행하기 위핸 실행 정보(그룹, 이름, JobDataMap)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Trigger&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Job 실행 조건&lt;br /&gt;- Job(1) = Trigger(N) 구조 가능&lt;br /&gt;- SimpleTrigger : &amp;nbsp;반복 횟수( 카운트 + 1 수행), 반복 간격(ms)&lt;br /&gt;- CronTrigger : Cron 표현식&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;2. 공통 속성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 트리거 유형에는 추적하기 위한 키 속성이 있다. 그 외에도 공통적인 트리거 속성은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;jobKey : 트리거가 실행되는 작업ID&lt;/li&gt;
&lt;li&gt;startTime : 트리거의 일정이 처음 적용되는 시간&lt;/li&gt;
&lt;li&gt;endTime : 트리거의 일정이 더 이상 적용되지 않는 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Priority(우선순위)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트리거가 많이 있거나 트리거를 체크하는 워크스레드가 부족한 경우 Quartz가 같은 시간에 지정된 모든 트리거를 실행이 불가한 경우, priority 속성을 통해 지정할 수 있다. (디폴트 5)&lt;/li&gt;
&lt;li&gt;트리거의 실행 시간이 동일한 경우에만 우선순위 비교&lt;/li&gt;
&lt;li&gt;트리거의 작업이 복구 시 원래 트리거와 동일한 우선순위로 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Misfire(불발)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;불발 시 Job이 실행되어야 하는 시간을 의미&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;스케줄러가&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;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. SimpleTrigger&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작업을 특정 시점에 정확히 한번 실행하거나 특정 시점에 특정 간격으로 반복해서 실행하는 경우에 사용&lt;/li&gt;
&lt;li&gt;시작 시간, 종료 시간, 반복 횟수, 반복 간격이 포함&lt;/li&gt;
&lt;li&gt;반복 횟수는 0 또는 양의 정수&lt;/li&gt;
&lt;li&gt;반복 간격은 milliseconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. CronTrigger&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 180px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;필드&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;필수&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;값&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;허용 특수문자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;초(Seconds)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;0 ~ 59&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: center;&quot;&gt;, - * /&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;분(Minutes)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;0 ~ 59&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;, - * /&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;시(Hours)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;0 ~ 23&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: center;&quot;&gt;, - * /&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;일(Day-of-Month)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;1 ~ 31&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;, - * / ? L W&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;월(Month)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;0 ~ 11 or JAN ~ DEC&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: center;&quot;&gt;, - * /&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;요일(Day-of-Week)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;Y&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;1 ~ 7 or SUN ~ SAT&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;, - * / ? L #&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;년(Year)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;N&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;empty or 1979 ~ 2099&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: center;&quot;&gt;, - * /&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;'*' 모든 값 의미(매일, 매월, 매주 등)&lt;/li&gt;
&lt;li&gt;'?' 특정 값이 없음을 의미(일, 요일에서 사용가능)&lt;/li&gt;
&lt;li&gt;'-' 범위를 의미(MON-WED 값은 월요일에서 수요일)&lt;/li&gt;
&lt;li&gt;',' 여러 개의 값을 의미(MON, WED, FRI 값은 월, 수, 금)&lt;/li&gt;
&lt;li&gt;'/' 증분을 의미, 분이라고 할 때 3/20 - 20분마다 3분에 시작을 의미 (3, 23, 43)&lt;/li&gt;
&lt;li&gt;'L' 일 및 요일 필드에 허용되며 마지막을 의미 (마지막 일, 마지막 주)&lt;/li&gt;
&lt;li&gt;'W' 주어진 요일에 가장 가까운 평일을 지정하는데 사용 (15W 값은 매월 15일에서 가장 가까운 평일)&lt;/li&gt;
&lt;li&gt;'#' 해당 월의 n번째 요일을 지정하는데 사용 (6#3 또는 FRI#3 값은 매월 3번째 금요일)&lt;/li&gt;
&lt;li&gt;일 1~31의 값이 될 수 있지만 주어진 달이 며칠인지 주의 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 126px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 27.674419%; height: 18px;&quot;&gt;Cron 표현식&lt;/td&gt;
&lt;td style=&quot;width: 72.325581%; height: 18px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 27.674419%; height: 18px;&quot;&gt;0 0/5 * * * ?&lt;/td&gt;
&lt;td style=&quot;width: 72.325581%; height: 18px;&quot;&gt;5분 마다 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 27.674419%; height: 18px;&quot;&gt;0 0 12 * * ?&lt;/td&gt;
&lt;td style=&quot;width: 72.325581%; height: 18px;&quot;&gt;매일 12시에 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 27.674419%; height: 18px;&quot;&gt;10 0/5 * * * ?&lt;/td&gt;
&lt;td style=&quot;width: 72.325581%; height: 18px;&quot;&gt;10초를 기점으로 5분 마다 실행(10:00:10, 10:05:10 ...)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 27.674419%; height: 18px;&quot;&gt;0 30 10-13 ? * WED,FRI&lt;/td&gt;
&lt;td style=&quot;width: 72.325581%; height: 18px;&quot;&gt;매주 수요일, 금요일 10~13시 30분에 실행(10:30, 11:30, 12:30, 13:30)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 27.674419%; height: 18px;&quot;&gt;0 0/30 8-9 5,20 * ?&lt;/td&gt;
&lt;td style=&quot;width: 72.325581%; height: 18px;&quot;&gt;매월 5,20일에 8~9시 30분 마다 실행(8:30, 9:00, 9:30)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 27.674419%; height: 18px;&quot;&gt;0 0 12 ? * WED&lt;/td&gt;
&lt;td style=&quot;width: 72.325581%; height: 18px;&quot;&gt;매주 수요일 12시에 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cron Maker를 이용하여 표현식을 공부하거나, 검증하는데 사용하면 좋다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.cronmaker.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.cronmaker.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684383680200&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;CronMaker&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.cronmaker.com&quot; data-og-source-url=&quot;http://www.cronmaker.com/&quot; data-og-url=&quot;http://www.cronmaker.com/;jsessionid=node01x80hn6l9n36u19z6l8vocdcfz476962.node0?0&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.cronmaker.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.cronmaker.com/&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;CronMaker&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.cronmaker.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;h2 data-ke-size=&quot;size26&quot;&gt;5. SchedulerListeners&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스케줄러&amp;nbsp;자체 내에서&amp;nbsp;이벤트에&amp;nbsp;대한&amp;nbsp;알림을&amp;nbsp;수신(작업/트리거&amp;nbsp;추가,&amp;nbsp;제거,&amp;nbsp;오류,&amp;nbsp;종료&amp;nbsp;등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. Job&amp;nbsp;Stores&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RAM JobStore : 손쉬운&amp;nbsp;사용과&amp;nbsp;성능이&amp;nbsp;우수하지만&amp;nbsp;종료 시&amp;nbsp;모든&amp;nbsp;스케줄&amp;nbsp;정보가&amp;nbsp;유실(휘발성)&lt;/li&gt;
&lt;li&gt;JDBC JobStore : JDBC를 통해 스케줄 정보를 데이터베이스에 보관이 가능하지만, RAMJobStore에 비해 구성이 복잡하고 빠르지 않다. (Quartz가&amp;nbsp;사용할&amp;nbsp;DataSource&amp;nbsp;이름&amp;nbsp;지정&amp;nbsp;필요)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. Clustering&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JDBC JobStore에서만 클러스터링 지원(부하 분산 및 작업 장애 조치)&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;8. Quartz Table&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QRTZ_LOCKS : 작업 실행 인스턴스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QRTZ_JOB_DETAILS : 실행될 Job 정보(이름, 그룹, 클래스 등)&lt;br /&gt;QRTZ_TRIGGERS : Job을 실행할 스케줄 Trigger 정보(Trigger 종류 구분 및 시간)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QRTZ_CRON_TRIGGERS : Cron Trigger 정보(Cron Expression, Time Zone)&lt;br /&gt;QRTZ_SIMPLE_TRIGGERS&amp;nbsp;:&amp;nbsp;Simple&amp;nbsp;Trigger&amp;nbsp;정보(반복&amp;nbsp;횟수,&amp;nbsp;간격)&lt;br /&gt;QRTZ_CALENDARS : 달력 형태 스케줄러 정보(특정 범위에 스케줄을 동작시키지 않을 때 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QRTZ_SCHEDULER_STATE : 스케줄러 상태 확인(LAST_CHECKIN_TIME이 CHECKIN_INTERVAL 간격으로 갱신)&lt;br /&gt;QRTZ_FIRED_TRIGGERS&amp;nbsp;:&amp;nbsp;실행된&amp;nbsp;Trigger&amp;nbsp;정보&lt;br /&gt;QRTZ_PAUSED_TRIGGER_GRPS&amp;nbsp;:&amp;nbsp;정지된&amp;nbsp;Trigger&amp;nbsp;정보&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;quartz.png&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;864&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VMDnb/btsglAFTU6a/RfkRuy8bPGqRb2SZFFUUK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VMDnb/btsglAFTU6a/RfkRuy8bPGqRb2SZFFUUK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VMDnb/btsglAFTU6a/RfkRuy8bPGqRb2SZFFUUK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVMDnb%2FbtsglAFTU6a%2FRfkRuy8bPGqRb2SZFFUUK0%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;945&quot; height=&quot;864&quot; data-filename=&quot;quartz.png&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;864&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/Back end</category>
      <category>Quartz</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/408</guid>
      <comments>https://reference-m1.tistory.com/408#entry408comment</comments>
      <pubDate>Thu, 18 May 2023 13:33:38 +0900</pubDate>
    </item>
    <item>
      <title>[Back end] Spring Boot @Autowired null 에러</title>
      <link>https://reference-m1.tistory.com/406</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Thread를 통해 Service를 호출하려고 하면 @Autowired&amp;nbsp;null 관련 에러가 발생한다. Thread 클래스가 Bean으로 등록된 클래스가 아니어서 IOC Container를 통해 자동 주입되지 않는다. @Autowired는 Bean으로 등록된 클래스에서만 사용 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때는 Bean을 수동으로 주입하면 해결 가능하다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;ApplicationContextProvider&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1669080579209&quot; class=&quot;prettyprint java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

  private static ApplicationContext applicationContext;

  @Override
  public void setApplicationContext(ApplicationContext ctx) throws BeansException {
    applicationContext = ctx;
  }

  public static ApplicationContext getApplicationContext() {
    return applicationContext;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;BeanUtils&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1669080628253&quot; class=&quot;prettyprint java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.springframework.context.ApplicationContext;

import com.skcc.kw.common.ApplicationContextProvider;

public class BeanUtils {
  public static Object getBean(String bean) {
    ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
    return applicationContext.getBean(bean);
  }
}&lt;/code&gt;&lt;/pre&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;Example&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1669080884894&quot; class=&quot;prettyprint java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class UserService {
  ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1669080838012&quot; class=&quot;prettyprint java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class UserThread implements Runnable {

  // Bean 주입
  UserService userService = (UserService) BeanUtils.getBean(&quot;userService&quot;);
  
  ...
  
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Back end</category>
      <category>@Autowired null</category>
      <author>Reference M1</author>
      <guid isPermaLink="true">https://reference-m1.tistory.com/406</guid>
      <comments>https://reference-m1.tistory.com/406#entry406comment</comments>
      <pubDate>Tue, 22 Nov 2022 10:38:00 +0900</pubDate>
    </item>
  </channel>
</rss>