@Retention

@Retention ์–ด๋…ธํ…Œ์ด์…˜์€ ์–ด๋…ธํ…Œ์ด์…˜์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ์ฆ‰, ์–ด๋…ธํ…Œ์ด์…˜์ด ์–ธ์ œ๊นŒ์ง€ ์‚ด์•„ ์žˆ์„์ง€๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

package java.lang.annotation;

/**
 * Indicates how long annotations with the annotated type are to
 * be retained.  If no Retention annotation is present on
 * an annotation type declaration, the retention policy defaults to
 * {@code RetentionPolicy.CLASS}.
 *
 * <p>A Retention meta-annotation has effect only if the
 * meta-annotated type is used directly for annotation.  It has no
 * effect if the meta-annotated type is used as a member type in
 * another annotation type.
 *
 * @author  Joshua Bloch
 * @since 1.5
 * @jls 9.6.4.2 @Retention
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

RetentionPolicy

@Retention ์–ด๋…ธํ…Œ์ด์…˜์˜ ์†์„ฑ์œผ๋กœ, SOURCE, CLASS, RUNTIME 3๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • RetentionPolicy.SOURCE : ์†Œ์Šค์ฝ”๋“œ(.java)๊นŒ์ง€ ์œ ์ง€(์ปดํŒŒ์ผ ๊ณผ์ •์—์„œ ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ณด ์‚ฌ๋ผ์ง)

  • RetentionPolicy.CLASS : ํด๋ž˜์ŠคํŒŒ์ผ(.class)๊นŒ์ง€ ์œ ์ง€(๋Ÿฐํƒ€์ž„์‹œ ์œ ์ง€์•ˆ๋จ)

  • RetentionPolicy.RUNTIME : ๋Ÿฐํƒ€์ž„์‹œ์ ๊นŒ์ง€ ์œ ์ง€ (Reflection API๋กœ ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ณด ์กฐํšŒ ๊ฐ€๋Šฅ)

๊ฐ ์ข…๋ฅ˜๋ณ„๋กœ ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉฐ, ์ž์„ธํžˆ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค.

RetentionPolicy.SOURCE

RetentionPolicy.SOURCE ๋ฅผ ๋ฉ”ํƒ€ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์„ ์–ธํ•œ ์–ด๋…ธํ…Œ์ด์…˜์ค‘ lombok์˜ @Getter๋ฅผ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค.

  • Item.java : lombok์„ ์‚ฌ์šฉํ•œ POJO ํด๋ž˜์Šค

    import lombok.Getter;
    import lombok.Setter;
    
    @Getter
    @Setter
    public class Item {
        private long Id;
        private String name;
    }
  • @Getter

    package lombok;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.FIELD, ElementType.TYPE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Getter {
        AccessLevel value() default AccessLevel.PUBLIC;
    
        Getter.AnyAnnotation[] onMethod() default {};
    
        boolean lazy() default false;
    
        /** @deprecated */
        @Deprecated
        @Retention(RetentionPolicy.SOURCE)
        @Target({})
        public @interface AnyAnnotation {
        }
    }

    @Getter ์–ด๋…ธํ…Œ์ด์…˜ ๋‚ด๋ถ€์— Retention(RetentionPolicy.SOURCE) ๋ฉ”ํƒ€ ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ RetentionPolicy.SOURCE ์ด๋ฏ€๋กœ ์†Œ์Šค์ฝ”๋“œ(.java)๊นŒ์ง€ ์–ด๋…ธํ…Œ์ด์…˜์ด ๋‚จ์•„ ์žˆ๊ณ , ์ปดํŒŒ์ผ ์ดํ›„์—๋Š” ์‚ฌ๋ผ์งˆ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Item.class

      public class Item {
          private long Id;
          private String name;
    
          public Item() {
          }
    
          public long getId() {
              return this.Id;
          }
    
          public String getName() {
              return this.name;
          }
    
          public void setId(long Id) {
              this.Id = Id;
          }
    
          public void setName(String name) {
              this.name = name;
          }
      }

    ํด๋ž˜์Šค ํŒŒ์ผ์„ ๋””์ปดํŒŒ์ผ ํ–ˆ์„ ๋•Œ, @Getter, @Setter ์–ด๋…ธํ…Œ์ด์…˜์€ ์‚ฌ๋ผ์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์†Œ์Šค์ฝ”๋“œ์— ์ž‘์„ฑํ•˜์ง€ ์•Š์•˜๋˜ getter, setter ๋ฉ”์„œ๋“œ๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

RetentionPolicy.RUNTIME

๋Ÿฐํƒ€์ž„์— ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ณด๋ฅผ ๋ฝ‘์•„ ์“ธ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ๋กœ ์ฆ‰, Reflection API ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ณด๋ฅผ ์•Œ์ˆ˜ ์žˆ๋‹ค. ์Šคํ”„๋ง์—์„œ๋Š” @Controller, @Service, @Autowired, @Component ๋“ฑ์ด ์žˆ๋‹ค.

package org.springframework.stereotype;

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;

/**
 * Indicates that an annotated class is a "Service", originally defined by Domain-Driven
 * Design (Evans, 2003) as "an operation offered as an interface that stands alone in the
 * model, with no encapsulated state."
 *
 * <p>May also indicate that a class is a "Business Service Facade" (in the Core J2EE
 * patterns sense), or something similar. This annotation is a general-purpose stereotype
 * and individual teams may narrow their semantics and use as appropriate.
 *
 * <p>This annotation serves as a specialization of {@link Component @Component},
 * allowing for implementation classes to be autodetected through classpath scanning.
 *
 * @author Juergen Hoeller
 * @since 2.5
 * @see Component
 * @see Repository
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}

ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜๋“ค์€ ์Šคํ”„๋ง์ด ์˜ฌ๋ผ์˜ค๋Š” ์‹คํ–‰ ์ค‘์ธ ์‹œ์ ์— ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์ด ๊ฐ€๋Šฅํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— RUNTIME ์ •์ฑ…์ด ํ•„์š”ํ•œ ๊ฒƒ์ด๋‹ค. ( ์Šคํ”„๋ง๋„ ๋‚ด๋ถ€์ ์œผ๋กœ Reflection ๋“ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋งŒ ๊ฐ€์ ธ์˜ด )

RetentionPolicy.CLASS

๊ทธ๋ ‡๋‹ค๋ฉด, CLASS ์ •์ฑ…์€ ์™œ ํ•„์š”ํ•œ๊ฑธ๊นŒ? class ํŒŒ์ผ๋งŒ ์กด์žฌํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋„ ํƒ€์ž…์ฒด์ปค, IDE ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” CLASS ์ •์ฑ…์ด ํ•„์š”ํ•˜๋‹ค. SOURCE ์ •์ฑ…์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ jar ํŒŒ์ผ์—๋Š” ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ณด๊ฐ€ ๋‚จ์•„์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ˜น์€, ํด๋ž˜์Šค ๋กœ๋”ฉ์‹œ์ ์— ์ถ”๊ฐ€ํ–‰์œ„(?)๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • @NonNull

      package lombok;
    
      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;
    
      @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
      @Retention(RetentionPolicy.CLASS)
      @Documented
      public @interface NonNull {
      }

์ฐธ๊ณ 

Last updated