반응형
나만의 DI 프레임워크 만들기
@Inject 라는 애노테이션 만들어서 필드 주입 해주는 컨테이너 서비스 만들기
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
}
BookService.java
public class BookService {
@Inject
public Object bookRepository;
}
ContainerService.java
public class ContainerService {
public static <T> T getObject (Class<T> classType) {
T instance = createInstance(classType);
Arrays.stream( classType.getDeclaredFields() ).forEach( f -> {
if( f.getAnnotation(Inject.class) != null ) {
Object fieldInstance = createInstance(f.getType());
f.setAccessible(true);
try {
f.set(instance, fieldInstance);
} catch ( IllegalAccessException e) {
e.printStackTrace();
}
}
});
return instance;
}
private static <T> T createInstance (Class<T> classType) {
try {
return classType.getConstructor(null).newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException |SecurityException e) {
e.printStackTrace();
}
return null;
}
}
test
public class ContainerServiceTest {
@Test
public void getObject_BookRepository() {
BookRepository bookRepository = ContainerService.getObject(BookRepository.class);
assertNotNull(bookRepository);
}
@Test
public void getObject_BookService() {
BookService bookService = ContainerService.getObject(BookService.class);
assertNotNull(bookService);
assertNotNull(bookService.bookRepository);
}
}
- classType에 해당하는 타입의 객체를 만들어 준다.
- 단, 해당 객체의 필드 중에 @Inject가 있다면 해당 필드도 같이 만들어 제공한다.
pom.xml
<dependency>
<groupId>me.jueun</groupId>
<artifactId>reflection.di.ex</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
AccountRepository.java
public class AccountRepository {
public void save() {
System.out.println("Repo.save");
}
}
AccountService.java
public class AccountService {
@Inject
AccountRepository accountRepository;
public void join() {
System.out.println("Service.join");
accountRepository.save();
}
}
App.java
public class App {
public static void main( String[] args ) {
AccountService accountService = ContainerService.getObject(AccountService.class);
accountService.join();
}
}
리플렉션 정리
리플렉션 사용시 주의할 것
- 지나친 사용은 성능 이슈를 야기할 수 있다. 반드시 필요한 경우에만 사용할 것
- 컴파일 타임에 확인되지 않고 런타임 시에만 발생하는 문제를 만들 가능성이 있다.
- 접근 지시자를 무시할 수 있다.
스프링
- 의존성 주입
- MVC 뷰에서 넘어온 데이터를 객체에 바인딩 할 때
하이버네이트
- @Entity 클래스에 Setter가 없다면 리플렉션을 사용한다.
JUnit
참고
반응형
'JAVA' 카테고리의 다른 글
[JAVA] try with resources (0) | 2020.11.06 |
---|---|
jar, class 파일 확인하기 (0) | 2019.12.02 |
Reflection (0) | 2019.09.29 |
byte code 조작 (0) | 2019.09.28 |
Byte Code (0) | 2019.09.28 |