Arquitectura Central de Inyección de Dependencias
Jerarquía de BeanFactory
El sistema de inyección de Spring se basa en la interfaz BeanFactory y sus implementaciones:
public interface FabricaBeans {
Object obtenerBean(String nombre) throws ExcepcionBeans;
<T> T obtenerBean(String nombre, Class<T> tipoRequerido) throws ExcepcionBeans;
<T> T obtenerBean(Class<T> tipoRequerido) throws ExcepcionBeans;
boolean contieneBean(String nombre);
boolean esSingleton(String nombre) throws NoExisteDefinicionBean;
}
Diseño de Caché de Tres Niveles
Mecanismo para resolver dependencias circulares:
Solución Inteligente para Dependencias Circulares
Escenarios Comunes
Relcaiones de referencia cíclica entre objetos:
A → B → C → A
Mecanismo de Caché Multinivel
| Nivel | Contenido | Propósito |
|---|---|---|
| Caché primaria | Beans singleton completos | Instancias inicializadas |
| Caché secundaria | Beans en estado temprano | Instancias no inicializadas |
| Caché terciaria | Expresiones lambda Factory | Objetos de fábrica para referencias tempranas |
Implementación en Código
public class RegistroSingletonDefault {
private final Map<String, Object> instanciasSingleton = new ConcurrentHashMap<>(256);
private final Map<String, Object> instanciasTempranas = new ConcurrentHashMap<>(16);
private final Map<String, Proveedor<Object>> fabricasSingleton = new HashMap<>(16);
protected void agregarFabrica(String idBean, Proveedor<?> fabrica) {
synchronized (this.instanciasSingleton) {
if (!this.instanciasSingleton.containsKey(idBean)) {
this.fabricasSingleton.put(idBean, fabrica);
this.instanciasTempranas.remove(idBean);
}
}
}
}
Configuración Automatizada Basada en Anotaciones
Anotaciones Clave
| Anotación | Ámbito | Uso |
|---|---|---|
| @Inyectar | Campos, métodos | Inyección por tipo |
| @Calificador | Con @Inyectar | Especificar bean por nombre |
| @Recurso | Campos, métodos | Inyección por nombre (estándar) |
Implementación de Autoconfiguración
public class ProcesadorAnotacionInyeccion implements PostProcesadorBeans {
public ValoresPropiedad procesarPropiedades(
ValoresPropiedad valores, Object bean, String idBean) {
MetadatosInyeccion metadatos = buscarMetadatos(idBean, bean.getClass(), valores);
metadatos.inyectar(bean, idBean, valores);
return valores;
}
}
Configuración Condicional
@Configuracion
public class ConfiguracionBaseDatos {
@Bean
@CondicionalEnPropiedad(nombre = "bd.tipo", valor = "mysql")
public FuenteDatos fuenteMySQL() {
return new FuenteMySQL();
}
}
Patrones Avanzados de Inyección
Inyección Diferida
@Componente
public class ServicioPrincipal {
@Perezoso
@Inyectar
private ServicioAuxiliar servicio;
}
Inyección Basada en Entorno
@Configuracion
public class ConfiguracionPago {
@Bean
@Perfil("produccion")
public ServicioPago servicioReal() {
return new ServicioPagoReal();
}
}
Optimización y Mejores Prácticas
Rendimiento de Métodos de Inyección
| Método | Rendimiento | Caso de Uso |
|---|---|---|
| Constructor | Alto | Dependencias obligatorias |
| Método Setter | Medio | Dependencias opcionales |
Extensión Personalizada
@Destino({ElementType.FIELD})
@Retencion(RetentionPolicy.RUNTIME)
public @interface InyeccionPersonalizada {
String valor() default "";
}
public class ProcesadorInyeccionCustom implements PostProcesadorBeans {
public ValoresPropiedad procesarPropiedades(ValoresPropiedad valores, Object bean, String idBean) {
// Lógica de inyección personalizada
}
}
Refuerzo con Proxy Dinámico
public class ProcesadorRefuerzo implements PostProcesadorInteligente {
public Object postProcesar(Object bean, String idBean) {
if (bean instanceof Reforzable) {
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
new ManejadorRefuerzo(bean)
);
}
return bean;
}
private class ManejadorRefuerzo implements ManejadorInvocacion {
private final Object objetivo;
// Implementación de lógica de refuerzo
}
}