ConfigLoaderDemo.java
package configloader;
import configs.AppConfig;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Path;
import java.util.Scanner;
public class ConfigLoaderDemo {
private static final Path APP_CONFIG_PATH = Path.of("resources/application-config.cfg");
public static void main(String[] args) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
AppConfig appConfig = loadConfig(AppConfig.class, APP_CONFIG_PATH);
System.out.println(appConfig);
}
public static <T> T loadConfig(Class<T> configClass, Path configFilePath) throws IOException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Scanner fileScanner = new Scanner(configFilePath);
Constructor<?> constructor = configClass.getDeclaredConstructor();
constructor.setAccessible(true);
T configInstance = (T) constructor.newInstance();
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine();
String[] keyValue = line.split("=");
if (keyValue.length != 2) {
continue;
}
String fieldName = keyValue[0];
String fieldValue = keyValue[1];
Field field;
try {
field = configClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
System.out.printf("Field %s is not recognized and will be skipped.%n", fieldName);
continue;
}
field.setAccessible(true);
Object parsedValue = parseFieldValue(field.getType(), fieldValue);
field.set(configInstance, parsedValue);
}
return configInstance;
}
private static Object parseFieldValue(Class<?> fieldType, String value) {
if (fieldType.equals(int.class)) {
return Integer.parseInt(value);
} else if (fieldType.equals(short.class)) {
return Short.parseShort(value);
} else if (fieldType.equals(long.class)) {
return Long.parseLong(value);
} else if (fieldType.equals(float.class)) {
return Float.parseFloat(value);
} else if (fieldType.equals(double.class)) {
return Double.parseDouble(value);
} else if (fieldType.equals(String.class)) {
return value;
}
throw new UnsupportedOperationException("Unsupported field type: " + fieldType.getName());
}
}
configs/AppConfig.java
package configs;
public class AppConfig {
private int launchYear;
private String applicationName;
private double subscriptionCost;
public int getLaunchYear() {
return launchYear;
}
public String getApplicationName() {
return applicationName;
}
public double getSubscriptionCost() {
return subscriptionCost;
}
@Override
public String toString() {
return "AppConfig{" +
"launchYear=" + launchYear +
", applicationName='" + applicationName + '\'' +
", subscriptionCost=" + subscriptionCost +
'}';
}
}
1. Class.getDeclaredConstructor()
- 설명: 클래스의 지정된 생성자를 가져옵니다.
- 사용 예:
Constructor<?> constructor = configClass.getDeclaredConstructor(); constructor.setAccessible(true); T configInstance = (T) constructor.newInstance();
- 기본 생성자를 가져와 접근 제한을 해제하고, 새로운 인스턴스를 생성합니다.
- setAccessible(true)를 통해 private 생성자도 사용할 수 있도록 설정합니다.
2. Class.getDeclaredField(String name)
- 설명: 클래스의 지정된 필드를 가져옵니다.
- 사용 예:
Field field = configClass.getDeclaredField(fieldName);
3. Field.setAccessible(true)
- 설명: private 필드에도 접근할 수 있도록 제한을 해제합니다.
- 사용 예:
field.setAccessible(true);
4. Field.set(Object obj, Object value)
- 설명: 특정 객체에서 해당 필드에 값을 설정합니다.
- 사용 예:
field.set(configInstance, parsedValue);
5. Class.getType()
- 설명: 필드의 데이터 타입(Class 객체)을 반환합니다.
- 사용 예:
Object parsedValue = parseFieldValue(field.getType(), fieldValue);
'(2024-10) 스파르타 내일배움캠프 - 백엔드 > Java Reflect' 카테고리의 다른 글
Getter 동적 생성 (0) | 2024.11.27 |
---|---|
필드 제어 예제2) Json Serializer with Array (0) | 2024.11.27 |
Field 제어 (0) | 2024.11.27 |
Java Reflect의 Array 제어 (0) | 2024.11.27 |
Constructor 예제, 싱글턴에서(2) (0) | 2024.11.26 |