![[Spring Security] 0. Reflection](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog%3Ftitle%3D%255BSpring%2520Security%255D%25200.%2520Reflection%26logoUrl%3Dhttps%253A%252F%252Finblog.ai%252Finblog_logo.png%26blogTitle%3Djay0628&w=2048&q=75)
프로젝트 생성

우리의 목적은 App 파일을 건드리지 않는 것
지금 상황은 B = 나인데 내가 개발하고 싶은게 있을때마다 A한테 전화해서 추가해달라고 해야하고 App 파일에는 if문이 겁나 늘어난다는거다.


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 호출됨");
}
}

App 입장에서 UserController를 분석해야됨

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();

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