Durante la inicialización del contenedor, la ejecución delega la configuración de los interceptores de ciclo de vida a PostProcessorRegistrationDelegate. Este componente se encarga de recuperar todas las definiciones compatibles, clasificarlas según su nivel de prioridad y registrarlas en la fábrica de beans de manera escalonada para garantizar el orden de invocación correcto.
Clasificación y verificación inicial
El proceso comienza extrayendo los identificadores de todos los componentes que implementan BeanPostProcessor. Se establece un contador de referencia que incluye los ya registrados, los pendientes y un componente auxiliar de diagnóstico. Posteriormente, los nombres se distribuyen en tres categorías según implementen PriorityOrdered, Ordered o ninguna interfaz de ordenación.
public static void registrarInterceptoresDeBean(ConfigurableListableBeanFactory fabrica, AbstractApplicationContext contexto) {
String[] nombresCandidatos = fabrica.getBeanNamesForType(BeanPostProcessor.class, true, false);
int objetivoTotal = fabrica.getBeanPostProcessorCount() + 1 + nombresCandidatos.length;
fabrica.addBeanPostProcessor(new BeanPostProcessorChecker(fabrica, objetivoTotal));
List<BeanPostProcessor> altaPrioridad = new ArrayList<>();
List<BeanPostProcessor> internos = new ArrayList<>();
List<String> ordenExplicito = new ArrayList<>();
List<String> sinOrden = new ArrayList<>();
for (String id : nombresCandidatos) {
if (fabrica.isTypeMatch(id, PriorityOrdered.class)) {
BeanPostProcessor instancia = fabrica.getBean(id, BeanPostProcessor.class);
altaPrioridad.add(instancia);
if (instancia instanceof MergedBeanDefinitionPostProcessor) {
internos.add(instancia);
}
} else if (fabrica.isTypeMatch(id, Ordered.class)) {
ordenExplicito.add(id);
} else {
sinOrden.add(id);
}
}
aplicarFasePrioritaria(fabrica, altaPrioridad);
aplicarFaseOrdenada(fabrica, ordenExplicito, internos);
aplicarFaseEstandar(fabrica, sinOrden);
aplicarFaseInterna(fabrica, internos);
fabrica.addBeanPostProcessor(new ApplicationListenerDetector(contexto));
}
Aplicación de reglas de ordenamiento
Cada lote de procesadores se somete a un algoritmo de comparación antes de su inscripción. La fábrica proporciona un comparador específico que, por defecto, recurre a OrderComparator si no se ha configurado una estrategia personalizada de dependencias.
private static void aplicarFasePrioritaria(ConfigurableListableBeanFactory fabrica, List<BeanPostProcessor> grupo) {
ordenarInterceptores(fabrica, grupo);
inscribirBatch(fabrica, grupo);
}
private static void aplicarFaseOrdenada(ConfigurableListableBeanFactory fabrica,
List<String> pendientes,
List<BeanPostProcessor> trackingInternos) {
List<BeanPostProcessor> grupoOrdenado = new ArrayList<>(pendientes.size());
for (String id : pendientes) {
BeanPostProcessor p = fabrica.getBean(id, BeanPostProcessor.class);
grupoOrdenado.add(p);
if (p instanceof MergedBeanDefinitionPostProcessor) {
trackingInternos.add(p);
}
}
ordenarInterceptores(fabrica, grupoOrdenado);
inscribirBatch(fabrica, grupoOrdenado);
}
private static void ordenarInterceptores(ConfigurableListableBeanFactory fabrica, List<?> grupo) {
if (grupo.size() <= 1) return;
Comparator<Object> estrategia = (fabrica instanceof DefaultListableBeanFactory)
? ((DefaultListableBeanFactory) fabrica).getDependencyComparator()
: OrderComparator.INSTANCE;
((List<Object>) grupo).sort(estrategia);
}
Inscripción en la fábrica y componentes especializados
El registro efectivo diferencia entre fábricas de tipo abstracto, que permiten la adición en lote optimizando operaciones sobre listas concurrentes, y otras implementaciones que requieren iteración individual. Los procesadores internos de tipo MergedBeanDefinitionPostProcessor se recopilan durante las fases anteriores para garantizar que su ordenamiento final no genere duplicados, ya que el método de adición elimina instancias previas con la misma firma.
private static void aplicarFaseEstandar(ConfigurableListableBeanFactory fabrica, List<String> ids) {
List<BeanPostProcessor> lote = new ArrayList<>(ids.size());
for (String id : ids) {
lote.add(fabrica.getBean(id, BeanPostProcessor.class));
}
inscribirBatch(fabrica, lote);
}
private static void aplicarFaseInterna(ConfigurableListableBeanFactory fabrica, List<BeanPostProcessor> grupo) {
ordenarInterceptores(fabrica, grupo);
inscribirBatch(fabrica, grupo);
}
private static void inscribirBatch(ConfigurableListableBeanFactory fabrica, List<BeanPostProcessor> procesadores) {
if (fabrica instanceof AbstractBeanFactory) {
((AbstractBeanFactory) fabrica).addBeanPostProcessors(procesadores);
} else {
for (BeanPostProcessor pp : procesadores) {
fabrica.addBeanPostProcessor(pp);
}
}
}