<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>genie-99.log</title>
        <link>https://velog.io/</link>
        <description>컴퓨터의 모든 것을 배우자</description>
        <lastBuildDate>Sat, 19 Sep 2026 12:55:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. genie-99.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/genie-99" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Servlet ]]></title>
            <link>https://velog.io/@genie-99/Servlet</link>
            <guid>https://velog.io/@genie-99/Servlet</guid>
            <pubDate>Sat, 19 Sep 2026 12:55:38 GMT</pubDate>
            <description><![CDATA[<p>서블릿을 보면 굉장히 도움이 되는 무언가라고 많이 들었고 실제로도 많이 사용된다고 배웠는데... 
솔직히 저는 그게 뭔지 잘 모르겠네요.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/df20d90d-a3fa-446d-b530-cfe7ddf1aa0b/image.png" alt=""></p>
<p>Servlet을 공부하다보니 웹과 클라이언트간의 송수신에 대한 개념이 주용하더라구요.</p>
<hr>
<h3 id="-웹-서버-"><strong><em>[ 웹 서버! ]</em></strong></h3>
<ul>
<li>웹서버: 웹페이지를 사용자에게 전송하는 서버</li>
</ul>
<p><img src="https://velog.velcdn.com/images/genie-99/post/039ab3a8-c059-4c88-9a23-66ae68b2c51d/image.png" alt=""></p>
<blockquote>
<ul>
<li>웹 서버는 데이터를 전송하기 위해 HTTP 프로토콜을 사용합니다.</li>
</ul>
</blockquote>
<ul>
<li>일반적인 상황에서 사용자는 브라우저에 URL(<a href="https://velog.io/@genie-99)%EC%9D%84">https://velog.io/@genie-99)을</a> 입력합니다.</li>
<li>그리고 사용자는 웹페이지를 얻게 됩니다.</li>
<li>웹서버가 하는 일은 웹페이지를 사용자에게 전송하는 것입니다.</li>
</ul>
<hr>
<h2 id="servlet-api">Servlet API</h2>
<p><img src="https://velog.velcdn.com/images/genie-99/post/ef19b1b6-7634-4e88-86b9-d1ba0045456d/image.png" alt="">
DispatcherServlet를 해석해보면 <strong><em>Spring MVC에서 모든 요청을 가장 먼저 받아서, 적절한 Controller에게 넘겨주는 중앙 Servlet</em></strong>이라고 한다. 라고 나와있는데요...</p>
<p>여기서 Controller, Spring MVC, Servlet이라는 생소한 단어가 나오는데 우선 가장 기본이 되는 <strong><em>Servlet</em></strong>에 대해서 알아봅시다.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/71f0301a-b710-4bdd-aa8e-3f5b545b9e2e/image.png" alt=""></p>
<p>Specification(명세서)를 보면 container로 관리되는 Jakarta 기술이 사용된 웹 구성품이라고 나와있다.</p>
<p>즉, Servlet은 다음과 같은 특징을 가집니다.</p>
<blockquote>
<ul>
<li>Web Programming에서 Client의 요청을 처리</li>
</ul>
</blockquote>
<ul>
<li>그 결과를 다시 Client에게 전송하는 자바 프로그래밍 기술</li>
<li>Servlet 클래스의 구현 규칙을 따른다.</li>
</ul>
<h3 id="-servlet-lifecyle-"><strong><em>[ Servlet Lifecyle ]</em></strong></h3>
<p>서블릿은 서블릿 컨테이너 속에서 관리가 되며 init, service, destory 메서드를 통해서 만들어지고 실행되며 지워집니다.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/c2d48308-4a9d-4716-bafe-821eb6030078/image.png" alt=""></p>
<blockquote>
<ul>
<li><strong><em>서블릿의 라이프 사이클</em></strong>을 위한 세가지 필수적인 메소드를 정의</li>
</ul>
</blockquote>
<ul>
<li>init()</li>
<li>service()</li>
<li>destroy()</li>
</ul>
<h4 id="init">*init()</h4>
<blockquote>
<ul>
<li>서블릿 생명 주기 중 <strong><em>초기화 단계</em></strong>에 호출된다.</li>
</ul>
</blockquote>
<ul>
<li>javax.servlet.ServletConfig 인터페이스를 구현하는 오브젝트가 전달된다.</li>
<li>이를 통해 서블릿이 웹 애플리케이션에서 초기화 매개변수(parameter)에 접근할 수 있도록 한다.</li>
</ul>
<h4 id="service">*service()</h4>
<blockquote>
<ul>
<li>서블릿이 호출되면 이 service()메서드가 실행</li>
</ul>
</blockquote>
<ul>
<li>각각의 요청들은 별도로 나누어진 스레드에서 처리된다.</li>
<li>웹 컨테이너는 모든 요청에 대해 서블릿의 service() 메소드를 요청한다.</li>
<li>service() 메소드는 요청의 종류를 판별하고 요청을 처리할 적절한 메소드로 전달한다.</li>
</ul>
<h4 id="destroy">*destroy()</h4>
<blockquote>
<ul>
<li>서블릿 객체가 파괴되어야 할 때 호출된다.</li>
</ul>
</blockquote>
<ul>
<li>해당 서블릿이 가지고 있던 자원을 release 해준다.</li>
</ul>
<h3 id="-servlet-"><strong><em>[ Servlet ]</em></strong></h3>
<h4 id="servlet이-해야하는-일">Servlet이 해야하는 일</h4>
<blockquote>
<ul>
<li>HTTP 요청(request)을 받아서 처리.</li>
</ul>
</blockquote>
<ul>
<li>요청에 대한 응답(response)</li>
</ul>
<h4 id="servlet의-특징">Servlet의 특징</h4>
<blockquote>
<ol>
<li>Client의 요청에 동적으로 작동</li>
<li>Java Thread를 이용해 동작</li>
<li>HTML 변경시 재컴파일 필요</li>
<li>Java코드에 HTML이 들어가 있음</li>
<li>HTML을 사용해서 응답</li>
</ol>
</blockquote>
<h4 id="servlet-생성-방법">Servlet 생성 방법</h4>
<ol>
<li><p>@WebServlet</p>
<ul>
<li><p>해당 서블릿과 매핑될 url 지정</p>
<pre><code class="language-java">@WebServlet(name = &quot;helloServlet&quot;, urlPatterns =&quot;/hello&quot;)
public class HelloServlet extends HttpServlet {
  @Override
  protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException {

  }
}</code></pre>
</li>
</ul>
</li>
<li><p>HttpServlet 클래스 상속</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring이란?]]></title>
            <link>https://velog.io/@genie-99/Spring%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@genie-99/Spring%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Fri, 11 Sep 2026 13:28:48 GMT</pubDate>
            <description><![CDATA[<h1 id="spring">Spring?</h1>
<p>자바를 공부하다 보면 <strong>Spring</strong>이라는 단어가 종종 들린다.</p>
<p>그런데 뭔가 거리감이 느껴진다?랄까?</p>
<blockquote>
<p>Java를 공부하고 있는데 Spring을 사용한다는데... 이거 언어인가?</p>
</blockquote>
<p>그래서 이번에는 Spring이 무엇인지 정리해보려고 한다.</p>
<hr>
<h1 id="목차">목차</h1>
<ol>
<li>Spring이란?</li>
<li>Spring Framework란?</li>
<li>Spring은 왜 나왔을까?</li>
<li>Spring은 어디에서 사용되는가?</li>
<li>Spring Framework가 제공하는 기능</li>
<li>POJO와 IoC / DI</li>
<li>용어 정리</li>
</ol>
<hr>
<h2 id="1-spring이란">1. Spring이란?</h2>
<p>Spring 공식 사이트를 보면 정말 많은 프로젝트가 존재한다.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/48536784-e576-4936-b41e-0126a591c8b2/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/611bbf82-e345-4acb-983a-04c5147a4d0f/image.png" alt=""></p>
<p>이렇게 많이 있다....</p>
<p>Spring은 하나의 기술만을 의미하기도 하지만, 보통은 <strong>Spring Framework를 중심으로 한 여러 프로젝트의 생태계</strong>를 의미한다.</p>
<p>예를 들어</p>
<ul>
<li>Spring Framework</li>
<li>Spring Boot</li>
<li>Spring Data</li>
<li>Spring Security</li>
<li>Spring Cloud</li>
</ul>
<p>등이 있다.</p>
<p>즉 넓게 보면 <strong>Spring 생태계</strong>, 좁게 보면 <strong>Spring Framework</strong>를 의미한다고 생각하면 된다.</p>
<hr>
<h2 id="2-spring-framework란">2. Spring Framework란?</h2>
<p>Spring Framework는 <strong>Java 기반 애플리케이션을 만들 때 필요한 여러 기능과 구조를 제공하는 Framework</strong>이다.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/ee56e65a-e588-4e7c-8354-bf1ae78dcdc6/image.png" alt=""></p>
<h4 id="framework란">Framework란?</h4>
<blockquote>
<p>어떠한 목적을 쉽게 달성할 수 있도록 관련된 코드와 구조를 미리 만들어 둔 틀</p>
</blockquote>
<p>자동차를 만든다고 생각해보자.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/2c8916aa-dc8a-48bd-95f0-3650eec1d682/image.png" alt=""></p>
<p>처음부터 자동차 전체를 만드는 것이 아니라, 기본 틀은 이미 있으니까 그 위에 내가 필요한 것을 만드는 것! 이것이 Framework이다.</p>
<p><strong>즉,</strong> Spring은 우리가 Java로 실제 서비스를 만들 때 반복적으로 필요한 기능들을 미리 제공한다.</p>
<p>예를 들어 회원가입 기능을 만든다고 생각해보자.</p>
<p>우리가 실제로 만들고 싶은 것은</p>
<pre><code class="language-java">public void join(Member member) {
    // 회원가입 로직
}</code></pre>
<p>이런 비즈니스 로직이다.</p>
<p>하지만 실제 웹 서비스에서는 이것만 있으면 끝나는 것이 아니다.</p>
<pre><code class="language-text">HTTP 요청 받기

DB 연결

Transaction 관리

객체 생성과 관리

예외 처리

응답 반환</code></pre>
<p>등 다양한 기반 기능이 필요하다.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/9aff623e-07c1-4cff-9e6c-7002aaeb18cd/image.png" alt=""></p>
<p>Spring은 이런 과정들을 보다 편리하게 처리할 수 있도록 도와준다.</p>
<p>즉,</p>
<blockquote>
<p>Spring은 Java로 실제 애플리케이션을 만들 때 필요한 구조와 기능을 제공하는 Framework이다.</p>
</blockquote>
<p>라고 생각하면 된다.</p>
<hr>
<h2 id="3-spring은-왜-나왔을까">3. Spring은 왜 나왔을까?</h2>
<p>Java만으로도 프로그램을 만들 수 있다.</p>
<p>하지만 프로그램의 규모가 커지면 직접 관리해야 하는 것들이 많아진다.</p>
<p>예를 들어</p>
<pre><code class="language-text">회원가입
로그인
상품 조회
주문
결제</code></pre>
<p>와 같은 기능을 구현하면서 동시에</p>
<pre><code class="language-text">HTTP 요청 처리
객체 관리
DB 연결
Transaction 관리
테스트</code></pre>
<p>까지 직접 처리해야 한다.</p>
<p>Spring은 이러한 <strong>반복적인 기반 작업을 줄이고, 개발자가 비즈니스 로직에 집중할 수 있도록 하기 위해 등장한 Framework</strong>라고 이해하면 된다.</p>
<hr>
<h2 id="4-spring은-어디에서-사용되는가">4. Spring은 어디에서 사용되는가?</h2>
<p>이 부분이 가장 궁금했다.</p>
<blockquote>
<p>Spring이 도대체 어디에서 사용되는 건데?</p>
</blockquote>
<p>아래처럼 상품을 구매하는 상황을 생각해보자.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/efc14714-063d-41ff-8aa3-4e181dedd1ce/image.png" alt=""></p>
<p>대략적인 흐름은 다음과 같다.</p>
<pre><code class="language-text">사용자

↓

HTTP 요청

↓

Controller

↓

Service

↓

Repository

↓

Database</code></pre>
<p>Spring은 이 중간에 하나의 프로그램처럼 들어가는 것이 아니다.</p>
<p>이 <strong>전체 흐름의 여러 부분에서 Spring이 사용된다.</strong></p>
<p>예를 들어</p>
<pre><code class="language-text">HTTP 요청과 Controller 연결
→ Spring MVC

객체 생성과 관리
→ Spring Container

객체 간 연결
→ DI

DB 접근
→ Data Access

Transaction 관리
→ Spring Transaction</code></pre>
<p>이런 식이다.</p>
<hr>
<h2 id="5-spring-framework가-제공하는-기능">5. Spring Framework가 제공하는 기능</h2>
<p>Spring Framework가 제공하는 기능은 매우 많다.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/d08fea19-2b57-49fb-b8d5-72c2308e0372/image.png" alt=""></p>
<p>근데, 내가 설명하는 것만 해도 충분하지 않을까?</p>
<h3 id="core">Core</h3>
<p>Spring의 핵심 기능이다.</p>
<ul>
<li>IoC</li>
<li>DI</li>
<li>Bean</li>
<li>Spring Container</li>
<li>AOP</li>
</ul>
<h3 id="spring-mvc">Spring MVC</h3>
<p>웹 애플리케이션에서 HTTP 요청을 처리하고 Controller와 연결해주는 역할을 한다.</p>
<p>예를 들어</p>
<pre><code class="language-java">@Controller
public class OrderController {

    @PostMapping(&quot;/orders&quot;)
    public String order() {
        return &quot;orderComplete&quot;;
    }
}</code></pre>
<p>처럼 사용할 수 있다.</p>
<h3 id="data-access">Data Access</h3>
<p>DB와 관련된 기능을 제공한다.</p>
<ul>
<li>JDBC</li>
<li>Transaction</li>
<li>ORM</li>
</ul>
<h3 id="testing">Testing</h3>
<p>Spring을 사용하는 코드를 테스트할 수 있도록 여러 기능을 제공한다.</p>
<h3 id="integration">Integration</h3>
<p>Messaging, Scheduling 등 다른 기술과 연결하기 위한 기능도 제공한다.</p>
<hr>
<h2 id="6-pojo">6. POJO</h2>
<p>Spring의 특징을 공부하다 보면 <strong>POJO</strong>라는 단어가 등장한다.</p>
<h3 id="pojo--plain-old-java-object">POJO = Plain Old Java Object</h3>
<p>말 그대로 <strong>평범한 Java 객체</strong>이다.</p>
<pre><code class="language-java">public class Member {

    private String name;

}</code></pre>
<p>특정 Framework의 클래스를 반드시 상속하지 않아도 되는 일반적인 Java 객체이다.</p>
<p>Spring은 이러한 일반 Java 객체를 중심으로 애플리케이션을 구성할 수 있도록 도와준다.</p>
<hr>
<h2 id="7-ioc--di">7. IoC / DI</h2>
<h3 id="ioc--inversion-of-control">IoC = Inversion of Control</h3>
<p>한국어로는 <strong>제어의 역전</strong>이다.</p>
<p>일반적인 Java 코드에서는 필요한 객체를 직접 만든다.</p>
<pre><code class="language-java">OrderRepository repository = new OrderRepository();</code></pre>
<p>하지만 Spring에서는 객체의 생성과 관리를 Spring에게 맡길 수 있다.</p>
<pre><code class="language-text">Spring Container

↓

OrderRepository 생성

↓

OrderService에 전달</code></pre>
<p>즉 객체를 생성하고 관리하는 제어권이 개발자 코드에서 Framework 쪽으로 이동한다.</p>
<p>그래서 <strong>제어의 역전</strong>이라고 한다.</p>
<hr>
<h3 id="di--dependency-injection">DI = Dependency Injection</h3>
<p>DI는 <strong>Dependency Injection</strong>, 즉 <strong>의존성 주입</strong>이다.</p>
<p>예를 들어</p>
<pre><code class="language-java">public OrderService(OrderRepository repository) {
    this.repository = repository;
}</code></pre>
<p><code>OrderService</code>는 <code>OrderRepository</code>가 필요하다.</p>
<p>그런데 직접 생성하지 않고 외부에서 전달받는다.</p>
<pre><code class="language-text">Spring Container

↓

OrderRepository

↓

OrderService</code></pre>
<p>이렇게 필요한 객체를 외부에서 넣어주는 것이 <strong>DI</strong>이다.</p>
<hr>
<h3 id="다음-이야기">다음 이야기</h3>
<p>아직까지 Spring이라는 개념이 명확하게 이해된 것은 아니지만 Spring 이라는 거대한 바다에 이제 들어갈 준비가 되었다? 다음에는 Container과 Bean에 대해서 한번 공부해 보는 것이 어떨까 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Annotation — @Override를 통해서…]]></title>
            <link>https://velog.io/@genie-99/Annotation-Override%EB%A5%BC-%ED%86%B5%ED%95%B4%EC%84%9C</link>
            <guid>https://velog.io/@genie-99/Annotation-Override%EB%A5%BC-%ED%86%B5%ED%95%B4%EC%84%9C</guid>
            <pubDate>Sun, 06 Sep 2026 11:57:34 GMT</pubDate>
            <description><![CDATA[<p>자바를 공부한 지 2달째다. 공부하면서 <code>@Override</code>를 통해 애너테이션(Annotation)을 처음 접했고, 이후에도 다양한 애너테이션을 사용하게 되었다.</p>
<p>스프링을 공부하기 시작한 지금, 애너테이션이 정확히 무엇인지 조금 더 자세히 알아보고 싶어 찾아보았다.</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/1aa5d900-a614-4e7a-8ded-7c33aebd386b/image.png" alt="Override의 정의"></p>
<p>사진을 보면 <code>@Override</code>의 정의는 생각보다 짧다.</p>
<p>이 정의를 바탕으로 <strong>애너테이션이 무엇인지</strong>, 그리고 <strong><code>@Target</code>, <code>@Retention</code>, <code>public @interface Override</code>가 각각 무엇을 의미하는지</strong> 공부해 보자.</p>
<hr>
<h2 id="annotation은-어떤-역할을-할까">Annotation은 어떤 역할을 할까?</h2>
<p>애너테이션은 코드에 부가적인 정보를 제공하는 <strong>메타데이터(metadata)</strong>다. Oracle의 Java 공식 문서에서는 애너테이션의 대표적인 활용을 다음과 같이 설명한다. (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/">Oracle 공식 문서</a>)</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/481a5542-b620-4b60-993b-d299ec2bdc85/image.png" alt="애너테이션의 대표적인 활용"></p>
<h3 id="1-information-for-the-compiler">1. Information for the compiler</h3>
<p><strong>컴파일러가 오류를 찾아내거나 경고를 억제할 때 사용할 정보를 전달한다.</strong></p>
<p>예를 들어 <code>@Override</code>는 해당 메서드가 상위 타입의 메서드를 재정의하거나 구현하려는 것임을 컴파일러에 알린다. 컴파일러는 이것이 올바른지 검사하고, 조건에 맞지 않으면 컴파일 오류를 발생시킨다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override API 문서</a>)</p>
<p><code>@Override</code>를 붙였기 때문에 메서드가 재정의되는 것은 아니다. <strong>재정의는 애너테이션 없이도 가능하고, <code>@Override</code>는 그 의도가 올바르게 구현되었는지 검사하는 데 도움을 준다.</strong> (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html">Oracle 공식 문서</a>)</p>
<h3 id="2-compile-time-and-deployment-time-processing">2. Compile-time and deployment-time processing</h3>
<p><strong>컴파일 또는 배포 과정에서 도구가 코드나 설정 파일 등을 생성하는 데 사용할 정보를 전달한다.</strong> (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/">Oracle 공식 문서</a>)</p>
<p>예를 들어 Lombok의 <code>@Data</code>가 있다. Lombok은 컴파일 과정에 관여하여 이 애너테이션을 처리하고, getter·setter 등 필요한 코드를 생성한다. 여기서 실제로 처리하는 주체는 <strong>빌드 도구 자체가 아니라, 빌드 과정에 연결된 Lombok</strong>이다. (<a href="https://projectlombok.org/features/Data">Lombok @Data 문서</a>, <a href="https://projectlombok.org/contributing/lombok-execution-path">Lombok 실행 과정</a>)</p>
<h3 id="3-runtime-processing">3. Runtime processing</h3>
<p><strong>실행 중에 프로그램이나 프레임워크가 읽고 활용할 정보를 제공한다.</strong></p>
<p>예를 들어 Spring은 <code>@Autowired</code> 정보를 처리하여, 자신이 관리하는 객체에 필요한 의존 객체를 주입한다. 실제 처리는 애너테이션 자체가 아니라 Spring의 처리 코드가 담당한다. (<a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html">Spring 공식 문서</a>)</p>
<h3 id="그렇다면-누구에게-정보를-전달하는-걸까">그렇다면… 누구에게 정보를 전달하는 걸까?</h3>
<p>애너테이션에 따라 <strong>컴파일러, Lombok과 같은 도구, Spring과 같은 프레임워크</strong>가 정보를 읽고 처리한다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override</a>, <a href="https://projectlombok.org/contributing/lombok-execution-path">Lombok</a>, <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html">Spring</a>)</p>
<blockquote>
<p><strong>애너테이션은 그 자체로 기능을 실행하는 코드가 아니다.</strong><br><strong>애너테이션에 담긴 정보를 읽고 처리하는 주체가 있어야 한다.</strong> (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/">Oracle 공식 문서</a>)</p>
</blockquote>
<hr>
<h2 id="annotation의-종류">Annotation의 종류</h2>
<h3 id="built-in-annotation">Built-in Annotation</h3>
<p>자바에서 기본적으로 제공하는 애너테이션이다.</p>
<p>대표적인 예로 <code>@Override</code>, <code>@Deprecated</code>, <code>@SuppressWarnings</code>, <code>@SafeVarargs</code>, <code>@FunctionalInterface</code> 등이 있다. (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html">Oracle 공식 문서</a>)</p>
<h3 id="meta-annotation">Meta Annotation</h3>
<p><strong>다른 애너테이션의 선언에 붙여 사용하는 애너테이션</strong>이다.</p>
<p>대표적인 예로 <code>@Target</code>, <code>@Retention</code>, <code>@Documented</code>, <code>@Inherited</code>, <code>@Repeatable</code>이 있다. (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html">Oracle 공식 문서</a>)</p>
<p>여기서 주의할 점이 있다. <strong>Built-in과 Meta는 서로 완전히 분리된 분류가 아니다.</strong> Built-in은 “누가 제공하는가”, Meta는 “어디에 사용하는가”에 관한 구분이다. 따라서 자바가 기본으로 제공하는 <code>@Target</code>과 <code>@Retention</code>은 두 설명에 모두 해당한다. (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html">Oracle 공식 문서</a>)</p>
<p>다시 <code>@Override</code>의 정의를 보자.</p>
<pre><code class="language-java">@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}</code></pre>
<p>어? <code>@Override</code>라는 애너테이션을 정의한 곳에도 애너테이션이 붙어 있다!</p>
<p>이제 위에 붙은 <code>@Target</code>과 <code>@Retention</code>이 <strong>메타 애너테이션</strong>이라는 것을 알게 되었으니, 각각 무엇을 의미하는지 알아보자. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override API 문서</a>)</p>
<hr>
<h2 id="target--어디에-붙일-수-있을까">@Target — 어디에 붙일 수 있을까?</h2>
<p>Target은 ‘대상’이라는 뜻이다.</p>
<p><code>@Target</code>은 <strong>정의하려는 애너테이션을 코드의 어떤 위치에 붙일 수 있는지 지정한다.</strong> 사용할 수 있는 위치는 <code>ElementType</code>에 정의된 값으로 나타낸다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/Target.html">Target API 문서</a>)</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/b20be2b2-5718-499f-8c5a-8438b8aeeb73/image.png" alt="ElementType의 종류"></p>
<p>영어 이름을 보면 어느 위치에 사용할 수 있는지 비교적 직관적으로 파악할 수 있다.</p>
<p>예를 들어 <code>METHOD</code>는 메서드 선언, <code>FIELD</code>는 필드 선언, <code>TYPE</code>은 클래스·인터페이스 등의 타입 선언, <code>ANNOTATION_TYPE</code>은 애너테이션 선언을 의미한다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/ElementType.html">ElementType API 문서</a>)</p>
<p><code>@Override</code>에는 다음과 같이 지정되어 있다.</p>
<pre><code class="language-java">@Target(ElementType.METHOD)</code></pre>
<p>즉, <strong><code>@Override</code>는 메서드 선언에 붙일 수 있는 애너테이션</strong>이라는 뜻이다. 클래스나 필드 선언에 붙이면 컴파일 오류가 발생한다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override API 문서</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/Target.html">Target API 문서</a>)</p>
<hr>
<h2 id="retention--언제까지-남겨-둘까">@Retention — 언제까지 남겨 둘까?</h2>
<p>Retention은 ‘보유’ 또는 ‘유지’라는 뜻이다.</p>
<p><code>@Retention</code>은 <strong>코드에 붙인 애너테이션의 정보를 어느 단계까지 유지할지 지정한다.</strong> (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/Retention.html">Retention API 문서</a>)</p>
<p><img src="https://velog.velcdn.com/images/genie-99/post/3f2a854e-b0f6-4114-9c2b-705cd5c6610b/image.png" alt="RetentionPolicy의 종류"></p>
<p>보존 정책은 다음 세 가지로 구분된다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/RetentionPolicy.html">RetentionPolicy API 문서</a>)</p>
<table>
<thead>
<tr>
<th>보존 정책</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><code>SOURCE</code></td>
<td>소스 코드에만 남으며, 컴파일 결과인 <code>.class</code> 파일에는 기록되지 않는다.</td>
</tr>
<tr>
<td><code>CLASS</code></td>
<td><code>.class</code> 파일에 기록되지만, 실행 중 일반적인 리플렉션으로는 조회할 수 없다.</td>
</tr>
<tr>
<td><code>RUNTIME</code></td>
<td><code>.class</code> 파일에 기록되고 실행 중에도 유지되어, 리플렉션으로 조회할 수 있다.</td>
</tr>
</tbody></table>
<p>여기서 <strong><code>SOURCE</code>라고 해서 컴파일러가 애너테이션을 아예 읽지 않는다는 뜻은 아니다.</strong> <code>@Override</code>처럼 컴파일 과정에서 검사에 사용되지만, <code>.class</code> 파일에는 남지 않는 경우가 있다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override API 문서</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/RetentionPolicy.html">RetentionPolicy API 문서</a>)</p>
<p>따라서 <code>@Override</code>에 붙은 다음 코드는,</p>
<pre><code class="language-java">@Retention(RetentionPolicy.SOURCE)</code></pre>
<p><strong>“코드에 붙인 <code>@Override</code> 정보는 컴파일된 <code>.class</code> 파일에는 남기지 않는다”</strong>라는 뜻이다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override API 문서</a>, <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/RetentionPolicy.html">RetentionPolicy API 문서</a>)</p>
<p>참고로 애너테이션을 정의할 때 <code>@Retention</code>을 생략하면 기본값은 <code>CLASS</code>다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/Retention.html">Retention API 문서</a>)</p>
<hr>
<h2 id="custom-annotation을-만들어-보자">Custom Annotation을 만들어 보자</h2>
<p>직접 애너테이션을 정의할 때는 <strong><code>@interface</code> 뒤에 애너테이션 이름을 작성한다.</strong></p>
<p>중괄호 안에는 애너테이션이 전달할 정보를 정의할 수 있다. 이를 <strong>요소(element)</strong>라고 부르며, 메서드 선언과 비슷하게 <code>타입 이름();</code> 형태로 작성한다. (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/declaring.html">Oracle 공식 문서</a>)</p>
<pre><code class="language-java">// AnnotationName.java
public @interface AnnotationName {
    String name();
    int count() default 1;
}</code></pre>
<p>여기서 <code>name</code>은 기본값이 없으므로 애너테이션을 사용할 때 반드시 값을 지정해야 한다. 반면 <code>count</code>는 기본값이 <code>1</code>이므로 생략할 수 있다. (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/declaring.html">Oracle 공식 문서</a>)</p>
<pre><code class="language-java">// count를 생략하면 기본값인 1이 적용된다.
@AnnotationName(name = &quot;이름&quot;)
class Example {
}</code></pre>
<p>기본값 대신 다른 값을 지정할 수도 있다.</p>
<pre><code class="language-java">@AnnotationName(name = &quot;이름&quot;, count = 3)
class AnotherExample {
}</code></pre>
<p>즉, <code>name()</code>과 <code>count()</code>는 여기서 어떤 동작을 구현하는 코드가 아니라, <strong>애너테이션에 어떤 이름과 타입의 정보를 담을 수 있는지 정의하는 부분</strong>이다. (<a href="https://docs.oracle.com/javase/tutorial/java/annotations/declaring.html">Oracle 공식 문서</a>)</p>
<h3 id="target의-정의에서도-같은-형태를-찾을-수-있다">@Target의 정의에서도 같은 형태를 찾을 수 있다!</h3>
<p><img src="https://velog.velcdn.com/images/genie-99/post/d35d64a0-86c7-44af-9ef2-4ae8bfec2e09/image.png" alt="Target의 정의"></p>
<p>사진에서 주목할 부분은 다음 코드다.</p>
<pre><code class="language-java">ElementType[] value();</code></pre>
<p>요소의 이름은 <code>value</code>이고, 타입은 <code>ElementType[]</code>이다. 기본값을 지정하는 <code>default</code>가 없으므로 <strong><code>@Target</code>을 사용할 때는 <code>value</code>에 해당하는 값을 반드시 지정해야 한다.</strong> (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/Target.html">Target API 문서</a>)</p>
<p>그런데 앞에서는 <code>value =</code> 없이 사용했다.</p>
<pre><code class="language-java">@Target(ElementType.METHOD)</code></pre>
<p>왜 가능할까?</p>
<p>애너테이션에는 <strong><code>value</code>라는 이름의 요소에만 값을 지정하는 경우, <code>value =</code>를 생략할 수 있는 문법</strong>이 있기 때문이다. 다른 요소가 있다면, 생략하는 요소에는 기본값이 있어야 한다. 또한 배열 형태의 요소에 값을 하나만 지정할 때는 <code>{}</code>도 생략할 수 있다. 따라서 아래 세 표현은 같은 의미다. (<a href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.7.3">Java 언어 명세 — 단일 요소 애너테이션</a>)</p>
<pre><code class="language-java">// 기본 형태
@Target(value = {ElementType.METHOD})

// value = 생략
@Target({ElementType.METHOD})

// 값이 하나이므로 배열의 중괄호도 생략
@Target(ElementType.METHOD)</code></pre>
<p>위 코드는 세 가지 대체 표현을 비교한 것으로, 실제 사용 시에는 그중 하나만 애너테이션 선언 위에 붙이면 된다.</p>
<p>즉, <strong>값 자체를 생략한 것이 아니라, 값을 지정하는 문법의 일부를 생략한 것</strong>이다. (<a href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.7.3">Java 언어 명세</a>)</p>
<hr>
<h2 id="다시-override를-보면">다시 @Override를 보면…</h2>
<pre><code class="language-java">@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}</code></pre>
<p>이제 이 정의는 다음과 같이 읽을 수 있다.</p>
<blockquote>
<p><strong><code>Override</code>라는 애너테이션을 정의한다.</strong><br><strong>이 애너테이션은 메서드 선언에 붙일 수 있고, 코드에 붙인 애너테이션 정보는 <code>.class</code> 파일에는 남기지 않는다.</strong> (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override API 문서</a>)</p>
</blockquote>
<p>그리고 실제로 재정의가 올바른지 검사하는 주체는, 이 짧은 애너테이션 정의 안에 있는 코드가 아니라 <strong>자바 컴파일러</strong>다. (<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Override API 문서</a>)</p>
<hr>
<h2 id="참고-자료">참고 자료</h2>
<p><a href="https://docs.oracle.com/javase/tutorial/java/annotations/">Oracle — Annotations</a> · <a href="https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html">Predefined Annotation Types</a> · <a href="https://docs.oracle.com/javase/tutorial/java/annotations/declaring.html">Declaring an Annotation Type</a></p>
<p><a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Override.html">Java SE 21 API — Override</a> · <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/Target.html">Target</a> · <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/ElementType.html">ElementType</a> · <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/Retention.html">Retention</a> · <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/annotation/RetentionPolicy.html">RetentionPolicy</a></p>
<p><a href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.7.3">Java 언어 명세 — Single-Element Annotations</a></p>
<p><a href="https://projectlombok.org/features/Data">Project Lombok — @Data</a> · <a href="https://projectlombok.org/contributing/lombok-execution-path">Lombok Execution Path</a></p>
<p><a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html">Spring — AutowiredAnnotationBeanPostProcessor</a></p>
]]></description>
        </item>
    </channel>
</rss>