Annotation 커스텀해버리기

leverest96·2022년 12월 8일
0

Spring / Java

목록 보기
2/20
post-thumbnail

테스트 코드 작성을 하며 모든 클래스의 상단에 annotation이 반복되는 것을 목격할 수 있었다.

뭐 한두개면 와 다음에도 적자~ 하겠지만 매번 annotation을 5개씩 적어야한다면 끔찍하군.

이를 방지하고자 annotation을 만들어 관리하려고 한다.

물론, Thanks to Igoc. 덕분에 이런걸 알았어.

간단히 예를 들어, Repository test의 경우 아래와 같이 @DataJpaTest와 @AutoConfigureTestDatabase에 관련된 어노테이션이 필요하고 이를 하나의 annotation인 @RepositoryTest 하나로 만들고 싶은 것이다.

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class RepositoryIntegrationTest {

	...

}

------------------------------------

@RepositoryIntegrationTest
class RepositoryIntegrationTest {

	...

}

방법

  1. @interface로 annotation임을 알려준다.

    public @interface Annotation {
    	...
    }
  2. 필요한 annotation을 작성한다.

    @annotation1
    @annotation2
    public @interface Annotation {
     	...
    }
  3. annotation 위에 아래의 annotation 2개를 필수적으로 추가한다.

    • 2개에 대한 설명과 필요시 추가 가능한 annotation은 아래에 기재한다.
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    ------------------------------------
    @annotation1
    @annotation2
    public @interface Annotation {
    	...
    }
    1. @Target : 선언한 annotation이 적용될 수 있는 위치를 결정한다.

      • ElementType Enum에 선언된 값(즉, ElementType.{아래 enum})
        1-1. TYPE : class, interface, enum에 적용
        1-2. FIELD : 클래스 필드 변수
        1-3. METHOD : 메서드
        1-4. PARAMETER : 메서드 인자
        1-5. CONSTRUCTOR : 생성자
        1-6. LOCAL_VARIABLE : 로컬 변수
        1-7. ANNOTATION_TYPE : 어노테이션 타입에만 적용
        1-8. PACKAGE : 패키지
        1-9. TYPE_PARAMETER : 자바8부터 추가된 값으로 제네릭 타입 변수에 적용 (ex. MyClass)
        1-10. TYPE_USE : 자바8부터 추가된 값으로 어떤 타입에도 적용 (ex. extends, implements, 객체 생성시등등)
        1-11. MODULE : 자바9부터 추가된 값으로 모듈에 적용된다.
    2. @Retention : annotation이 어느 레벨까지 유지되는지를 결정짓는다.

      • RetentionPolicy Enum에 선언된 값(즉, RetentionPolicy.{아래 enum})
        2-1. SOURCE : 자바 컴파일에 의해서 annotation은 삭제된다.
        2-2. CLASS : annotation은 .class 파일에 남아 있지만, runtime에는 제공되지 않는 annotation으로 Retention policy의 기본 값이다.
        2-3. RUNTIME : runtime에도 annotation이 제공되어 자바 reflection으로 선언한 annotation에 접근할 수 있다
    3. @Inherited : 자식클래스가 어노테이션을 상속받는다.

    4. @Documented : 해당 annotation이 자바 문서 생성시 자바 문서에도 포함시킨다.

    5. @Repeatable : 반복 선언을 가능하게 만들어준다.



아래는 Igoc의 코드 중 일부를 가져왔다. 헤헤 고마워 :)

1. Application Integration Test

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Import(H2ConsoleProperties.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Transactional
@AutoConfigureMockMvc
public @interface ApplicationIntegrationTest {

	  ...
}

2. Controller Integration Test

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@WebMvcTest
@Import({WebSecurityConfig.class, H2ConsoleProperties.class})
@MockBean(JpaMetamodelMappingContext.class)
public @interface ControllerIntegrationTest {
    String[] properties() default {};

    @AliasFor("controllers")
    Class<?>[] value() default {};

    @AliasFor("value")
    Class<?>[] controllers() default {};

    boolean useDefaultFilters() default true;

    Filter[] includeFilters() default {};

    Filter[] excludeFilters() default {};

    @AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
    Class<?>[] excludeAutoConfiguration() default {};
}

3. Controller / Service Test

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@ExtendWith(MockitoExtension.class)
public @interface ControllerOrServiceTest {
}

4. Repository Test

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
------------------------------------
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public @interface RepositoryIntegrationTest {
}

https://advenoh.tistory.com/21
https://github.com/Devgather/TIARY/pull/57/files#diff-3c58630cceed2b236d7fd5f51b08fa5cd2f146d17ac174b38ac28cbbec92cda7

profile
응애 난 애기 개발자

0개의 댓글