@Inject어노테이션을 만들어 DI 하기
2023. 2. 28. 18:58ㆍ카테고리 없음
1. @Inject 어노테이션을 만들기
package hello.hellospring.di;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
}
2.car 클래스에 carPosition 필드에 @Inject어노테이션 붙이기
package hello.hellospring.di;
public class Car {
public CarName carName;
@Inject
private CarPosition carPosition;
public CarName getCarName() {
return carName;
}
public CarPosition getCarPosition() {
return carPosition;
}
@Override
public String toString() {
return "Car{" +
"carName=" + carName +
", carPosition=" + carPosition +
'}';
}
}
package hello.hellospring.di;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Objects;
public class RefectionEx {
public static <T> T getObject(Class<T> clazz) {
// 해당 클래스 타입의 인스턴스 생성 및 대입
T instance = createInstance(clazz);
// 해당 인스턴스가 가지고 있는 필드를 하나씩 꺼낸다.
Arrays.stream(instance.getClass().getDeclaredFields())
.forEach(field -> {
// 해당 필드에 @Inject 어노테이션이 붙어있는지 확인한다.
if (!Objects.isNull(field.getAnnotation(Inject.class))) {
try {
// private 인 경우를 대비해서 true 로 설정
field.setAccessible(true);
// 위에서 만든 인스턴스 객체의 해당 필드에 필드 인스턴스를 생성해서 대입(set)한다.
field.set(instance, createInstance(field.getType()));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
});
// 인스턴스를 반환한다.
return instance;
}
// 클래스 타입을 받고 해당 클래스 타입의 인스턴스 객체를 생성해서 반환
private static <T> T createInstance(Class<T> clazz) {
try {
return clazz.getConstructor().newInstance();
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
검증
package hello.hellospring.di;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.assertj.core.api.Assertions.*;
class CarTest {
@Test
void reflectionTest(){
Car car = RefectionEx.getObject(Car.class);
System.out.println(car);
assertAll(
() -> assertThat(car).isNotNull(),
() -> assertThat(car.getCarName()).isNull(),
() -> assertThat(car.getCarPosition()).isNotNull()
);
}
}
getObject() 메서드로 인스턴스를 생성 시, 해당 인스턴스와 그 인스턴스의 필드 중 @Inject 어노테이션이 붙은 것까지 인스턴스 주입이 되어야 한다.
[자바, Java] 리플렉션 (Reflection) - 리플렉션의 개념 및 사용법 | Abel’s Development Blog (tjdtls690.github.io)