Why @Configuration Beans Lose @Value and @PostConstruct in Dubbo Spring Boot Starter
This article investigates why @Configuration classes imported via @Import in a Spring Boot Dubbo starter fail to inject @Value properties and execute @PostConstruct, tracing the issue to early bean creation by a FactoryBean and offering practical work‑arounds.
Last week I encountered an interesting problem while using Spring Boot with Dubbo. I imported Dubbo as a starter and configured the registry using JavaConfig, but the @Value properties were not injected and @PostConstruct never ran.
Below is the configuration code:
@Configuration
public class DubboRegistryConfig {
@Value("${dynamic.dubbo.registries.nacos.address:#{null}}")
private String nacosAddress;
@Value("${dynamic.dubbo.registries.zk.address:#{null}}")
private String zkAddress;
@Bean
public RegistryConfig nacosRegistry() {
RegistryConfig nacosConfig = new RegistryConfig();
nacosConfig.setAddress(nacosAddress);
nacosConfig.setProtocol("nacos");
return nacosConfig;
}
@Bean
public RegistryConfig zkRegistry() {
RegistryConfig zkConfig = new RegistryConfig();
zkConfig.setAddress(zkAddress);
zkConfig.setProtocol("zookeeper");
return zkConfig;
}
@Bean
public ConsumerConfig consumerConfig() {
ConsumerConfig consumerConfig = new ConsumerConfig();
List<RegistryConfig> registryConfigs = new ArrayList<>(2);
registryConfigs.add(nacosRegistry());
registryConfigs.add(zkRegistry());
consumerConfig.setRegistries(registryConfigs);
return consumerConfig;
}
@Bean
public ProviderConfig providerConfig() {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setRegistry(zkRegistry());
return providerConfig;
}
}The jar is packaged and imported in the main project with:
@SpringBootApplication
@Import(DubboRegistryConfig.class)
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.run(args);
}
}Registry addresses are placed in application.properties. When the application runs, the two registry addresses are not injected into consumerConfig. The log shows:
ConfigurationClassPostProcessor.enhanceConfigurationClasses()|Cannot enhance @Configuration bean definition 'com.lkxiaolou.registry.dynamic.config.DubboRegistryConfig' since its singleton instance has been created too early. The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'.This indicates that DubboRegistryConfig was instantiated too early, before ConfigurationClassPostProcessor could enhance it, so @Value and @PostConstruct were ineffective.
Adding debug prints inside the configuration class revealed that only three beans printed their creation messages:
=== consumerConfig create
=== nacosRegistry create
=== zkRegistry createThe providerConfig bean never printed because the application crashed, and the DubboRegistryConfig itself never executed its @PostConstruct method.
Investigation showed that the problem stems from the order of Spring’s post‑processors. ServiceAnnotationBeanPostProcessor, provided by dubbo-spring-boot-starter, implements BeanFactoryPostProcessor. It runs before any BeanPostProcessor. During its execution it tries to inject Environment, which forces Spring to scan all bean definitions. When it encounters Dubbo’s ReferenceBean (a FactoryBean), Spring calls getTypeForFactoryBean, which creates the bean prematurely.
Because the ReferenceBean is instantiated before the regular BeanPostProcessor chain (which handles @Value and @PostConstruct), those annotations never take effect in DubboRegistryConfig.
Solution: avoid using @Value and @PostConstruct in such configuration classes. Instead, implement InitializingBean and override afterPropertiesSet for post‑construction logic, and implement EnvironmentAware to obtain configuration values via setEnvironment.
Additional open questions include why a @Configuration class imported via @Import is not treated as a bean and the significance of the first log output.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Xiao Lou's Tech Notes
Backend technology sharing, architecture design, performance optimization, source code reading, troubleshooting, and pitfall practices
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
