• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TAKETODAY / today-infrastructure / 16688256371

02 Aug 2025 01:13AM UTC coverage: 81.778% (-0.006%) from 81.784%
16688256371

push

github

TAKETODAY
:white_check_mark:

59512 of 77725 branches covered (76.57%)

Branch coverage included in aggregate %.

140809 of 167233 relevant lines covered (84.2%)

3.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.88
today-context/src/main/java/infra/context/support/PostProcessorRegistrationDelegate.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.context.support;
19

20
import java.util.ArrayList;
21
import java.util.Collection;
22
import java.util.Comparator;
23
import java.util.HashSet;
24
import java.util.LinkedHashSet;
25
import java.util.List;
26
import java.util.Set;
27
import java.util.function.BiConsumer;
28

29
import infra.beans.PropertyValue;
30
import infra.beans.factory.InitializationBeanPostProcessor;
31
import infra.beans.factory.config.BeanDefinition;
32
import infra.beans.factory.config.BeanDefinitionHolder;
33
import infra.beans.factory.config.BeanFactoryPostProcessor;
34
import infra.beans.factory.config.BeanPostProcessor;
35
import infra.beans.factory.config.ConfigurableBeanFactory;
36
import infra.beans.factory.config.ConstructorArgumentValues.ValueHolder;
37
import infra.beans.factory.config.TypedStringValue;
38
import infra.beans.factory.support.AbstractBeanDefinition;
39
import infra.beans.factory.support.AbstractBeanFactory;
40
import infra.beans.factory.support.BeanDefinitionRegistry;
41
import infra.beans.factory.support.BeanDefinitionRegistryPostProcessor;
42
import infra.beans.factory.support.BeanDefinitionValueResolver;
43
import infra.beans.factory.support.MergedBeanDefinitionPostProcessor;
44
import infra.beans.factory.support.RootBeanDefinition;
45
import infra.beans.factory.support.StandardBeanFactory;
46
import infra.core.OrderComparator;
47
import infra.core.Ordered;
48
import infra.core.PriorityOrdered;
49
import infra.lang.Nullable;
50
import infra.logging.Logger;
51
import infra.logging.LoggerFactory;
52

53
/**
54
 * Delegate for AbstractApplicationContext's post-processor handling.
55
 *
56
 * @author Juergen Hoeller
57
 * @author Sam Brannen
58
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
59
 * @since 4.0 2021/12/8 14:59
60
 */
61
final class PostProcessorRegistrationDelegate {
62

63
  private PostProcessorRegistrationDelegate() {
64
  }
65

66
  public static void invokeBeanFactoryPostProcessors(
67
          ConfigurableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
68

69
    // WARNING: Although it may appear that the body of this method can be easily
70
    // refactored to avoid the use of multiple loops and multiple lists, the use
71
    // of multiple lists and multiple passes over the names of processors is
72
    // intentional. We must ensure that we honor the contracts for PriorityOrdered
73
    // and Ordered processors. Specifically, we must NOT cause processors to be
74
    // instantiated (via getBean() invocations) or registered in the ApplicationContext
75
    // in the wrong order.
76

77
    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
78
    HashSet<String> processedBeans = new HashSet<>();
4✔
79

80
    if (beanFactory instanceof BeanDefinitionRegistry registry) {
6!
81
      ArrayList<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
4✔
82
      ArrayList<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
4✔
83

84
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
10✔
85
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
6✔
86
          registryProcessor.postProcessBeanDefinitionRegistry(registry);
3✔
87
          registryProcessors.add(registryProcessor);
5✔
88
        }
89
        else {
90
          regularPostProcessors.add(postProcessor);
4✔
91
        }
92
      }
1✔
93

94
      // Do not initialize FactoryBeans here: We need to leave all regular beans
95
      // uninitialized to let the bean factory post-processors apply to them!
96
      // Separate between BeanDefinitionRegistryPostProcessors that implement
97
      // PriorityOrdered, Ordered, and the rest.
98
      ArrayList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
4✔
99

100
      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
101
      var postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
6✔
102
      for (String ppName : postProcessorNames) {
16✔
103
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
5✔
104
          currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
8✔
105
          processedBeans.add(ppName);
4✔
106
        }
107
      }
108
      sortPostProcessors(currentRegistryProcessors, beanFactory);
3✔
109
      registryProcessors.addAll(currentRegistryProcessors);
4✔
110
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
3✔
111
      currentRegistryProcessors.clear();
2✔
112

113
      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
