reflection 리플랙션

윤주헌's avatar
Aug 18, 2024
reflection 리플랙션
add sample 체크 빼고 생성
notion image
 
스프링을 하는 사람이 리플랙션을 모른다고??? 잉??? spring기반 기술이 리플랙션이다
  • 여담
강사님은 이래 생각 안함 → 지금은 모르겠지만 잘하는 것 보다 태도가 중요하다(사람 자체가 가지고 있는 습관을 본다) 코딩 테스트로는 사람을 검사할 수 없다. 유형을 공부하고나면 다 비슷 비슷함
하지만 태도는 금방 만들어지지 않는다.

리플랙션이란

💡
반사 반영하다 비추다 이런 뜻이다 → 속을 비추다 라고 기억하자

리플랙션 이해 쉽게 하기 위한 예제

만약 오솔길에 나무를 나둔다, 그리고 청소부가 있는데 오솔길 걸어가는데 썩은 나무가 있으면 수리하면서 가 (명령)→ 가면서 계속 썩었는지 아닌지 전체를 풀 스캔하면서 가야한다. 자기 마음대로 나무 재꿔가며 스캔할 수 없다
 
리플랙션 → 런타임때 하려면
전체가 컴파일러가 분석해서 고칠 수 있는데 이거는 행위다
 
  • 어노테이션
💡
깃발 (실행전에 표시해주는 것) 정확하게 프로그램적으로 보면 !!!!!! JVM이 실행될 때 JVM이 보는 힌트 JVM이 보는 주석!!!!! //는 사용자, 개발자가 보는 힌트 개발자가 보는 주석
어노테이션 붙이는 것은 어렵지 않다
하지만 어려운게 행위 정의를 해줘야 한다
 

예시 이어서

한 나무가 1미터 다른 나무는 3미터로 지정한 나무들이 있다.
 
메서드 안에 2미터 사다리를 주고, 가위질 해라 이러면 찾아가서 수리할 수 없다. 1미터짜리는 할 수 있지만 3미터 나무는 수리할 수 없다.
 
상황이 다른데 어떻게 동일한 동작으로 나무를 수리할 수 있는가가 어렵다 수리는 동일한데 상황이 다르다 관점에 따라 같은 대상이 다르게 보인다
 
관점에 따라 수리하는 관점이 달라서 어렵다 나중에 할거임
 
4가지 배울거임
  1. 리플랙션이 뭔지
  1. 깃발다는 것
  1. 깃발 달고 어떤 행위
  1. 깃발 달고 관점에 따라 다르게
 
  1. 일일이 다 확인한다 런타임()
  1. 코드 실행전에 이 친구는 썩었어, 다른 친구는 썩었어 말해주고 하면 → 표시가 된 것만 청소해라고 하면 표시 된거 체크한다 (원래는 전부 다 하나 하나 찾아봄) 여기서 표시를 어노테이션이라 한다 이 친구가 어노테이션 붙은 애한테 가서 수리를 한다. 하지만 미리 어노테이션 붙이는 수고가 필요하다

1번 설명 (리플랙션이 무엇인가)

패키지 만들기

notion image

클래스 2개 만들거임

ex01에 App, UserController 클래스 만들어 주기
notion image
notion image

내용 삽입

login, join 메서드 넣고 System.out.println(”login 호출됨”) System.out.println(”join 호출됨”) 넣어주기
notion image
app에서 호출하자
  • 라우터를 만든다
notion image
notion image
package ex01; public class App { public static void main(String[] args) { String path = "/login"; UserController uc = new UserController(); //라우터 만듬 if(path.equals("/login")) { uc.login(); } else if (path.equals("/joing")) { uc.join(); } } }
 
 
이제 생각해보자
완전 외부사람과 코드를 한적은 없지?

생각해보자 , 리플랙션 사용 이유

APP을 만드는 개발자A , UserController만드는 개발자B 2명이 있고 서로 엄청 멀리있다
 
A 개발자가 만든 것을 B 개발자가 샀다. 갑자기 B 개발자가 userInfo라는 메서드를 만들고 싶어서 만들었지만 죽어도 실행 안됨
그래서
아 돈주고 샀는데 되는게 없네? → A한테 전화해서 너희 프로그램에 userinfo가 연결이 안돼있다
그래서 A개발자가 만들어줌
notion image
아직은 쉬움 하지만

리플랙션 사용 이유

100개를 팔았는데 각 각 원하는 바가 있어서 프로그램이 안 돌아가서 전화가 온다
이 때는 연락 온 것 전부 다 직접 수정, 보안, 유지보수하기 귀찮다!!
  • 그래서 자동으로 반영시켜주는 것을 해야한다 (자동반영 리플랙션)

ex02만들기 3번

userController 클래스 만들기
notion image
app에서 리프랙션 할거다 →코드 속을 분석함
 
App클래스 만들기
package ex02; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class App { public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { UserController uc = new UserController(); //uc래퍼런스 코드 통해서 분석할 수 있다 System.out.println(uc.getClass()); // uc안에 어떤 메서드 있는지 알려줌 배열타입 Method[] methods = uc.getClass().getDeclaredMethods(); //메서드 전체 실행함 //나무에 깃발이 꼽힌것만 실행할거임 //지금은 깃발 안 꼽아서 다 실행됨 for(Method mt : methods) { System.out.println(mt.getName()); mt.invoke(uc); } //실행시 분석하는 것이 리플랙션이다 //그러면 호출도 할 수 있다 uc.메서드 이름 말고 //리플랙션 하면 mt.invoke } }
 
이름 몰라도 메서드 호출할 수 있다.
notion image

깃발 만들기

notion image
notion image
@Retention
런타임 → JVM실행시 깃발 실행 시 깃발 확인
소스 → 컴파일러 javaC가 확인함 깃발 실행 전에 찾아보는 것
  • 참고하자
 
타겟
💡
어노테이션이 붙을 수 있는 위치 설정 field → 변수
 
Constructor → 빌더 같이 생성자 위에
 
methode → 메서드 위에

깃발 장착

실행 시에 확인한다
RequestMapping 어노테이션 클래스
package ex02; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //깃발 만들기 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping { // 변수 못적음 추상 메서드?? String uri() ; }
 
notion image

리플랙션 완성

 
notion image
리플랙션은 메서드 순서 정할 수 없다 그냥 막 나옴
 
notion image
실행하면 rm는 null이여서 nullpoint 됨
notion image
만약 rm이 null이면 break해라 추가함
 
notion image
결과 →
notion image
package ex02; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class App { public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { String path = "/login" UserController uc = new UserController(); //uc래퍼런스 코드 동해서 분석할 수 있다 System.out.println(uc.getClass()); // uc안에 어떤 메서드 있는지 알려줌 배열타입 Method[] methods = uc.getClass().getDeclaredMethods(); //mt = join join이 rquesetMapping인지 확인 -> null 뜸 // 다시 돌아서 mt= login 하면 나온다 for(Method mt : methods) { Annotation anno = mt.getDeclaredAnnotation(RequestMapping.class); //일반적으로는 Annotation이 부모여서 다운케스팅해서 많이 사용한다 RequestMapping rm = (RequestMapping) anno; if(rm == null)break; if(rm.uri().equals(path)){ mt.invoke(uc); } } } }
notion image
join을 찾아라 이건데 어딘지 지정을 안 해서 못 찾음
 
→ userController 가서
notion image
어노테이션 붙이니까 찾아진다
notion image
 
 

이제 앱 판놈은 할게 없음

다른 사람전화가 온다 → 동작 안된다 하면 requestMapping해서 주소만 붙이면 된다 하면 됨
이해할게 없음 그냥 쓰면 됨
 
notion image
 
notion image
왜 실행이 안됐나 ? 어노테이션 없어서
notion image
notion image
동작됨!!
 

번외

앞에 uri안 적혀 잇는데
value()라는 디폴트가 있다.
value()라고 하면 key 생략 가능하다 원래는 uri = “/주소” 이렇게 쓰는데 바로 “/주소”로 사용 가능하다
values 는 배열이어서 한 개만 넣을 수도 있고 여러 개 넣을 있다. ({”/join”,”/login”})
 
notion image
uri를 value로 바꿀 수 있다.
retentional → 런타입이고 타입은 메서드
 
컴퍼넌트 스켄이 있다 예제 슬랙에 있다. 메모리에 떠서 동작된다!! 해보자
 
Share article

code-sudal