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

TAKETODAY / today-infrastructure / 18154768944

01 Oct 2025 07:26AM UTC coverage: 81.882% (-0.005%) from 81.887%
18154768944

push

github

web-flow
Merge pull request #290 from TAKETODAY/dev/jspecify

jspecify

59788 of 78013 branches covered (76.64%)

Branch coverage included in aggregate %.

141239 of 167496 relevant lines covered (84.32%)

3.6 hits per line

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

92.11
today-context/src/main/java/infra/context/properties/ConfigurationPropertiesBindingPostProcessor.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.properties;
19

20
import org.jspecify.annotations.Nullable;
21

22
import infra.beans.BeansException;
23
import infra.beans.factory.InitializationBeanPostProcessor;
24
import infra.beans.factory.InitializingBean;
25
import infra.beans.factory.config.BeanDefinition;
26
import infra.beans.factory.config.BeanPostProcessor;
27
import infra.beans.factory.support.BeanDefinitionRegistry;
28
import infra.beans.factory.support.RootBeanDefinition;
29
import infra.context.ApplicationContext;
30
import infra.context.ApplicationContextAware;
31
import infra.context.properties.bind.BindMethod;
32
import infra.core.Ordered;
33
import infra.core.PriorityOrdered;
34
import infra.core.env.PropertySources;
35
import infra.lang.Assert;
36

37
/**
38
 * {@link BeanPostProcessor} to bind {@link PropertySources} to beans annotated with
39
 * {@link ConfigurationProperties @ConfigurationProperties}.
40
 *
41
 * @author Dave Syer
42
 * @author Phillip Webb
43
 * @author Christian Dupuis
44
 * @author Stephane Nicoll
45
 * @author Madhura Bhave
46
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
47
 * @since 4.0
48
 */
49
public class ConfigurationPropertiesBindingPostProcessor
3✔
50
        implements InitializationBeanPostProcessor, PriorityOrdered, ApplicationContextAware, InitializingBean {
51

52
  /**
53
   * The bean name that this post-processor is registered with.
54
   */
55
  public static final String BEAN_NAME = ConfigurationPropertiesBindingPostProcessor.class.getName();
4✔
56

57
  @SuppressWarnings("NullAway.Init")
58
  private ApplicationContext applicationContext;
59

60
  @SuppressWarnings("NullAway.Init")
61
  private BeanDefinitionRegistry registry;
62

63
  @SuppressWarnings("NullAway.Init")
64
  private ConfigurationPropertiesBinder binder;
65

66
  @Override
67
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
68
    this.applicationContext = applicationContext;
3✔
69
  }
1✔
70

71
  @Override
72
  public void afterPropertiesSet() throws Exception {
73
    // We can't use constructor injection of the application context because
74
    // it causes eager factory bean initialization
75
    this.registry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();
6✔
76
    this.binder = ConfigurationPropertiesBinder.get(applicationContext);
5✔
77
  }
1✔
78

79
  @Override
80
  public int getOrder() {
81
    return Ordered.HIGHEST_PRECEDENCE + 1;
2✔
82
  }
83

84
  @Override
85
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
86
    if (!hasBoundValueObject(beanName)) {
4✔
87
      bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
7✔
88
    }
89
    return bean;
2✔
90
  }
91

92
  private boolean hasBoundValueObject(String beanName) {
93
    return BindMethod.VALUE_OBJECT.equals(BindMethodAttribute.get(this.registry, beanName));
7✔
94
  }
95

96
  private void bind(@Nullable ConfigurationPropertiesBean bean) {
97
    if (bean == null) {
2✔
98
      return;
1✔
99
    }
100
    if (bean.asBindTarget().getBindMethod() == BindMethod.VALUE_OBJECT) {
5!
101
      throw new IllegalStateException("Cannot bind @ConfigurationProperties for bean '%s'. Ensure that @ConstructorBinding has not been applied to regular bean"
×
102
              .formatted(bean.getName()));
×
103
    }
104
    try {
105
      this.binder.bind(bean);
5✔
106
    }
107
    catch (Exception ex) {
1✔
108
      throw new ConfigurationPropertiesBindException(bean, ex);
6✔
109
    }
1✔
110
  }
1✔
111

112
  /**
113
   * Register a {@link ConfigurationPropertiesBindingPostProcessor} bean if one is not
114
   * already registered.
115
   *
116
   * @param registry the bean definition registry
117
   */
118
  public static void register(BeanDefinitionRegistry registry) {
119
    Assert.notNull(registry, "Registry is required");
3✔
120
    if (!registry.containsBeanDefinition(BEAN_NAME)) {
4✔
121
      BeanDefinition definition = new RootBeanDefinition(ConfigurationPropertiesBindingPostProcessor.class);
5✔
122
      definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
3✔
123
      definition.setEnableDependencyInjection(false);
3✔
124
      registry.registerBeanDefinition(BEAN_NAME, definition);
4✔
125
    }
126
    ConfigurationPropertiesBinder.register(registry);
2✔
127
  }
1✔
128

129
}
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