어노테이션

아마 자바에서 책이나 이런데에는 설명이 없고 보통 spring공부를 할때 처음 만나보는것일거다.

아마 그나마 책에서 몇번 봣던게 @override일텐데 학부생때는 당시 어노테이션이란게 그냥 있구나 하고 넘어갔었다.

이거저것 일하면서 공부하는김에 어노테이션의 동작 원리 문득 궁금해졌다.

먼저 @override 생김새는 어떻게 생겼고 어떻게 구동될까?

@ovrride의 내부 모습이다.

package java.lang;

import java.lang.annotation.*;

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a supertype. If a method is annotated with
 * this annotation type compilers are required to generate an error
 * message unless at least one of the following conditions hold:
 *
 * <ul><li>
 * The method does override or implement a method declared in a
 * supertype.
 * </li><li>
 * The method has a signature that is override-equivalent to that of
 * any public method declared in {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 8.4.8 Inheritance, Overriding, and Hiding
 * @jls 9.4.1 Inheritance and Overriding
 * @jls 9.6.4.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

그렇다면 저기서  @Target @Retetion, @interface등이 존재한다. 우리 입장에선 @Override 형태를 쉽게 썻던형태들이 저런 형태들로 계속해서 이루어진다 다른것들도 확인해보자

@GetMapping은 Spring에서 굉장히 많이쓰는 어노테이션이다 

/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.annotation.AliasFor;

/**
 * Annotation for mapping HTTP {@code GET} requests onto specific handler
 * methods.
 *
 * <p>Specifically, {@code @GetMapping} is a <em>composed annotation</em> that
 * acts as a shortcut for {@code @RequestMapping(method = RequestMethod.GET)}.
 *
 * @author Sam Brannen
 * @since 4.3
 * @see PostMapping
 * @see PutMapping
 * @see DeleteMapping
 * @see PatchMapping
 * @see RequestMapping
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {

   /**
    * Alias for {@link RequestMapping#name}.
    */
   @AliasFor(annotation = RequestMapping.class)
   String name() default "";

   /**
    * Alias for {@link RequestMapping#value}.
    */
   @AliasFor(annotation = RequestMapping.class)
   String[] value() default {};

   /**
    * Alias for {@link RequestMapping#path}.
    */
   @AliasFor(annotation = RequestMapping.class)
   String[] path() default {};

   /**
    * Alias for {@link RequestMapping#params}.
    */
   @AliasFor(annotation = RequestMapping.class)
   String[] params() default {};

   /**
    * Alias for {@link RequestMapping#headers}.
    */
   @AliasFor(annotation = RequestMapping.class)
   String[] headers() default {};

   /**
    * Alias for {@link RequestMapping#consumes}.
    * @since 4.3.5
    */
   @AliasFor(annotation = RequestMapping.class)
   String[] consumes() default {};

   /**
    * Alias for {@link RequestMapping#produces}.
    */
   @AliasFor(annotation = RequestMapping.class)
   String[] produces() default {};

}

 

마찬가지로 엄청 나게 많은 내부소스코드가 존재한다. 이런걸 하나하나따라가기 힘들다 그래서 우리는 검색의 힘과 어떻게 구동되는지 알아보자 

@Target ,  @Retention ,@interface 를 공통적으로 쓰는걸 볼수있다.

이중에서  @Target 이 뭔지 알아보자  보면 Element 타입을 리턴해준다고 한다. 

 

public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

또 여기서도 넘어가기전 궁금하게 생긴다.

@interface,interface의 차이점은 뭘까 우리가 자바에서는 평상시에 interface를 통해서 자바의 다형을 높여 개발코드 유지보수나 코드를 깔금히 정리하기 위해 많이 사용된다 그렇다면 @interface는 차이가 뭘까 ? 

스택오버플로우의 말을 빌려보자 

@interface는 사실상 우리가는 annotation type 정의이다 실제 인터페이스처럼 사용하는게 아니라 @override 같은 함수

