10. reflection
10. reflection
Reflection(23. 11. 30)
reflection을 이용한 객체 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
try {
Class userClass = Class.forName(User.class.getName());
Constructor<?> constructor = userClass.getConstructor();
User user = (User) constructor.newInstance();
System.out.println(user);
} catch (ClassNotFoundException | NoSuchMethodException e){
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
Class.forName(className)
- 물리적인 클래스 파일명을 인자로 넘겨주면 이에 해당하는 클래스를 반환합니다.
Class.getConstructor()
- public 접근자를 가진 생성자를 반환합니다.
Class.forName(User.class.getName()).getConstructor(String.class ,Integer.TYPE);
이런식으로 타입을 지정 할 수 도있다.
getDeclaredMethod
- method를 복사하는 기능
getter
를 복하- ``Method setUserNameMethod =clazz.getDeclaredMethod(“setUserName”,String.class);`
- private 도 접근이 가능할까? →
userAgeField.setAccessible(true);
로 가능!
의존성 주입
- 의존성 주입을 위한
@Autowired annotation
를 이용한다. UserRepository.java
1 2 3 4 5 6 7 8 9 10 11
public class UserRepository { private List<User> users = new ArrayList<>(); public User findByName(String userName){ return users.stream() .filter(o->o.getUserName().equals(userName)).findFirst().orElse(null); } public void save(User user){ this.users.add(user); } }
UserService.java
1 2 3 4 5 6 7 8 9 10 11
public class UserService { @Autowired private UserRepository userRepository; public User getUser(String userName){ return userRepository.findByName(userName); } public void addUser(User user){ userRepository.save(user); }
InjectUtil
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
public final class InjectUtil { public static <T> T getObject(Class<T> classType){ T instance = createInstance(classType); Field[] fields = classType.getDeclaredFields(); for(Field field : fields){ if (field.getAnnotation(Autowired.class) != null) { Object fieldInstance = createInstance(field.getType()); field.setAccessible(true); try { field.set(instance, fieldInstance); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } } return instance; } private static <T> T createInstance(Class<T> classType) { try { return classType.getConstructor(null).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; }
UserService
에UserRepository
를 자동으로 주입해주는 classUserService
의 Reflection API를 이용해 모든 Fields를 조회 Field[] 배열로 반환- 배열 순회하면서
@Autosired annotaion
이 있는 field를 조회createInstance()
를 통해 객체 생성 - 객체의 생성을 프로그램에 의해서 컨트롤 → InjectUtil이 객체 의존성을 제어한다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.