114
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
6✔
115
      for (String ppName : postProcessorNames) {
16✔
116
        if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
9✔
117
          currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
8✔
118
          processedBeans.add(ppName);
4✔
119
        }
120
      }
121
      sortPostProcessors(currentRegistryProcessors, beanFactory);
3✔
122
      registryProcessors.addAll(currentRegistryProcessors);
4✔
123
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
3✔
124
      currentRegistryProcessors.clear();
2✔
125

126
      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
127
      boolean reiterate = true;
2✔
128
      while (reiterate) {
2✔
129
        reiterate = false;
2✔
130
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
6✔
131
        for (String ppName : postProcessorNames) {
16✔
132
          if (!processedBeans.contains(ppName)) {
4✔
133
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
8✔
134
            processedBeans.add(ppName);
4✔
135
            reiterate = true;
2✔
136
          }
137
        }
138
        sortPostProcessors(currentRegistryProcessors, beanFactory);
3✔
139
        registryProcessors.addAll(currentRegistryProcessors);
4✔
140
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
3✔
141
        currentRegistryProcessors.clear();
3✔
142
      }
143

144
      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
145
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
3✔
146
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
3✔
147
    }
1✔
148

149
    else {
150
      // Invoke factory processors registered with the context instance.
151
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
×
152
    }
153

154
    // Do not initialize FactoryBeans here: We need to leave all regular beans
155
    // uninitialized to let the bean factory post-processors apply to them!
156
    var postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
6✔
157

158
    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
159
    // Ordered, and the rest.
160
    ArrayList<String> orderedPostProcessorNames = new ArrayList<>();
4✔
161
    ArrayList<String> nonOrderedPostProcessorNames = new ArrayList<>();
4✔
162
    ArrayList<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
4✔
163
    for (String ppName : postProcessorNames) {
16✔
164
      if (processedBeans.contains(ppName)) {
5✔
165
        // skip - already processed in first phase above
166
      }
167
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
5✔
168
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
9✔
169
      }
170
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
5✔
171
        orderedPostProcessorNames.add(ppName);
5✔
172
      }
173
      else {
174
        nonOrderedPostProcessorNames.add(ppName);
4✔
175
      }
176
    }
177

178
    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
179
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
3✔
180
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
3✔
181

182
    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
183
    ArrayList<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
6✔
184
    for (String postProcessorName : orderedPostProcessorNames) {
10✔
185
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
8✔
186
    }
1✔
187
    sortPostProcessors(orderedPostProcessors, beanFactory);
3✔
188
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
3✔
189

190
    // Finally, invoke all other BeanFactoryPostProcessors.
191
    ArrayList<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
6✔
192
    for (String postProcessorName : nonOrderedPostProcessorNames) {
10✔
193
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
8✔
194
    }
1✔
195
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
3✔
196

197
    // Clear cached merged bean definitions since the post-processors might have
198
    // modified the original metadata, e.g. replacing placeholders in values...
199
    beanFactory.clearMetadataCache();
2✔
200
  }
1✔
201

202
  public static void registerBeanPostProcessors(
203
          ConfigurableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
204

205
    // WARNING: Although it may appear that the body of this method can be easily
206
    // refactored to avoid the use of multiple loops and multiple lists, the use
207
    // of multiple lists and multiple passes over the names of processors is
208
    // intentional. We must ensure that we honor the contracts for PriorityOrdered
209
    // and Ordered processors. Specifically, we must NOT cause processors to be
210
    // instantiated (via getBean() invocations) or registered in the ApplicationContext
211
    // in the wrong order.
212

213
    var postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
6✔
214

215
    // Register BeanPostProcessorChecker that logs an info message when
216
    // a bean is created during BeanPostProcessor instantiation, i.e. when
217
    // a bean is not eligible for getting processed by all BeanPostProcessors.
218
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
8✔
219
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(
8✔
220
            beanFactory, postProcessorNames, beanProcessorTargetCount));
221

222
    // Separate between BeanPostProcessors that implement PriorityOrdered,
223
    // Ordered, and the rest.
224
    ArrayList<String> orderedPostProcessorNames = new ArrayList<>();
4✔
225
    ArrayList<String> nonOrderedPostProcessorNames = new ArrayList<>();
4✔
226
    ArrayList<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
4✔
227
    ArrayList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
4✔
228
    for (String ppName : postProcessorNames) {
16✔
229
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
5✔
230
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
6✔
231
        priorityOrderedPostProcessors.add(pp);
4✔
232
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
3✔
233
          internalPostProcessors.add(pp);
4✔
234
        }
235
      }
