Repository navigation
Expand file tree
/
Copy pathExpConfig.java
More file actions
105 lines (88 loc) · 4 KB
/
Copy pathExpConfig.java
File metadata and controls
105 lines (88 loc) · 4 KB
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
// En Spring Boot, @Value y @ConfigurationProperties leen propiedades del entorno.
// Aquí se replica la misma lógica con java.util.Properties y un PropertyResolver propio.
public class ExpConfig {
// Equivalente a @ConfigurationProperties(prefix = "app")
// Agrupa propiedades relacionadas bajo un mismo prefijo
static class AppConfig {
final String nombre;
final int timeout;
final int reintentos;
AppConfig(String nombre, int timeout, int reintentos) {
this.nombre = nombre;
this.timeout = timeout;
this.reintentos = reintentos;
}
}
// Resuelve propiedades con soporte de default — equivalente al mecanismo de @Value
static class PropertyResolver {
private final Properties props;
PropertyResolver(Map<String, String> source) {
this.props = new Properties();
this.props.putAll(source);
}
// Equivalente a @Value("${key}") — lanza si no existe
String require(String key) {
String val = props.getProperty(key);
if (val == null) throw new IllegalStateException("Propiedad requerida no encontrada: " + key);
return val;
}
// Equivalente a @Value("${key:default}") — usa defaultValue si no existe
String get(String key, String defaultValue) {
return props.getProperty(key, defaultValue);
}
int getInt(String key, int defaultValue) {
String val = props.getProperty(key);
return val != null ? Integer.parseInt(val) : defaultValue;
}
}
// Simula el contenedor / fábrica de beans equivalente a @Configuration + @Bean
static class AppContext {
private final PropertyResolver env;
private final Map<Class<?>, Object> beans = new HashMap<>();
AppContext(Map<String, String> properties) {
this.env = new PropertyResolver(properties);
}
void refresh() {
// Equivalente al método @Bean que lee @Value("${...}")
// @Value("${app.nombre}") → require("app.nombre")
// @Value("${app.timeout:30}") → getInt("app.timeout", 30)
// @Value("${app.reintentos:3}") → getInt("app.reintentos", 3)
AppConfig config = new AppConfig(
env.require("app.nombre"),
env.getInt("app.timeout", 30),
env.getInt("app.reintentos", 3)
);
beans.put(AppConfig.class, config);
}
@SuppressWarnings("unchecked")
<T> T getBean(Class<T> type) {
Object bean = beans.get(type);
if (bean == null) throw new IllegalStateException("Bean no encontrado: " + type.getSimpleName());
return (T) bean;
}
PropertyResolver getEnvironment() {
return env;
}
}
public static void main(String[] args) {
// Simula application.properties cargado en el contexto.
// En Spring Boot esto lo hace automáticamente al arrancar.
Map<String, String> applicationProperties = new HashMap<>();
applicationProperties.put("app.nombre", "java-prep");
applicationProperties.put("app.timeout", "45");
// app.reintentos no definida → usará el default 3
AppContext ctx = new AppContext(applicationProperties);
ctx.refresh();
AppConfig config = ctx.getBean(AppConfig.class);
System.out.println("Nombre: " + config.nombre);
System.out.println("Timeout: " + config.timeout + "s");
System.out.println("Reintentos: " + config.reintentos); // 3 (default)
// Acceso directo al Environment — útil para leer propiedades de forma programática
PropertyResolver env = ctx.getEnvironment();
System.out.println("Via env: " + env.require("app.nombre"));
System.out.println("Missing: " + env.get("app.debug", "false"));
}
}