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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With