1✔
236
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
5✔
237
        orderedPostProcessorNames.add(ppName);
5✔
238
      }
239
      else {
240
        nonOrderedPostProcessorNames.add(ppName);
4✔
241
      }
242
    }
243

244
    // First, register the BeanPostProcessors that implement PriorityOrdered.
245
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
3✔
246
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
3✔
247

248
    // Next, register the BeanPostProcessors that implement Ordered.
249
    ArrayList<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
6✔
250
    for (String ppName : orderedPostProcessorNames) {
10✔
251
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
6✔
252
      orderedPostProcessors.add(pp);
4✔
253
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
3✔
254
        internalPostProcessors.add(pp);
4✔
255
      }
256
    }
1✔
257
    sortPostProcessors(orderedPostProcessors, beanFactory);
3✔
258
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);
3✔
259

260
    // Now, register all regular BeanPostProcessors.
261
    ArrayList<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
6✔
262
    for (String ppName : nonOrderedPostProcessorNames) {
10✔
263
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
6✔
264
      nonOrderedPostProcessors.add(pp);
4✔
265
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
3✔
266
        internalPostProcessors.add(pp);
4✔
267
      }
268
    }
1✔
269
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
3✔
270

271
    // Finally, re-register all internal BeanPostProcessors.
272
    sortPostProcessors(internalPostProcessors, beanFactory);
3✔
273
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
3✔
274

275
    // Re-register post-processor for detecting inner beans as ApplicationListeners,
276
    // moving it to the end of the processor chain (for picking up proxies etc).
277
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
6✔
278
  }
1✔
279

280
  /**
281
   * Load and sort the post-processors of the specified type.
282
   *
283
   * @param beanFactory the bean factory to use
284
   * @param beanPostProcessorType the post-processor type
285
   * @param <T> the post-processor type
286
   * @return a list of sorted post-processors for the specified type
287
   */
288
  static <T extends BeanPostProcessor> List<T> loadBeanPostProcessors(
289
          ConfigurableBeanFactory beanFactory, Class<T> beanPostProcessorType) {
290

291
    var postProcessorNames = beanFactory.getBeanNamesForType(beanPostProcessorType, true, false);
6✔
292
    List<T> postProcessors = new ArrayList<>();
4✔
293
    for (String ppName : postProcessorNames) {
16✔
294
      postProcessors.add(beanFactory.getBean(ppName, beanPostProcessorType));
8✔
295
    }
296
    sortPostProcessors(postProcessors, beanFactory);
3✔
297
    return postProcessors;
2✔
298

299
  }
300

301
  /**
302
   * Selectively invoke {@link MergedBeanDefinitionPostProcessor} instances
303
   * registered in the specified bean factory, resolving bean definitions and
304
   * any attributes if necessary as well as any inner bean definitions that
305
   * they may contain.
306
   *
307
   * @param beanFactory the bean factory to use
308
   */
309
  static void invokeMergedBeanDefinitionPostProcessors(StandardBeanFactory beanFactory) {
310
    new MergedBeanDefinitionPostProcessorInvoker(beanFactory).invokeMergedBeanDefinitionPostProcessors();
5✔
311
  }
1✔
312

313
  private static void sortPostProcessors(List<?> postProcessors, ConfigurableBeanFactory beanFactory) {
314
    // Nothing to sort?
315
    if (postProcessors.size() <= 1) {
4✔
316
      return;
1✔
317
    }
318
    Comparator<Object> comparatorToUse = null;
2✔
319
    if (beanFactory instanceof StandardBeanFactory std) {
6!
320
      comparatorToUse = std.getDependencyComparator();
3✔
321
    }
322
    if (comparatorToUse == null) {
2✔
323
      comparatorToUse = OrderComparator.INSTANCE;
2✔
324
    }
325
    postProcessors.sort(comparatorToUse);
3✔
326
  }
1✔
327

328
  /**
329
   * Invoke the given BeanDefinitionRegistryPostProcessor beans.
330
   */
331
  private static void invokeBeanDefinitionRegistryPostProcessors(
332
          Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
333

334
    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
10✔
335
      postProcessor.postProcessBeanDefinitionRegistry(registry);
3✔
336
    }
1✔
337
  }
1✔
338

339
  /**
340
   * Invoke the given BeanFactoryPostProcessor beans.
341
   */
342
  private static void invokeBeanFactoryPostProcessors(
343
          Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableBeanFactory beanFactory) {
344

345
    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
10✔
346
      postProcessor.postProcessBeanFactory(beanFactory);
3✔
347
    }
