이 글은 "그래서 스프링 어노테이션을 어떻게 인식하길래 어노테이션만으로 동작하는건데?"라는 궁금증을 해결한 글입니다.
"스프링 어노테이션 동작 원리", "스프링 DI 원리" 따위의 검색어로는 스프링에서 어노테이션에 어떻게 기능을 부착하는지 궁금증을 해소할 수 없었는데, 리플렉션을 이용한 방식이었다.
reflection
명사 (거울 등에 비친) 상[모습]
컴파일 시점에는 어떤 타입의 클래스를 사용할지 모르지만, 런타임 시점에 가져와 실행해야 하는 경우 필요하다.
리플렉션을 사용한 예시로는
어노테이션만 붙였을 뿐인데 클래스가 컨트롤러로 인식되고, url 매핑까지 자동(사실 스프링이 함)으로 된다.
등이 있다고 한다.
Dog Class
public class Dog {
public String name = "poppy";
public Dog() {
}
public void run() {
System.out.println(name + "run");
}
}
사용 예시
public class DogMain {
public static void main(String[] args) throws Exception {
Dog dog = new Dog();
Class<Dog> dogClass = Dog.class;
// 클래스 이름 불러오기
System.out.println("클래스명 -> " + dogClass.getName());
// 클래스명 -> reflection.Dog
// 생성자 불러오기
System.out.println("생성자 -> " + dogClass.getDeclaredConstructor());
// 생성자 -> public reflection.Dog()
// 메서드 불러오기
System.out.println("메서드 -> " + dogClass.getDeclaredMethod("run"));
// 메서드 -> public void reflection.Dog.run()
// 변수 불러오기
System.out.println("변수명 -> " + dogClass.getDeclaredField("name"));
// 변수명 -> public java.lang.String reflection.Dog.name
// 변수의 값 불러오기 및 변경하기
Field field = dogClass.getDeclaredField("name");
System.out.println("변수값 -> " + field.get(dog));
// 변수값 -> poppy
field.set(dog, "chulsu");
System.out.println("변수값 변경 -> " + field.get(dog));
// 변수값 변경 -> chulsu
}
}
스프링에서 어노테이션만으로도 수많은 기능이 동작하는 마법이 바로 이 리플렉션을 사용한 것이다.
// 뭘 구현한건진 모르겠지만,,, 스프링의 어떤 클래스 내부의 메서드 중 하나
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
for (Annotation annotation : getAnnotations()) {
if (annotation.annotationType() == annotationClass) {
return (T) annotation;
}
}
return null;
}
// 그냥 인텔리제이에서 shift * 2 한 뒤 찾은 메서드라 의미는 모릅니다...
위 코드와 같이 스프링에서는 리플렉션 객체를 인자로 받아서 엄청난 일을 벌인다. 그 중 일부가 바로 스프링 코드가 존재하는 패키지를 스캔하며 @Component를 찾아 빈을 등록하고, @GetMapping과 같은 어노테이션이 붙은 메서드에 url을 매핑해주는 것이다.
물론 이 이상의 깊은 내용은 아직 내 초식에선 알 수 없지만, 아무튼 아래와 같은 과정을 거칠것이다.
여러 내용을 찾아본 결과 대답은 "No"인듯 하다. 프레임워크나 라이브러리를 만드는 천상계 개발자들은 단점들을 최소화 하며 장점만 극대화 시키고 사용하겠지만, 우리같은 응애들은 쓸 상황도 없을 것이며, 쓰더라도 제대로 못쓸것이기 때문에 다른 방식을 찾아보는게 좋을거같다.
JAVA - 리플렉션 (Reflection)이란?
[Java] 리플렉션 (Reflection)이란 무엇일까? (개념/ 예시)
[10분 테코톡] 파랑, 아키의 리플렉션
꼭 라이브러리나 프레임워크가 아니더라도, 간단하게 API 목록을 뽑아낼 때 활용도가 좋습니다^^ 저는 Reflection으로 Swagger와 유사한 API 테스트를 만들었습니다
형태로 개발했습니다