리플렉션과 애너테이션

김민지·2022년 10월 20일
0

자바

목록 보기
9/21

스프링의 의존성 주입 어떻게 동작하는지 알아보자

  • 어떻게 스프링은 어노테이션만으로 자동으로 의존성을 주입해줄 수 있는걸까?
  • 어떻게 저 변수값들이 null이 아닌걸까?

리플렉션

  • 리플렉션은 힙 영역에 로드된 Class 타입의 객체를 통해, 원하는 클래스의 인스턴스를 생성할 수 있도록 지원하고, 인스턴스의 필드와 메소드를 접근 제어자와 상관 없이 사용할 수 있도록 지원하는 API이다.
    여기서 로드된 클래스라고 함은, JVM의 클래스 로더에서 클래스 파일에 대한 로딩을 완료한 후, 해당 클래스의 정보를 담은 Class 타입의 객체를 생성하여 메모리의 힙 영역에 저장해 둔 것을 의미한다. new 키워드를 통해 만드는 객체와는 다른 것임을 유의하자

  • 자바는 컴파일시점에 타입을 결정하는 정적인언어야
    컴파일시점에 그 타입에 대한 정보를 다 알고있어야해.
    근데 object obj = new Car(); 와 같이 선언하고 obj에 대해 접근하면 컴파일에러가 나
    컴파일 시점에 그 타입에 대한 정보를 다 알고 있지 않아서. obj는 object에 대한 변수, 메서드만 갖고있어서
    오류가 나
    근데 리플렉션을 사용하면 저상황에서도, 즉, 구체적인 타입은 몰라도 car클래스의 변수나 메서드에 접근할 수 있어
    class파일을 가지고 분석해서 얻어내거든

annotation

  • 애너테이션은 기본적으로 런타임에서 다음 세가지중 하나의 라이프 사이클을 갖는다
    RetentionPolicy.SOURCE : 소스 코드(.java)까지 남아있는다.(default)
    RetentionPolicy.CLASS : 클래스 파일(.class)까지 남아있는다.(=바이트 코드)
    RetentionPolicy.RUNTIME : 런타임까지 남아있는다.(=사실상 안 사라진다.)
  • 그래서 소스코드를 실행시키고 어떤 클래스에 대해 annotation을 출력하려고 하면 아무것도 안뜬다 왜냐하면 컴파일 이후(바이트코드가되면)에는 사라지기 때문이다.
  • annotation은 해당 폴더 이하에만 적용가능하도록 할수도있고, 필드에게만 붙이도록 설정할수도있다
  • Inherit 어노테이션을 추가해주면 이 어노테이션이 붙은 어노테이션은 상속이 가능하다. 예를들어 book이라는 클래스에 어노테이션이 붙어있다. 그런데 이 book을 상속받은 mybook도 book을 상속받았기 때문에 book의 어노테이션 중, 상속이 가능한 어노테이션을 상속받는다.

DI container 만들기

test코드에 BookService, BookRepository를 만들고 자바폴더쪽의 코드에는 ContainerService를 만든다
ContainerService : class객체를 받아서 그 객체의 타입을 return
BookService, BookRepository: 예제 클래스들 service쪽에서 Inject어노테이션을 사용해 BookRepository를 주입받는다

ContainerService로 class객체를 넘겨준다
넘어온 클래스 객체의 필드 중 Inject어노테이션이 붙은 필드가 있는지 검사한다
만약 있다면 해당 필드에 대한 instance를 만든다음에 필드에 setting해준다
그리고 setting까지 완료해준 class객체에 대한 인스턴스를 return한다

DI container 외부에서 사용하기

  • 내가 만든 프로젝트를 mvn install한다 그러면 ~~.jar파일이 생성되는데 이 위치를 기억했다가 pom.xml파일의 dependency에 적어준다. 그러면 내가 만들어놨던 어노테이션이나 서비스를 사용할수있게 된다.

https://github.com/Flre-fly/theJavaReflection.git


출처
https://steady-coding.tistory.com/609
https://tecoble.techcourse.co.kr/post/2020-07-16-reflection-api/ < 여기 좋다

profile
안녕하세요!

0개의 댓글