Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am trying to get a Spring-boot application going and I am not sure what I am doing wrong here. I have a application.properties file at src/main/resources & src/test/resources. I have an @Bean for my ConfigurationSettings so that I can use them throughout my application:

@Component
public class ConfigurationSettings {

private String product;
private String version;
private String copyright;
private String appName;
private String appDescription;
... 
// getters and setters

}

Here is how I kick the application off:

@Configuration
@EnableJpaRepositories
@EnableAutoConfiguration
@EnableConfigurationProperties
@PropertySources(value = {@PropertySource("classpath:application.properties")})
@ComponentScan(basePackages = "com.product")
@EnableScheduling
public class OFAC {

public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run( OFAC.class, args );        
}

And here is my configuration class:

@Configuration
@ComponentScan(basePackages = {"com.product"})
@PropertySources(value = {@PropertySource("classpath:application.properties")})
public class OFAConfiguration {

     @Autowired
     private Environment env;

     @Bean
     public ConfigurationSettings configurationSettings() {
         ConfigurationSettings configurationSettings = new ConfigurationSettings();
         configurationSettings.setAppDescription( env.getRequiredProperty("app.description" ) );
         configurationSettings.setAppName( env.getRequiredProperty( "app.name" ) );
         configurationSettings.setServerPort( env.getRequiredProperty( "server.port" ) );
         return configurationSettings;
    }

I am trying to use it in a controller:

@RestController
public class AboutController {

   @Autowired
   private ConfigurationSettings configurationSettings;

   @RequestMapping(value = "/about", method = RequestMethod.GET)
   public About index() {

     String product = configurationSettings.getProduct();
     String version = configurationSettings.getVersion();
     String copyright = configurationSettings.getCopyright();
    return new About( product, version, copyright );
   }
}

However, when step thru this, all the values of ConfigurationSettings are null. I do have a test that successfully loads the values:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {OFAConfiguration.class})
public class OFAConfigurationTest {
  @Autowired
  private Environment environment;

  @Autowired
  private ConfigurationSettings configurationSettings;

  @Test
  public void testConfigurationLoads() {
    assertNotNull(environment);
    Assert.assertNotNull(configurationSettings);
  }

  @Test
  public void testConfigurationSettingValues() {
     assertEquals("Product Name", configurationSettings.getProduct());
    assertEquals("0.0.1", configurationSettings.getVersion());
    assertEquals("2014 Product", configurationSettings.getCopyright());
 }

Can anyone see why the ConfigurationSettings are not being populated in my Controller?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
171 views
Welcome To Ask or Share your Answers For Others

1 Answer

Your configuration leads to 2 instances of the ConfigurationSettings class and probably one instance overrides the other.

The 'ConfigurationSettings' has the @Component annotation as you are scanning for components (@ComponentScan) this will lead to an instance. You also have a @Bean annotated method which also leads to an instance. The latter is overridden with the first.

In short remove the @Component annotation as that isn't needed because you already have a factory method for this class.

public class ConfigurationSettings { ... }

You should also remove the @PropertySource annotations as Spring-Boot will already load the application.properties for you.

Finally you should not use the @ContextConfiguration annotation on your test class but the @SpringApplicationConfiguration and pass in your application class (not your configuration class!).

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes=OFAC.class)
public class OFAConfigurationTest {

    @Autowired
    private Environment environment;

    @Autowired
    private ConfigurationSettings configurationSettings;

    @Test
    public void testConfigurationLoads() {
        assertNotNull(environment);
        assertNotNull(configurationSettings);
    }

    @Test
    public void testConfigurationSettingValues() {
        assertEquals("Product Name", configurationSettings.getProduct());
        assertEquals("0.0.1", configurationSettings.getVersion());
        assertEquals("2014 Product", configurationSettings.getCopyright());
    } 

This will fix your runtime configuration problems and will let your test use the power of Spring Boot to configure your application.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...