스프링 공부를 하다가 다음과 같은 의문이 들었다
아래와 같은 인터페이스와
package com.spring.basic.core.member;
public interface MemberRepository {
void save(Member member);
Member findById(Long memberId);
}
아래와 같은 구현체가 있을 때
@Repository
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
@Override
public void save(Member member) {
store.put(member.getId(), member);
}
@Override
public Member findById(Long memberId) {
return store.get(memberId);
}
}
이 구현체가 빈으로 등록되고 나서 어떻게 MemberRepository 타입으로 조회되는지 의문이 생겼다.
MemoryMemberRepository타입으로 조회는 당연히 클래스 이름이 타입이므로 해당 타입을 빈에 등록하는건 자연스러웠지만
어떻게 인터페이스 타입을 빈에 등록하는지가 잘 상상이 가지 않았다.
이 의문을 풀어준게 이 시리즈에서 다루고 있는 리플렉션이다.
Class.getName() : 해당 클래스의 이름을 반환
Class.getInterfaces(): 해당 클래스의 인터페이스(들)를 반환
아래 코드와 실행 결과를 통해 쉽게 이해할 수 있다.
@Test
void registBean() {
Class<?> clazz = MemoryMemberRepository.class;
String name = clazz.getName();
System.out.println("name = " + name);
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> anInterface : interfaces) {
System.out.println("interface = " + anInterface);
}
}
이것을 실행해보면 아래와 같이 출력된다.
자 이제 어떻게 해당 클래스의 인터페이스 타입도 스프링빈으로 등록되는지 감을 잡을 수 있다.
getName() 을 통해서 자기 자신타입을 빈에 등록하고, getInterfaces()를 통해서 인터페이스 타입까지 등록하는 것이었다.
아래의 표현을 Map 즉 key와 value라고 생각해보자
(getName() -> memoryMemberRepository) , (getInterfaces() -> memoryMemberRepository)
이런식으로 등록하면 결국에
getBean(MemberRepository.class) 와 getBean(MemoryMemberRepository.class)두 개의 타입으로 모두 memoryMemberRepository를 반환 받을 수 있을 것이다.
이 시리즈는 여기서 마무리 하겠다.