[{"data":1,"prerenderedAt":695},["ShallowReactive",2],{"post-document:\u002Fjava\u002Fadvanced\u002F2026\u002F08\u002F11\u002Fjava-annotations\u002F":3},{"id":4,"title":5,"body":6,"categories":676,"date":678,"description":679,"extension":680,"image":681,"key_concepts":681,"last_modified_at":681,"legacyPath":682,"meta":683,"navigation":138,"part":685,"path":686,"published":138,"robots":681,"seo":687,"series":688,"stem":689,"strengths":681,"summary":681,"tags":690,"tradeoffs":681,"__hash__":694},"posts\u002Fposts\u002FBackend\u002FJAVA\u002Fadvanced\u002F2026-08-11-java-annotations.md","Java 심화 Part 2: Annotation",{"type":7,"value":8,"toc":663},"minimark",[9,13,18,78,85,94,104,175,184,214,230,234,243,267,270,278,281,285,338,362,366,369,388,394,462,465,496,500,503,509,512,518,522,525,549,559,562,634,644,648,654,659],[10,11,5],"h2",{"id":12},"java-심화-part-2-annotation",[14,15,17],"h3",{"id":16},"_1-먼저-알아둘-단어","1. 먼저 알아둘 단어",[19,20,21,34],"table",{},[22,23,24],"thead",{},[25,26,27,31],"tr",{},[28,29,30],"th",{},"단어",[28,32,33],{},"정의",[35,36,37,46,54,62,70],"tbody",{},[25,38,39,43],{},[40,41,42],"td",{},"Annotation",[40,44,45],{},"클래스, 메서드, 필드 등에 추가 정보를 붙이는 Java 문법",[25,47,48,51],{},[40,49,50],{},"Metadata",[40,52,53],{},"코드의 실행 로직이 아니라 코드의 역할과 설정을 설명하는 정보",[25,55,56,59],{},[40,57,58],{},"컴파일러",[40,60,61],{},"Java 코드를 검사하고 바이트코드로 변환하는 도구",[25,63,64,67],{},[40,65,66],{},"Reflection",[40,68,69],{},"실행 중에 클래스, 메서드, 필드, 애너테이션 정보를 조회하는 기능",[25,71,72,75],{},[40,73,74],{},"Bean",[40,76,77],{},"Spring 컨테이너가 생성하고 관리하는 객체",[79,80,81],"blockquote",{},[82,83,84],"p",{},"Annotation은 클래스, 메서드, 필드 등에 추가적인 메타데이터를 붙이는 기능이다. 애너테이션 자체가 로직을 실행하는 것은 아니며, 컴파일러나 프레임워크가 이 정보를 읽고 처리한다.",[14,86,88,89,93],{"id":87},"_2-override-컴파일러에게-재정의를-알리기","2. ",[90,91,92],"code",{},"@Override",": 컴파일러에게 재정의를 알리기",[82,95,96,97,100,101,103],{},"Java에서 ",[90,98,99],{},"@","로 시작하는 것이 Annotation이다. 가장 익숙한 예시는 ",[90,102,92],{},"다.",[105,106,111],"pre",{"className":107,"code":108,"language":109,"meta":110,"style":110},"language-java shiki shiki-themes github-light github-dark","interface Animal {\n    void makeSound();\n}\n\nclass Dog implements Animal {\n    @Override\n    public void makeSound() {\n        System.out.println(\"멍멍!\");\n    }\n}\n","java","",[90,112,113,121,127,133,140,146,152,158,164,170],{"__ignoreMap":110},[114,115,118],"span",{"class":116,"line":117},"line",1,[114,119,120],{},"interface Animal {\n",[114,122,124],{"class":116,"line":123},2,[114,125,126],{},"    void makeSound();\n",[114,128,130],{"class":116,"line":129},3,[114,131,132],{},"}\n",[114,134,136],{"class":116,"line":135},4,[114,137,139],{"emptyLinePlaceholder":138},true,"\n",[114,141,143],{"class":116,"line":142},5,[114,144,145],{},"class Dog implements Animal {\n",[114,147,149],{"class":116,"line":148},6,[114,150,151],{},"    @Override\n",[114,153,155],{"class":116,"line":154},7,[114,156,157],{},"    public void makeSound() {\n",[114,159,161],{"class":116,"line":160},8,[114,162,163],{},"        System.out.println(\"멍멍!\");\n",[114,165,167],{"class":116,"line":166},9,[114,168,169],{},"    }\n",[114,171,173],{"class":116,"line":172},10,[114,174,132],{},[82,176,177,179,180,183],{},[90,178,92],{},"는 ",[90,181,182],{},"makeSound()","가 부모 클래스나 인터페이스의 메서드를 재정의했다는 사실을 컴파일러에 알려준다.",[105,185,187],{"className":107,"code":186,"language":109,"meta":110,"style":110},"class Dog implements Animal {\n    @Override\n    public void makeSond() {\n        System.out.println(\"멍멍!\");\n    }\n}\n",[90,188,189,193,197,202,206,210],{"__ignoreMap":110},[114,190,191],{"class":116,"line":117},[114,192,145],{},[114,194,195],{"class":116,"line":123},[114,196,151],{},[114,198,199],{"class":116,"line":129},[114,200,201],{},"    public void makeSond() {\n",[114,203,204],{"class":116,"line":135},[114,205,163],{},[114,207,208],{"class":116,"line":142},[114,209,169],{},[114,211,212],{"class":116,"line":148},[114,213,132],{},[82,215,216,217,179,220,223,224,226,227,229],{},"위 코드의 ",[90,218,219],{},"makeSond()",[90,221,222],{},"Animal","의 ",[90,225,182],{},"와 이름이 다르다. ",[90,228,92],{},"가 있기 때문에 컴파일러가 재정의가 아니라는 오류를 바로 알려준다.",[14,231,233],{"id":232},"_3-애너테이션은-혼자-실행되지-않는다","3. 애너테이션은 혼자 실행되지 않는다",[82,235,236,237,239,240,242],{},"다음 코드에서 ",[90,238,92],{},"가 직접 ",[90,241,182],{},"를 실행하는 것은 아니다.",[105,244,246],{"className":107,"code":245,"language":109,"meta":110,"style":110},"@Override\npublic void makeSound() {\n    System.out.println(\"멍멍!\");\n}\n",[90,247,248,253,258,263],{"__ignoreMap":110},[114,249,250],{"class":116,"line":117},[114,251,252],{},"@Override\n",[114,254,255],{"class":116,"line":123},[114,256,257],{},"public void makeSound() {\n",[114,259,260],{"class":116,"line":129},[114,261,262],{},"    System.out.println(\"멍멍!\");\n",[114,264,265],{"class":116,"line":135},[114,266,132],{},[82,268,269],{},"역할은 다음처럼 나뉜다.",[105,271,276],{"className":272,"code":274,"language":275,"meta":110},[273],"language-text","@Override\n    ↓\n재정의라는 정보를 표시한다\n    ↓\n컴파일러가 이 정보를 검사한다\n    ↓\n부모 또는 인터페이스 메서드가 없으면 오류를 보여 준다\n","text",[90,277,274],{"__ignoreMap":110},[82,279,280],{},"즉, 애너테이션은 표시이고 그 표시를 해석하는 컴파일러나 프레임워크가 실제 처리를 담당한다.",[14,282,284],{"id":283},"_4-자주-사용하는-java-애너테이션","4. 자주 사용하는 Java 애너테이션",[19,286,287,297],{},[22,288,289],{},[25,290,291,294],{},[28,292,293],{},"애너테이션",[28,295,296],{},"역할",[35,298,299,308,318,328],{},[25,300,301,305],{},[40,302,303],{},[90,304,92],{},[40,306,307],{},"부모 클래스 또는 인터페이스 메서드를 재정의했음을 표시",[25,309,310,315],{},[40,311,312],{},[90,313,314],{},"@Deprecated",[40,316,317],{},"더 이상 사용을 권장하지 않는 코드임을 표시",[25,319,320,325],{},[40,321,322],{},[90,323,324],{},"@SuppressWarnings",[40,326,327],{},"특정 컴파일 경고를 억제",[25,329,330,335],{},[40,331,332],{},[90,333,334],{},"@FunctionalInterface",[40,336,337],{},"함수형 인터페이스 규칙을 지키는지 검사",[105,339,341],{"className":107,"code":340,"language":109,"meta":110,"style":110},"@Deprecated\npublic void oldLogin() {\n    System.out.println(\"이 메서드는 더 이상 권장하지 않습니다.\");\n}\n",[90,342,343,348,353,358],{"__ignoreMap":110},[114,344,345],{"class":116,"line":117},[114,346,347],{},"@Deprecated\n",[114,349,350],{"class":116,"line":123},[114,351,352],{},"public void oldLogin() {\n",[114,354,355],{"class":116,"line":129},[114,356,357],{},"    System.out.println(\"이 메서드는 더 이상 권장하지 않습니다.\");\n",[114,359,360],{"class":116,"line":135},[114,361,132],{},[14,363,365],{"id":364},"_5-spring에서의-annotation","5. Spring에서의 Annotation",[82,367,368],{},"Spring에서는 애너테이션이 클래스의 역할과 처리 방식을 알려 주는 중요한 설정 정보가 된다.",[105,370,372],{"className":107,"code":371,"language":109,"meta":110,"style":110},"@Service\npublic class UserService {\n}\n",[90,373,374,379,384],{"__ignoreMap":110},[114,375,376],{"class":116,"line":117},[114,377,378],{},"@Service\n",[114,380,381],{"class":116,"line":123},[114,382,383],{},"public class UserService {\n",[114,385,386],{"class":116,"line":129},[114,387,132],{},[82,389,390,393],{},[90,391,392],{},"@Service","는 Spring에 이 클래스가 서비스 역할을 하며 관리할 객체 후보라는 정보를 전달한다.",[105,395,397],{"className":107,"code":396,"language":109,"meta":110,"style":110},"@RestController\npublic class UserController {\n    private final UserService userService;\n\n    public UserController(UserService userService) {\n        this.userService = userService;\n    }\n\n    @GetMapping(\"\u002Fusers\")\n    public List\u003CUser> getUsers() {\n        return userService.findAll();\n    }\n}\n",[90,398,399,404,409,414,418,423,428,432,436,441,446,452,457],{"__ignoreMap":110},[114,400,401],{"class":116,"line":117},[114,402,403],{},"@RestController\n",[114,405,406],{"class":116,"line":123},[114,407,408],{},"public class UserController {\n",[114,410,411],{"class":116,"line":129},[114,412,413],{},"    private final UserService userService;\n",[114,415,416],{"class":116,"line":135},[114,417,139],{"emptyLinePlaceholder":138},[114,419,420],{"class":116,"line":142},[114,421,422],{},"    public UserController(UserService userService) {\n",[114,424,425],{"class":116,"line":148},[114,426,427],{},"        this.userService = userService;\n",[114,429,430],{"class":116,"line":154},[114,431,169],{},[114,433,434],{"class":116,"line":160},[114,435,139],{"emptyLinePlaceholder":138},[114,437,438],{"class":116,"line":166},[114,439,440],{},"    @GetMapping(\"\u002Fusers\")\n",[114,442,443],{"class":116,"line":172},[114,444,445],{},"    public List\u003CUser> getUsers() {\n",[114,447,449],{"class":116,"line":448},11,[114,450,451],{},"        return userService.findAll();\n",[114,453,455],{"class":116,"line":454},12,[114,456,169],{},[114,458,460],{"class":116,"line":459},13,[114,461,132],{},[82,463,464],{},"위 코드에서:",[466,467,468,475,485],"ul",{},[469,470,471,474],"li",{},[90,472,473],{},"@RestController",": HTTP 요청을 처리하는 Controller 클래스임을 표시한다.",[469,476,477,480,481,484],{},[90,478,479],{},"@GetMapping(\"\u002Fusers\")",": ",[90,482,483],{},"\u002Fusers","로 들어오는 GET 요청을 이 메서드와 연결한다.",[469,486,487,488,491,492,495],{},"생성자: Spring이 필요한 ",[90,489,490],{},"UserService","를 주입할 수 있는 위치다. 생성자가 하나라면 보통 ",[90,493,494],{},"@Autowired","를 생략한다.",[14,497,499],{"id":498},"_6-reflection과-spring의-연결","6. Reflection과 Spring의 연결",[82,501,502],{},"Spring은 실행 중 Reflection을 이용해 클래스와 애너테이션을 검사한다.",[105,504,507],{"className":505,"code":506,"language":275,"meta":110},[273],"클래스 탐색\n    ↓\n@Service, @Controller 같은 애너테이션 발견\n    ↓\nSpring이 관리할 클래스인지 판단\n    ↓\n객체 생성\n    ↓\nBean으로 등록\n    ↓\n필요한 객체에 의존성 주입\n",[90,508,506],{"__ignoreMap":110},[82,510,511],{},"정리하면 역할은 다음과 같다.",[105,513,516],{"className":514,"code":515,"language":275,"meta":110},[273],"Annotation → 코드에 의미와 설정을 표시\nReflection → 실행 중 그 표시를 읽음\nSpring     → 읽은 정보를 기준으로 객체를 생성하고 관리\n",[90,517,515],{"__ignoreMap":110},[14,519,521],{"id":520},"_7-애너테이션에-값-넣기","7. 애너테이션에 값 넣기",[82,523,524],{},"애너테이션은 설정값도 받을 수 있다.",[105,526,528],{"className":107,"code":527,"language":109,"meta":110,"style":110},"@GetMapping(\"\u002Fusers\")\npublic List\u003CUser> getUsers() {\n    return userService.findAll();\n}\n",[90,529,530,535,540,545],{"__ignoreMap":110},[114,531,532],{"class":116,"line":117},[114,533,534],{},"@GetMapping(\"\u002Fusers\")\n",[114,536,537],{"class":116,"line":123},[114,538,539],{},"public List\u003CUser> getUsers() {\n",[114,541,542],{"class":116,"line":129},[114,543,544],{},"    return userService.findAll();\n",[114,546,547],{"class":116,"line":135},[114,548,132],{},[82,550,551,552,179,555,558],{},"여기서 ",[90,553,554],{},"\"\u002Fusers\"",[90,556,557],{},"@GetMapping","에 전달한 요청 경로 설정값이다.",[82,560,561],{},"직접 애너테이션을 만들 수도 있다.",[105,563,565],{"className":107,"code":564,"language":109,"meta":110,"style":110},"import java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\n@interface Role {\n    String value();\n}\n\n@Role(\"ADMIN\")\nclass AdminService {\n}\n",[90,566,567,572,577,582,587,591,596,601,606,611,615,619,624,629],{"__ignoreMap":110},[114,568,569],{"class":116,"line":117},[114,570,571],{},"import java.lang.annotation.ElementType;\n",[114,573,574],{"class":116,"line":123},[114,575,576],{},"import java.lang.annotation.Retention;\n",[114,578,579],{"class":116,"line":129},[114,580,581],{},"import java.lang.annotation.RetentionPolicy;\n",[114,583,584],{"class":116,"line":135},[114,585,586],{},"import java.lang.annotation.Target;\n",[114,588,589],{"class":116,"line":142},[114,590,139],{"emptyLinePlaceholder":138},[114,592,593],{"class":116,"line":148},[114,594,595],{},"@Retention(RetentionPolicy.RUNTIME)\n",[114,597,598],{"class":116,"line":154},[114,599,600],{},"@Target(ElementType.TYPE)\n",[114,602,603],{"class":116,"line":160},[114,604,605],{},"@interface Role {\n",[114,607,608],{"class":116,"line":166},[114,609,610],{},"    String value();\n",[114,612,613],{"class":116,"line":172},[114,614,132],{},[114,616,617],{"class":116,"line":448},[114,618,139],{"emptyLinePlaceholder":138},[114,620,621],{"class":116,"line":454},[114,622,623],{},"@Role(\"ADMIN\")\n",[114,625,626],{"class":116,"line":459},[114,627,628],{},"class AdminService {\n",[114,630,632],{"class":116,"line":631},14,[114,633,132],{},[82,635,636,639,640,643],{},[90,637,638],{},"@Retention(RetentionPolicy.RUNTIME)","은 실행 중 Reflection으로 이 애너테이션을 읽을 수 있게 한다. ",[90,641,642],{},"@Target(ElementType.TYPE)","은 이 애너테이션을 클래스나 인터페이스에 붙일 수 있다는 뜻이다.",[14,645,647],{"id":646},"_8-요약","8. 요약",[105,649,652],{"className":650,"code":651,"language":275,"meta":110},[273],"Annotation\n    ↓\n코드에 역할과 설정 정보를 표시한다\n    ↓\n컴파일러 또는 프레임워크가 정보를 읽는다\n    ↓\n검사, 요청 매핑, Bean 등록, 의존성 주입 같은 처리를 수행한다\n",[90,653,651],{"__ignoreMap":110},[79,655,656],{},[82,657,658],{},"Annotation은 코드에 메타데이터를 붙이는 기능이다. 컴파일러는 코드 검증에 사용하고, Spring 같은 프레임워크는 Reflection으로 읽어 객체 관리와 요청 처리에 활용한다.",[660,661,662],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":110,"searchDepth":123,"depth":123,"links":664},[665],{"id":12,"depth":123,"text":5,"children":666},[667,668,670,671,672,673,674,675],{"id":16,"depth":129,"text":17},{"id":87,"depth":129,"text":669},"2. @Override: 컴파일러에게 재정의를 알리기",{"id":232,"depth":129,"text":233},{"id":283,"depth":129,"text":284},{"id":364,"depth":129,"text":365},{"id":498,"depth":129,"text":499},{"id":520,"depth":129,"text":521},{"id":646,"depth":129,"text":647},[109,677],"advanced","2026-08-11 11:00:00 +0900","Java Annotation의 메타데이터 역할과 Override, Spring 컴포넌트, 요청 매핑, Reflection의 연결을 정리한다.","md",null,"\u002Fjava\u002Fadvanced\u002F2026\u002F08\u002F11\u002Fjava-annotations\u002F",{"layout":684},"post","2","\u002Fposts\u002Fbackend\u002Fjava\u002Fadvanced\u002F2026-08-11-java-annotations",{"title":5,"description":679},"Java 심화","posts\u002FBackend\u002FJAVA\u002Fadvanced\u002F2026-08-11-java-annotations",[691,42,66,692,693,50],"Java","Spring","Override","mnLUESgs4qzyJoTW-ASBLjfiEo3LdLqJf5wrxVaEMg0",1788744784348]