1✔
348
  }
1✔
349

350
  /**
351
   * Register the given BeanPostProcessor beans.
352
   */
353
  private static void registerBeanPostProcessors(
354
          ConfigurableBeanFactory beanFactory, List<? extends BeanPostProcessor> postProcessors) {
355

356
    if (beanFactory instanceof AbstractBeanFactory abstractBeanFactory) {
6!
357
      // Bulk addition is more efficient against our list there
358
      abstractBeanFactory.addBeanPostProcessors(postProcessors);
4✔
359
    }
360
    else {
361
      for (BeanPostProcessor postProcessor : postProcessors) {
×
362
        beanFactory.addBeanPostProcessor(postProcessor);
×
363
      }
×
364
    }
365
  }
1✔
366

367
  /**
368
   * BeanPostProcessor that logs an info message when a bean is created during
369
   * BeanPostProcessor instantiation, i.e. when a bean is not eligible for
370
   * getting processed by all BeanPostProcessors.
371
   */
372
  private static final class BeanPostProcessorChecker implements InitializationBeanPostProcessor {
373
    private static final Logger log = LoggerFactory.getLogger(BeanPostProcessorChecker.class);
4✔
374

375
    private final ConfigurableBeanFactory beanFactory;
376

377
    private final String[] postProcessorNames;
378

379
    private final int beanPostProcessorTargetCount;
380

381
    public BeanPostProcessorChecker(ConfigurableBeanFactory beanFactory,
382
            String[] postProcessorNames, int beanPostProcessorTargetCount) {
2✔
383

384
      this.beanFactory = beanFactory;
3✔
385
      this.postProcessorNames = postProcessorNames;
3✔
386
      this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
3✔
387
    }
1✔
388

389
    @Override
390
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
391
      return bean;
2✔
392
    }
393

394
    @Override
395
    public Object postProcessAfterInitialization(Object bean, String beanName) {
396
      if (!(bean instanceof BeanPostProcessor)
5✔
397
              && !isInfrastructureBean(beanName)
4✔
398
              && this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
4✔
399
        if (log.isWarnEnabled()) {
3✔
400
          Set<String> bppsInCreation = new LinkedHashSet<>(2);
5✔
401
          for (String bppName : this.postProcessorNames) {
17✔
402
            if (this.beanFactory.isCurrentlyInCreation(bppName)) {
5✔
403
              bppsInCreation.add(bppName);
4✔
404
            }
405
          }
406
          if (bppsInCreation.size() == 1) {
4!
407
            String bppName = bppsInCreation.iterator().next();
5✔
408
            if (this.beanFactory.containsBeanDefinition(bppName) &&
9!
409
                    beanName.equals(this.beanFactory.getBeanDefinition(bppName).getFactoryBeanName())) {
4✔
410
              log.warn("Bean '{}' of type [{}] is not eligible for getting processed by all BeanPostProcessors " +
12✔
411
                              "(for example: not eligible for auto-proxying). The currently created " +
412
                              "BeanPostProcessor {} is declared through a non-static " +
413
                              "factory method on that class; consider declaring it as static instead.",
414
                      beanName, bean.getClass().getName(), bppsInCreation);
7✔
415
              return bean;
2✔
416
            }
417
          }
418
          log.warn("Bean '{}' of type [{}] is not eligible for getting processed by all BeanPostProcessors " +
12✔
419
                          "(for example: not eligible for auto-proxying). Is this bean getting eagerly " +
420
                          "injected/applied to a currently created BeanPostProcessor {}? " +
421
                          "Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. " +
422
                          "If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.",
423
                  beanName, bean.getClass().getName(), bppsInCreation);
7✔
424
        }
425
      }
426
      return bean;
2✔
427
    }
428

429
    private boolean isInfrastructureBean(@Nullable String beanName) {
430
      if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) {
7✔
431
        BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName);
5✔
432
        return (bd.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
8✔
433
      }
434
      return false;
2✔
435
    }
436
  }
437

