스프링 프레임워크 매핑 원리

호떡·2022년 10월 28일
0

Reflection
Annotation

/*
{/board/writeForm=com.ssafy.annotation6.CtrlAndMethod@2d6a9952,
/member/join=com.ssafy.annotation6.CtrlAndMethod@22a71081, 
/board/delete=com.ssafy.annotation6.CtrlAndMethod@3930015a, 
/login/login=com.ssafy.annotation6.CtrlAndMethod@629f0666, 
/board/list=com.ssafy.annotation6.CtrlAndMethod@1bc6a36e}
호출할 URI 입력 : /board/writeForm
글쓰기 폼용
호출할 URI 입력 : /member/join
join 메서드 실행됨
호출할 URI 입력 : /member/list
등록된 URL이 아닙니다.
호출할 URI 입력 : quit
프로그램이 종료되었습니다.
 */


// 프로젝트에서 요청 URL이 들어오는데
// 내가 작성한 컨트롤러랑 그 요청 URL이랑 매핑시켜주는걸
// 스프링 같은게 하는건데 내가 직접 구현한 것
package com.ssafy.annotation6;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Test {
	private static Map<String, CtrlAndMethod> mappings = new HashMap<>();
	static {
		Class<?>[] clzArr = {
				BoardController.class, 
				MemberController.class,
				LoginController.class
		};
		try {
			for (Class<?> clz : clzArr) {
				// 인스턴스 
				// obj = 컨트롤러를 객체로 만들어. Reflection 방법으로
				Object obj = clz.getDeclaredConstructor().newInstance();
				// 클래스에 선언되어 있는 메서드 얻기
				// 컨트롤러에 선언된 모든 메서드들을 담아 ,arr 에
				Method[] arr = clz.getDeclaredMethods();
				for (Method m : arr) {
					// 메서드에 선언되어 있는 RequestMapping 어노테이션 얻기
					RequestMapping rm = m.getAnnotation(RequestMapping.class);
					// 만약, 메서드에 RequestMapping 선언이 없다면 다음 반복 실행
					if(rm == null) continue;
					
					// 맵의 키를 RequestMapping에 입력된 value 속성 설정
					// 맵의 값으로 메서드를 실행하기 위해 객체와 메서드 참조를 CtrlAndMethod 객체에 입력하여 설
					for(String key : rm.value()) {
						// key : 하나의 RequestMapping 애노테이션에 설정된 요청 URL ("/", "/index")
						// obj : 어떤 컨트롤러?
						// m : 어떤 메서드?
						mappings.put(key, new CtrlAndMethod(obj, m));
					}
				}
			}
		} catch (Exception e) {
			System.out.println("클래스 정보 읽는 중 에러발생");
			e.printStackTrace();
		}
	}
	
	public void execute() {
		for(String key : mappings.keySet()) {
			System.out.println("등록된 URL : "+key);
	    }
//		System.out.println(mappings);
		Scanner sc = new Scanner(System.in);
		try {
			while (true) {  

				System.out.print("호출할 URL 입력 : ");
				// 콘솔에 입력한 url
				String url = sc.nextLine();

				if (url.equals("quit")) break;
				
				// 위에서 매핑해준 거에서 찾아봐
				// 51번줄: mappings.put(key, new CtrlAndMethod(obj, m));
				// 해당 url이랑 매핑된 컨트롤러랑 메서드를 cam 변수에 담아
				CtrlAndMethod cam = mappings.get(url);
				if (cam == null) {
					System.out.println("등록된 URL이 아닙니다.");
					continue;
				}
				
				// cam에 등록되어 잇는 메서드 실행
				// 아래 코드 참조
//              Object obj = clz.getDeclaredConstructor().newInstance();
//              Method method= clz.getDeclaredMethod(val[1]);
//              method.invoke(obj);
				// 메소드를 실행할건데, 어떤 컨트롤러의 메서드? =>invoke(cam.getTarget())
				cam.getMethod().invoke(cam.getTarget());
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}		
		
		System.out.println("프로그램이 종료되었습니다.");
		sc.close();
	}
	
	public static void main(String[] args) {
		try {
			Test t = new Test();
			t.execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

0개의 댓글