어노테이션: 1차 개발자가 제작. 깃발 역할+기계가 보는 힌트
1차 개발자가 어노테이션을 설정하는 파일 중 하나입니다.
@Target(ElementType.METHOD) //@target || 클래스 위에는 TYPE || 메서드 위에는 METHOD
@Retention(RetentionPolicy.RUNTIME) //@Retention
public @interface RequestMapping {
String value(); // value는 생략 가능하다. 작성도 가능
}
- @Target 은 어노테이션을 적용할 대상을 설정+지정 합니다.
ElementType 값
.TYPE || 적용 대상: 클래스
.FEILD || 적용 대상: 필드(멤버변수)
.METHOD || 적용 대상: 메서드
.PARAMETER || 적용 대상: 메서드의 매개변수
.CONSTRUCTOR || 적용 대상: 생성자
.LOCAL_VARIABLE || 적용 대상: 지역변수
.ANNOTATION_TYPE || 적용 대상: 다른 어노테이션
.PACKAGE || 적용 대상: 패키지 선언
- @Retention 은 어노테이션이 어떤 시점까지 유지될지 결정해서 메모리와 성능을 최적화 하는 역할입니다.
RetentionPolicy 유형
.SOURCE
컴파일러가 어노테이션을 소스 코드에서만 유지 / 컴파일 단계에서 제거
EX) @Override
.CLASS
바이트코드(.class 파일)까지 유지 / 런타임에는 JVM에 의해 로드되지 않고 사용불가
.RUNTIME
런타임에도 유지 / 리플렉션을 통해 접근 가능
런타임에 특정 동작을 트리거하거나 검증할 때 사용
주로 사용자 정의 어노테이션에 사용됨
- 리플렉션: 기존 코드를 확인하는 행위
코드
어노테이션을 이해하기 위해 간단하게 작성한 코드입니다.
- 1차 개발자가 어노테이션 기능을 만드는 코드
/**
* 1차 개발자 작성하는 코드
*/
----------------------------------------------------------------
@Target(ElementType.METHOD) //@target || 클래스 위에는 type ||
@Retention(RetentionPolicy.RUNTIME) //@Retention
public @interface RequestMapping {
String value(); // value는 생략 가능하다. 작성도 가능
}
-----------------------------------------------------------------
public class Router {
UserController uc;
public Router(UserController uc) {
this.uc = uc;
}
public void routing(String path){
// 1. 메서드 찾아내기
Method[] methods = uc.getClass().getMethods(); // uc에서 생성되는 메서드를 Method[]에 캡슐화 시킨다.
// 2. 어노테이션 체크하기
for (Method m : methods) {
RequestMapping rm = m.getAnnotation(RequestMapping.class);
// 3. value 와 path 일치 확인해서 일치하면 invoke 하기
if(rm == null) break;
if (rm.value().equals(path)){
try {
m.invoke(uc);
} catch (Exception e){
throw new RuntimeException("메서드 실행 중 오류가 발생했어요.");
}
}
}
- 1차 개발자가 만든 코드를 사용하기 위해 / 2차 개발자가 작성하는 코드
/**
* 2차 개발자가 작성하는 코드
*/
public class UserController {
@RequestMapping("/login")
public void login(){
System.out.println("로그인");
}
@RequestMapping("/join")
public void join(){
System.out.println("회원가입");
}
@RequestMapping("/logout")
public void logout(){
System.out.println("로그아웃");
}
@RequestMapping("/userinfo")
public void userinfo(){
System.out.println("유저정보");
}
}
---------------------------------------------------
public class App {
public static void main(String[] args) {
Router router = new Router(new UserController());
Scanner sc = new Scanner(System.in);
String path = sc.nextLine();
router.routing(path);
}
}
실행 클래스 App 을 실행하면 router.routing(path); 메서드가 작동되고
콘솔 창에 UserController의 @RequestMapping 중 하나를 입력하면
mapping 되어있는 메서드의 기능이 실행됩니다.
RequestMapping 을 통해 메서드를 찾아갈 수 있도록
1차 개발자가 만든 @interface RequestMapping 과 Router 클래스를 만들었기 때문입니다.
소감
어노테이션의 일부분이겠지만 작동하는 원리와 함께
1차 개발자가 어떻게 2차 개발자가 만들 메서드를 프로그램이 파악할 수 있게 하여
2차 개발자의 작업을 원활히 할 수 있게 만든 지에 대해서도 알게 되었습니다.
Share article