Spring JavaConfig properties in bean is not gettin

2020-07-10 08:59发布

问题:

I am looking at using Spring JavaConfig with some property files but properties in bean is not getting set?in bean is not getting set?

Here is my WebConfig:

@Configuration
@EnableWebMvc
@PropertySource(value = "classpath:application.properties")
@Import(DatabaseConfig.class)
@ImportResource("/WEB-INF/applicationContext.xml")
public class WebMVCConfig extends WebMvcConfigurerAdapter {

    private static final String MESSAGE_SOURCE = "/WEB-INF/classes/messages";

    private static final Logger logger = LoggerFactory.getLogger(WebMVCConfig.class);

    @Value("${rt.setPassword}")
    private String RTPassword;

    @Value("${rt.setUrl}")
    private String RTURL;

    @Value("${rt.setUser}")
    private String RTUser;


    @Bean
    public  ViewResolver resolver() {
        UrlBasedViewResolver url = new UrlBasedViewResolver();
        url.setPrefix("/WEB-INF/view/");
        url.setViewClass(JstlView.class);
        url.setSuffix(".jsp");
        return url;
    }


    @Bean(name = "messageSource")
    public MessageSource configureMessageSource() {
        logger.debug("setting up message source");
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename(MESSAGE_SOURCE);
        messageSource.setCacheSeconds(5);
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver lr = new SessionLocaleResolver();
        lr.setDefaultLocale(Locale.ENGLISH);
        return lr;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        logger.debug("setting up resource handlers");
        registry.addResourceHandler("/resources/").addResourceLocations("/resources/**");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        logger.debug("configureDefaultServletHandling");
        configurer.enable();
    }

    @Override
    public void addInterceptors(final InterceptorRegistry registry) {
        registry.addInterceptor(new LocaleChangeInterceptor());
    }

    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver();

        Properties mappings = new Properties();
        mappings.put("org.springframework.web.servlet.PageNotFound", "p404");
        mappings.put("org.springframework.dao.DataAccessException", "dataAccessFailure");
        mappings.put("org.springframework.transaction.TransactionException", "dataAccessFailure");
        b.setExceptionMappings(mappings);
        return b;
    }

    @Bean
    public RequestTrackerConfig requestTrackerConfig()
    {
        RequestTrackerConfig tr = new RequestTrackerConfig();
        tr.setPassword(RTPassword);
        tr.setUrl(RTURL);
        tr.setUser(RTUser);

        return tr;
    }


}

The value in tr.url is "rt.setUrl" not the value in application.properties?

回答1:

I'm not 100%, but I think your @PropertySource isn't quite right. Instead of

@PropertySource(value = "classpath:application.properties")

It should just be:

@PropertySource("classpath:application.properties")

based on this:

Spring PropertySource Documentation

Also, based on the link above and since you have mentioned you were converting to a java config approach instead of xml, I think the below might be the solution to your issue:

Resolving ${...} placeholders in and @Value annotations In order to resolve ${...} placeholders in definitions or @Value annotations using properties from a PropertySource, one must register a PropertySourcesPlaceholderConfigurer. This happens automatically when using in XML, but must be explicitly registered using a static @Bean method when using @Configuration classes. See the "Working with externalized values" section of @Configuration Javadoc and "a note on BeanFactoryPostProcessor-returning @Bean methods" of @Bean Javadoc for details and examples.

The example from the link above is how I normally do it:

 @Configuration
 @PropertySource("classpath:/com/myco/app.properties")
 public class AppConfig {
     @Autowired
     Environment env;

     @Bean
     public TestBean testBean() {
         TestBean testBean = new TestBean();
         testBean.setName(env.getProperty("testbean.name"));
         return testBean;
    }
 }

So add at the top:

@Autowired
Environment env;

Then in your method use:

tr.setPassword(env.getProperty("rt.setPassword"));

and so on for the remaining property values. I am just not as familiar with the way you are doing it. I know the above approach will work though.



回答2:

Aside from @ssn771 answer that involves injecting the Environment and retrieving the properties through it which is indeed the suggested way of doing it, this is what I've done as a workaround without having to change the way @Value is being used in the @Configuration POJO.



回答3:

Out of the many suggested things the most important one is that you need to configure PropertySourcesPlaceholderConfigurer in Spring 3.1+ (or PropertyPlaceholderConfigurer in Spring 3.0). It must be static if you want it to be applied to the configuration class (to use @Value annotations).

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

From javadoc for PropertySourcesPlaceholderConfigurer :

This class is designed as a general replacement for PropertyPlaceholderConfigurer in Spring 3.1 applications. It is used by default to support the property-placeholder element in working against the spring-context-3.1 XSD, whereas spring-context versions <= 3.0 default to PropertyPlaceholderConfigurer to ensure backward compatibility. See the spring-context XSD documentation for complete details.