[Spring Security] 0. Reflection

김주희's avatar
Jul 24, 2025
[Spring Security] 0. Reflection
프로젝트 생성
notion image
우리의 목적은 App 파일을 건드리지 않는 것
지금 상황은 B = 나인데 내가 개발하고 싶은게 있을때마다 A한테 전화해서 추가해달라고 해야하고 App 파일에는 if문이 겁나 늘어난다는거다.
notion image
notion image
 

reflection으로 찾기

package ex02; import java.lang.reflect.Method; import java.lang.reflect.Parameter; // A 개발자가 만든 것 public class App { public static void main(String[] args) { String path = "/login"; Method[] methods = UserController.class.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName()); if (method.getName().equals("login")) { int paramCount = method.getParameterCount(); System.out.println(paramCount); Parameter[] params = method.getParameters(); for (Parameter param : params) { System.out.println(param.getName()); System.out.println(param.getType()); } // System.out.println("-------------------------"); // Class<?>[] classes = method.getParameterTypes(); // for (int i = 0; i < classes.length; i++) { // Class<?> cls = classes[i]; // System.out.println(cls.getTypeName()); // } } } } }
package ex02; // B 개발자가 만든 것 public class UserController { public void login(int n1, String n2) { System.out.println("login 호출됨"); } public void join() { System.out.println("join 호출됨"); } public void logout() { System.out.println("logout 호출됨"); } }
notion image
 

App 입장에서 UserController를 분석해야됨
notion image
 
 
invoke = 메서드를 부르다는 뜻
invoke할때 매개변수로 heap에 뜬 객체를 넣어줘야 됨
UserController를 메모리에 띄우지 않았으니까 걔를 먼저 new해서 넣어줘야 됨
 

과제

for문 돌아서 매개변수 개수 분석해서 개수에 따라서 동작하도록 UserController에서 login 메서드의 매개변수로 Model을 받고있는데 login 호출할때 getinstance로 넣어서 login 실행했을때 ssar이 나오면 됨 userinfo에서 getInstance로 적혀잇으면 넣어주고 principle anno가 붙어있으면 session.instance 해서 주입하고 메서드 찾고 메서드에 매개변수 있는지 확인하고 어노테이션 붙어있으면 SessionUser이고 어노테이션 안붙어있으면 Model이고
 
 
 
 
Annotation[][] annotations = method.getParameterAnnotations();
 
notion image

1차 - invoke를 너무 자주 호출함ㅠ

package ex03; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.Scanner; // A 개발자가 만든 것 public class App { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String path = sc.nextLine(); Method[] methods = UserController.class.getDeclaredMethods(); UserController uc = new UserController(); for (Method method : methods) { Annotation anno = method.getDeclaredAnnotation(RequestMapping.class); RequestMapping rm = (RequestMapping) anno; // 1. 메서드 찾기 if (rm.value().equals(path)) { // 2. 메서드의 파라미터 여부 확인 if (method.getParameterCount() != 0) { // 파라미터가 있는 경우 Parameter[] parameters = method.getParameters(); for (Parameter parameter : parameters) { if (parameter.isAnnotationPresent(Principle.class)) { try { method.invoke(uc, SessionUser.getInstance()); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } else { try { method.invoke(uc, Model.getInstance()); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } } else { // 파라미터가 없는 경우 try { method.invoke(uc); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } } } }
 

2차 - invoke 한번만 시도

package ex03; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.Scanner; public class App { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String path = sc.nextLine(); Method[] methods = UserController.class.getDeclaredMethods(); UserController uc = new UserController(); for (Method method : methods) { RequestMapping rm = method.getDeclaredAnnotation(RequestMapping.class); if (rm == null || !rm.value().equals(path)) continue; // 파라미터 수만큼 인자 배열 준비 Object[] argsForInvoke = new Object[method.getParameterCount()]; Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { Parameter param = parameters[i]; if (param.isAnnotationPresent(Principle.class)) { argsForInvoke[i] = SessionUser.getInstance(); } else { argsForInvoke[i] = Model.getInstance(); } } try { method.invoke(uc, argsForInvoke); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } } }
 
Share article

jay0628