Spring @Bean和PropertyPlaceHolderConfigurer

最近,我被我认为将是一个相当简单的实现所困扰-考虑以下基于Spring Java的bean定义文件(
@Configuration ):

package root;

...

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig {

 @Value("${test.prop}")
 private String attr;

 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }
}

此处定义了一个bean“ sampleService”,该bean初始化为一个属性,该属性使用@Value注释(使用属性占位符字符串$ {test.prop})填充。

对此的测试如下:

@ContextConfiguration(classes=SampleConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class ConfigTest {
 @Autowired
 private SampleService sampleService;
 @Test
 public void testConfig() {
  assertThat(sampleService.aMethod(), is("testproperty"));
 }
}

由于占位符$ {test.prop}根本无法解析,因此使用SampleConfig的当前实现会失败。 为此的标准解决方法是注册一个PropertySourcesPlaceholderConfigurer ,它是一个BeanFactoryPostProcessor,负责扫描所有已注册的bean定义并注入已解析的占位符。 进行此更改后,@ Configuration文件如下所示:

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig { 
 @Value("${test.prop}")
 private String attr;

 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }

 @Bean
 public PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

但是,在添加了属性解析器后,测试仍然失败,这一次sampleService返回的值为null,甚至没有占位符值!

导致该问题的原因是,在@Configuration内部使用诸如@ Autowired,@ Value和@PostConstruct之类的批注的情况下,任何BeanFactoryPostProcessor Bean都必须使用static修饰符进行声明。 否则,包含的@Configuration类将在很早之前实例化,并且负责解析诸如@ Value,@ Autowired等注释的BeanPostProcessors无法对其执行操作。

此修复程序在@Bean的javadoc中有详细记录,还记录了一条消息,提供了解决方法:

WARN : org.springframework.context.annotation.ConfigurationClassEnhancer - @Bean method RootConfig.placeHolderConfigurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean Javadoc for complete details

因此,使用此修复程序,新的工作配置如下:

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig { 
 @Value("${test.prop}")
 private String attr;

 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }

 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

参考文献:

参考: all和其他博客中的Spring @Bean和PropertyPlaceHolderConfigurer(来自我们的JCG合作伙伴 Biju Kunjummen)。

翻译自: https://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值