438
  private static final class MergedBeanDefinitionPostProcessorInvoker {
439

440
    private final StandardBeanFactory beanFactory;
441

442
    private MergedBeanDefinitionPostProcessorInvoker(StandardBeanFactory beanFactory) {
2✔
443
      this.beanFactory = beanFactory;
3✔
444
    }
1✔
445

446
    private void invokeMergedBeanDefinitionPostProcessors() {
447
      var postProcessors = PostProcessorRegistrationDelegate.loadBeanPostProcessors(
5✔
448
              this.beanFactory, MergedBeanDefinitionPostProcessor.class);
449
      for (String beanName : this.beanFactory.getBeanDefinitionNames()) {
18✔
450
        RootBeanDefinition bd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
6✔
451
        Class<?> beanType = resolveBeanType(bd);
4✔
452
        postProcessRootBeanDefinition(postProcessors, beanName, beanType, bd);
6✔
453
        bd.markAsPostProcessed();
2✔
454
      }
455
      registerBeanPostProcessors(beanFactory, postProcessors);
4✔
456
    }
1✔
457

458
    private void postProcessRootBeanDefinition(List<MergedBeanDefinitionPostProcessor> postProcessors,
459
            String beanName, Class<?> beanType, RootBeanDefinition bd) {
460
      BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(beanFactory, beanName, bd);
8✔
461

462
      for (MergedBeanDefinitionPostProcessor postProcessor : postProcessors) {
10✔
463
        postProcessor.postProcessMergedBeanDefinition(bd, beanType, beanName);
5✔
464
      }
1✔
465

466
      if (bd.hasPropertyValues()) {
3✔
467
        for (PropertyValue propertyValue : bd.getPropertyValues().asList()) {
12✔
468
          postProcessValue(postProcessors, valueResolver, propertyValue.getValue());
6✔
469
        }
1✔
470
      }
471

472
      if (bd.hasConstructorArgumentValues()) {
3✔
473
        for (ValueHolder valueHolder : bd.getConstructorArgumentValues().getIndexedArgumentValues().values()) {
13✔
474
          postProcessValue(postProcessors, valueResolver, valueHolder.getValue());
6✔
475
        }
1✔
476
        for (ValueHolder valueHolder : bd.getConstructorArgumentValues().getGenericArgumentValues()) {
12✔
477
          postProcessValue(postProcessors, valueResolver, valueHolder.getValue());
6✔
478
        }
1✔
479
      }
480
    }
1✔
481

482
    private void postProcessValue(List<MergedBeanDefinitionPostProcessor> postProcessors,
483
            BeanDefinitionValueResolver valueResolver, @Nullable Object value) {
484
      if (value instanceof BeanDefinitionHolder bdh
6✔
485
              && bdh.getBeanDefinition() instanceof AbstractBeanDefinition innerBd) {
9!
486
        Class<?> innerBeanType = resolveBeanType(innerBd);
4✔
487
        resolveInnerBeanDefinition(valueResolver, innerBd, (innerBeanName, innerBeanDefinition)
8✔
488
                -> postProcessRootBeanDefinition(postProcessors, innerBeanName, innerBeanType, innerBeanDefinition));
7✔
489
      }
1✔
490
      else if (value instanceof AbstractBeanDefinition innerBd) {
6✔
491
        Class<?> innerBeanType = resolveBeanType(innerBd);
4✔
492
        resolveInnerBeanDefinition(valueResolver, innerBd, (innerBeanName, innerBeanDefinition)
8✔
493
                -> postProcessRootBeanDefinition(postProcessors, innerBeanName, innerBeanType, innerBeanDefinition));
7✔
494
      }
1✔
495
      else if (value instanceof TypedStringValue typedStringValue) {
6✔
496
        resolveTypeStringValue(typedStringValue);
3✔
497
      }
498
    }
1✔
499

500
    private void resolveInnerBeanDefinition(BeanDefinitionValueResolver valueResolver, BeanDefinition innerBeanDefinition,
501
            BiConsumer<String, RootBeanDefinition> resolver) {
502

503
      valueResolver.resolveInnerBean(null, innerBeanDefinition, (name, rbd) -> {
7✔
504
        resolver.accept(name, rbd);
4✔
505
        return Void.class;
2✔
506
      });
507
    }
1✔
508

509
    private void resolveTypeStringValue(TypedStringValue typedStringValue) {
510
      try {
511
        typedStringValue.resolveTargetType(this.beanFactory.getBeanClassLoader());
6✔
512
      }
513
      catch (ClassNotFoundException ex) {
×
514
        // ignore
515
      }
1✔
516
    }
1✔
517

518
    private Class<?> resolveBeanType(AbstractBeanDefinition bd) {
519
      if (!bd.hasBeanClass()) {
3✔
520
        try {
521
          bd.resolveBeanClass(this.beanFactory.getBeanClassLoader());
6✔
522
        }
523
        catch (ClassNotFoundException ex) {
×
524
          // ignore
525
        }
1✔
526
      }
527
      return bd.getResolvableType().toClass();
4✔
528
    }
529
  }
530

531
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc