리플렉션(Reflection)과 어노테이션(Annotation)

Jan 23, 2024
리플렉션(Reflection)과 어노테이션(Annotation)
 
리플렉션(Reflection) 은 실행 중인 프로그램의 클래스, 메서드, 필드 등의 정보를 동적으로 가져오고 조작할 수 있는 기능이다. 리플렉션을 사용하면, 프로그램이 자신의 구조에 대한 정보를 조사하고, 실행 중에 객체의 클래스를 알아내거나, 메소드와 필드에 접근하고, 메소드를 호출하는 것이 가능해진다.
 
리플렉션은 코드 작성 중일 때가 아니라 런타임 시점에 클래스를 가져와서 사용해야 할 때 필요하다.
클래스의 파일 위치나 이름만 있다면 해당 클래스의 정보를 얻어내고, 객체 또한 생성 가능하게 해준다.
 
notion image
 
정원사가 나무를 관리한다. 나무는 정상적인 나무도 있고, 썩어서 보수를 해줘야 하는 나무도 있다.
리플렉션은 모든 나무를 하나하나 관리한다. 그래서 리플렉션을 통한 접근은 느리다는 단점이 있다.
 
 
💡
리플렉션의 장단점
장점 : 구체적인 클래스를 알지 못해도 동적으로 클래스를 만들어 의존 관계를 만들 수 있음.
단점 : 느림. private 데이터도 접근 가능해 캡슐화 어려움. 런타임 단계에서 에러가 발생하기 때문에 디버깅 어려움
 

2. 어노테이션(Annotation)

 
notion image
 
 
리플렉션을 효율적으로 사용하기 위해 어노테이션(Annotation)을 사용한다. 어노테이션은 깃발을 꽂는다고 생각하면 된다. 내가 관리를 원하는 메서드에 깃발을 꽂으면 그 메서드만 조작할 수 있다.
 
RequestMapping rm = method.getDeclaredAnnotation(RequestMapping.class) getDeclaredAnnotation : 주어진 메서드에 선언된 어노테이션 중에서 특정 어노테이션을 찾는 데 사용 RequestMapping : 클라이언트이 요청(url)에 맞는 클래스나 메서드를 연결시켜주는 역할
 
 
public class App { public static void main(String[] args) { String path = "/update"; UserDAO dao = new UserDAO(); UserController con = new UserController(dao); Method[] methods = con.getClass().getDeclaredMethods(); for (Method method : methods) { RequestMapping rm = method.getDeclaredAnnotation(RequestMapping.class);// 이 메서드에 어떤 어노테이션이 있는지 if(rm==null)continue; // user 컨트롤러에서 어노테이션이 없는 것 때문에 오류남. 그래서 널 값으면 무시하고 아래 코드 실행 if(rm.uri().equals(path)){ //외부에서 들어온 path 와 uri 가 같다면 메서드 호출 try { method.invoke(con); // = con.update() 메서드를 리플렉션으로 호출 , con 은 힙이 여러개 일 수 있기 때문에 어떤 힙의 메서드인지 구분하기 위해 넣음. break; //찾으면 끝 } catch (Exception e) { e.printStackTrace(); } } } } }
 
반복문을 통해 RequestMapping 가 표시된 메서드를 rm 에 담는다.
 

3. RequestMapping 클래스 만들기

 
notion image
 
새로운 자바 클래스를 생성한다 타입은 .Annotation 으로 생성한다.
 
notion image
 
 
@Retention(RetentionPolicy.RUNTIME) // 리플렉션을 통해 런타임 시에도 어노테이션 정보를 읽어올 수 있음 @Target(ElementType.METHOD) // 표시된 아래의 메서드만 실행됨 public @interface RequestMapping { String uri(); }
 
 
 

4. UserController @RequestMapping 표시하기

 
@AllArgsConstructor public class UserController { private UserDAO dao ; @RequestMapping(uri="/insert") public void insert(){ System.out.println("controller :insert"); dao.insert("han","1777","01000002222"); } @RequestMapping(uri="/delete") public void delete(){ System.out.println("controller : delete"); dao.delete(5); } @RequestMapping(uri="/update") public void update(){ System.out.println("controller : update"); dao.update("1133","01044445555",6); } }
 
@RequestMapping 를 통해 메서드에 깃발을 단다.
uri 값이 일치하면 @RequestMapping 아래의 메서드가 실행된다.
 
 
notion image
 
 
notion image
 
 
💡
리플렉션 코드를 만들 필요는 없으나, 프레임워크 등에 자주 사용하기 때문에 깃발 꽂는 법은 알아두자.
Share article

{CODE-RYU};