수정자로 사용되는 새로운 annotation type이라고합니다.  댓글들을 보니 @inteface는 annotation type들의 확장을 위한 기능이고 interface는  class를 위한 확장이라고 하는듯 하다.  그래서 @Target이 annotation type의 기능성을 확장시켜준것이다. 그렇다면 어떤 타입이이 존재할까?

 

https://stackoverflow.com/questions/918393/whats-the-difference-between-interface-and-interface-in-java

 

 

What's the difference between interface and @interface in java?

I haven't touched Java since using JBuilder in the late 90's while at University, so I'm a little out of touch - at any rate I've been working on a small Java project this week, and using Intellij ...

stackoverflow.com

@Type이 리턴해주는 

Element.Method를 보자

여기서 Element. 는 여러개로 정의된다 보면 

public enum ElementType {
    /** Class, interface (including annotation type), enum, or record
     * declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE,

    /**
     * Module declaration.
     *
     * @since 9
     */
    MODULE,

    /**
     * {@preview Associated with records, a preview feature of the Java language.
     *
     *           This constant is associated with <i>records</i>, a preview
     *           feature of the Java language. Programs can only use this
     *           constant when preview features are enabled. Preview features
     *           may be removed in a future release, or upgraded to permanent
     *           features of the Java language.}
     *
     * Record component
     *
     * @jls 8.10.3 Record Members
     * @jls 9.7.4 Where Annotations May Appear
     *
     * @since 14
     */
    @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.RECORDS,
                                 essentialAPI=true)
    RECORD_COMPONENT;
}

내부에 여러가지 타입으로 정의되어 있지만 기능은 정확히는 아직 모르겠다 그나마 자주 쓰는것은 Method나 type을 주로 사용했던것 같다. 

http://cris.joongbu.ac.kr/course/java/api/java/lang/annotation/ElementType.html

 

ElementType (Java 2 Platform SE 5.0)

TYPE           클래스, 인터페이스 (어노테이션을 포함한다), 또는 emum 선언입니다.

cris.joongbu.ac.kr

위 URL이 예전꺼인듯 한데 크게 변경되는게 없을것같으니 일단 참고하시면 될것같다. 불안하시면 최대한 최신꺼로 찾으시면 충분할듯 하다.

어떤 형태의 Annotation을 잡아주는  Type이라고 이해했다 그렇다면 @Retention은 뭘까?

https://jeong-pro.tistory.com/234

 

아무 관심 없던 @Retention 어노테이션 정리(RetentionPolicy SOURCE vs CLASS vs RUNTIME)

@Retention annotation 관심 갖게 된 이유 자바에서 지향하는 방법은 아니지만 필요에 의해서 커스텀 애노테이션(Annotation)을 만들어야 할 때가 있습니다. 보통 예제 샘플 코드를 보면 메타 애노테이션

jeong-pro.tistory.com

Retention에 대한 정리가 되어 있어서 일단 링크를 올립니다. 

글을 빌리면 

@Retention 어노테이션의 속성으로 RetentionPolicy 라는 것이 있습니다.

여기에 올 수 있는 값은 source, class, runtime 이렇게 3가지가 있습니다. (공부하고나니 이름이 굉장히 직관적입니다.)

  • RetentionPolicy.SOURCE : 소스 코드(.java)까지 남아있는다.
  • RetentionPolicy.CLASS : 클래스 파일(.class)까지 남아있는다.(=바이트 코드)
  • RetentionPolicy.RUNTIME : 런타임까지 남아있는다.(=사실상 안 사라진다.)

출처: https://jeong-pro.tistory.com/234 [기본기를 쌓는 정아마추어 코딩블로그:티스토리]

나머지는 추후에 올리도록 하겠습니다 좀더 공부가 필요한부분이네요 이거 정리하는라 시간꽤 잡아먹네요 

+ Recent posts