본문 바로가기

JAVA

Reflection

반응형

https://asfirstalways.tistory.com/221

 

스프링의 Depedency Injection은 어떻게 동작할까?

 

BookService.java

@Service
public class BookService {

    @Autowired
    BookRepository bookRepository;
}

bookRepository 인스턴스는 어떻게 null이 아닌걸까?

스프링은 어떻게 BookService 인스턴스에 BookRepository 인스턴스를 넣어준 것일까?

 


리플렉션 API 1

클래스 정보 조회

리플렉션의 시작은 Class<T>

Class<T>에 접근하는 방법

  • 모든 클래스를 로딩 한 다음 Class<T>의 인스턴스가 생긴다. “타입.class”로 접근할 수 있다.
  • 모든 인스턴스는 getClass() 메소드를 가지고 있다. “인스턴스.getClass()”로 접근할 수 있다.
  • 클래스를 문자열로 읽어오는 방법
    - Class.forName(“FQCN”)
    - 클래스패스에 해당 클래스가 없다면 ClassNotFoundException이 발생한다.

 

Class<T>를 통해 할 수 있는 것

  • 필드 (목록) 가져오기
  • 메소드 (목록) 가져오기
  • 상위 클래스 가져오기
  • 인터페이스 (목록) 가져오기
  • 애노테이션 가져오기
  • 생성자 가져오기
  • ...

애노테이션과 리플렉션

 

중요 애노테이션

  • @Retention: 해당 애노테이션을 언제까지 유지할 것인가? 소스, 클래스(default), 런타임
  • @Inherit: 해당 애노테이션을 하위 클래스까지 전달할 것인가?
  • @Target: 어디에 사용할 수 있는가?
javap -c -v .class

리플렉션

  • getAnnotations(): 상속받은 (@Inherit) 애노테이션까지 조회
  • getDeclaredAnnotations(): 자기 자신에만 붙어있는 애노테이션 조회

리플렉션 API 1부: 클래스 정보 수정 또는 실행

 

Class 인스턴스 만들기

  • Class.newInstance()는 deprecated 됐으며 이제부터는
  • 생성자를 통해서 만들어야 한다.

생성자로 인스턴스 만들기

  • Constructor.newInstance(params)

필드 값 접근하기/설정하기

  • 특정 인스턴스가 가지고 있는 값을 가져오는 것이기 때문에 인스턴스가 필요하다.
  • Field.get(object)
  • Filed.set(object, value)
  • Static 필드를 가져올 때는 object가 없어도 되니까 null을 넘기면 된다.

 

메소드 실행하기

  • Object Method.invoke(object, params)
public class App {
	
    public static void main( String[] args ) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {

    	Class<?> bookClass = Class.forName("me.jueun.reflection.ex.Book");
    	Constructor<?> constructor = bookClass.getConstructor(null);
    	Book book_1 = (Book) constructor.newInstance();
    	System.out.println(book_1);
    	
    	Constructor<?> constructor_string = bookClass.getConstructor(String.class);
    	Book book_2 = (Book) constructor_string.newInstance("jueun");   
    	System.out.println(book_2);
    	
    	Field a = Book.class.getDeclaredField("A");
    	a.get(null); // 모든 인스턴스가 공유하는 static 변수니까
    	a.set(null, "AAAAA");
    	System.out.println(a.get(null));
    	

    	Field b = Book.class.getDeclaredField("B");
    	b.setAccessible(true);
    	b.get(book_1); // 모든 인스턴스가 공유하는 static 변수니까
    	b.set(book_1, "BBBBB");
    	System.out.println(b.get(book_1));
    	
    	Method c = Book.class.getDeclaredMethod("c");
    	c.setAccessible(true);
    	c.invoke(book_1);
 
    	
    	Method d = Book.class.getDeclaredMethod("d", int.class, int.class);
    	System.out.println( d.invoke(book_1, 1, 2) );
    	
    }
}
반응형

'JAVA' 카테고리의 다른 글

jar, class 파일 확인하기  (0) 2019.12.02
make DI Framework by reflection  (0) 2019.09.29
byte code 조작  (0) 2019.09.28
Byte Code  (0) 2019.09.28
Class Loader  (0) 2019.09.28