요구사항
@Inject 라는 애노테이션 만들어서 필드 주입 해주는 컨테이너 서비스 만들기
public class BookService { @Inject BookRepository bookRepository; } |
ContainerService.java
public static <T> T getObject(T classType) |
-
classType에 해당하는 타입의 객체를 만들어 준다.
-
단, 해당 객체의 필드 중에 @Inject가 있다면 해당 필드도 같이 만들어 제공한다.
코드작성
Inject 애노테이션
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
}
주입클래스
public static <T> T getObject(Class<T> classType) {
return null;
}
테스트 클래스 작성
BookRepository 클래스
public class BookRepository {
}
BookRepository를 주입받는 BookService 클래스
public class BookService {
@Inject
BookRepository bookRepository;
}
테스트 클래스
public class ContainerServiceTest {
}
리플렉션을 사용해서 필드에 @Inject 애노테이션이 붙어있을 경우 해당 필드에 대한 인스턴스를 생성해주도록 설계
public static <T> T getObject(Class<T> classType) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
T instance = createInstance(classType);
Arrays.stream(classType.getDeclaredFields()).forEach(field -> {
Inject annotation = field.getAnnotation(Inject.class);
if(annotation != null) {
Object fieldInstance = createInstance(field.getType());
field.setAccessible(true);
try {
field.set(instance, fieldInstance);
} catch (IllegalAccessException e) {
throw new RuntimeException();
}
}
});
return instance;
}
여기에서 field.set(instance, fieldInstance); 부분은
해당 파라미터에 필드의 타입인 BookRepository의 인스턴스를 넣어줌으로서 의존성 주입이 완료된다.
테스트코드
public class ContainerServiceTest {
@Test
public void getObject_BookService() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
BookService bookService = ContainerService.getObject(BookService.class);
assertNotNull(bookService);
assertNotNull(bookService.bookRepository);
}
}
BookService에 대한 인스턴스를 생성하였을때 BookRepository에 대한 인스턴스도 생성되는지 테스트 (by @Inject)
리플렉션 정리
리플렉션 사용시 주의할 것
-
지나친 사용은 성능 이슈를 야기할 수 있다. 반드시 필요한 경우에만 사용할 것
-
컴파일 타임에 확인되지 않고 런타임 시에만 발생하는 문제를 만들 가능성이 있다.
-
접근 지시자를 무시할 수 있다.
스프링
-
의존성 주입
-
MVC 뷰에서 넘어온 데이터를 객체에 바인딩 할 때
하이버네이트
-
@Entity 클래스에 Setter가 없다면 리플렉션을 사용한다.
JUnit
References
'Java > Java' 카테고리의 다른 글
(JAVA) 다이나믹 프록시 (0) | 2019.12.24 |
---|---|
(JAVA) 프록시 패턴 (0) | 2019.12.24 |
(JAVA) 리플렉션 API(3) - 클래스 정보 수정 또는 실행 (0) | 2019.12.23 |
(JAVA) 리플렉션 API(2) - 애노테이션과 리플렉션 (0) | 2019.12.22 |
(JAVA) 리플렉션 API(1) - 클래스 정보 조회 (0) | 2019.12.22 |