1-1. project : container-flash
1-2. project : container-apply
2-1. project : container-flash
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
}
public class FlashContainer {
public static <T> T getObject(Class<T> classType) {
T instance = createInstance(classType); //생성자 방식으로 클래스 타입에 대한 객체 생성
Arrays.stream(classType.getDeclaredFields()).forEach(field -> { //클래스에 정의된 필드들 중, Inject type 어노테이션이 붙어있는 필드 조회
if (field.getAnnotation(Inject.class) != null) {
Object injectedInstance = createInstance(field.getType()); //해당 필드에 대해서 객체를 만들고
field.setAccessible(true); //접근 제어자를 해제해준 뒤,
try {
field.set(instance, injectedInstance); //인스턴스에 해당 필드 타입의 인스턴스를 주입시켜준다.
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
});
return instance;
}
private static <T> T createInstance(Class<T> classType) {
try {
return classType.getConstructor(null).newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class FlashContainerTest {
@Test
void getObject_userRepository() {
UserRepository userRepository = FlashContainer.getObject(UserRepository.class); //reflection 을 반환
assertNotNull(userRepository);
}
@Test
void getObject_userService() {
UserService userService = FlashContainer.getObject(UserService.class);
assertNotNull(userService);
assertNotNull(userService.userRepository);
}
}
public class UserRepository {
}
public class UserService {
@Inject
UserRepository userRepository;
}
//terminal
gradle clean build
2-2. project : container-apply
public class Main {
public static void main(String[] args) {
CustomerService customerService = FlashContainer.getObject(CustomerService.class);
customerService.join();
//customerService:join
//customerRepository:save
}
}
public class CustomerService {
@Inject CustomerRepository customerRepository;
public void join() {
System.out.println("customerService:join");
customerRepository.save();
}
}
public class CustomerRepository {
void save() {
System.out.println("customerRepository:save");
}
}