Reputation: 955
I am started writing application where I wanted to include as much spring configuration in java code as I can. The problem that I encounter is with properties file. Take a look what I have writen so far:
File containing beans declaration:
@Configuration
@ImportResource("classpath:properties-configuration.xml")
public class ContextConfigutarion {
@Value("${database.url}")
private String database_url;
@Value("${database.user}")
private String database_user;
@Value("${database.password}")
private String database_password;
@Value("${database.default.shema}")
private String database_default_shema;
@Bean
public BasicDataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(com.mysql.jdbc.Driver.class.getName());
dataSource.setUrl(database_url);
dataSource.setUsername(database_user);
dataSource.setPassword(database_password);
return dataSource;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setHibernateProperties(hibernateProperties); // <- here I encountered a problem
return sessionFactory;
}
...
}
properties-configuration.xml it is minimum necessery file, used only for specify file properties location:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:database.properties" />
</beans>
When I started configuring sessionFactory object I notice a problem. As I understand in ContextConfiguration class I have to subtract every property from my database.properties file. If my application have a lot of properties then my configuration java code is redundantly growing. Isn't there better way to transfer properties through Spring to my components without extracting every single one of them.
Second related question: what is there a good way to preserve application properties in tree like structure? Because as you see in above example application properties contain: data source properties, hibernate properties, etc. which in fact is property tree. If my application whould be bigger and have more components preserving properies in tree like structure whould be great. I image that I have properties stored in catalogs like that:
/application
/hibernate
filename.properties
/database
filename.properties
/someOddComponent
/someStrangeComponent
filename.properties
filename.properties
filename.properties
So if I ask for application.properties I whould got sum for all .properties files in application directory (and sub catalogs), if I ask for hibernate.properties I whould got sum for all .properties files hibernate directory (and sub catalogs), etc. Maybe here I exaggerate the problem, what do you think?
Upvotes: 0
Views: 2085
Reputation: 125232
First ditch your xml file and use a @PropertySource
annotation to load the properties file and register a PropertySourcePlaceholderConfigurer
in your configuration class.
@Configuration
@PropertySource("classpath:database.properties")
public class ContextConfigutarion {
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer ();
}
}
If you have a lot of properties instead of specifying @Value
annotations use the Environment
and the getProperty
and getRequiredProperty
methods instead.
@Configuration
@PropertySource("classpath:database.properties")
public class ContextConfigutarion {
@Autowired
private Environment env;
@Bean
public BasicDataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(com.mysql.jdbc.Driver.class.getName());
dataSource.setUrl(env.getRequiredProperty("database.url"));
dataSource.setUsername(env.getRequiredProperty("database.user));
// Other properties
return dataSource;
}
}
You don't want to have a lot of configuration files as that will only make things complex and unmaintainable. Limit them to a certain number. If you want a tree like system don't use a property file use a yaml file instead. Although a bit harder too load (not supported by @PropertySource
) this allows for tree like configuration structures in a single file.
Or even better let Spring Boot handle the complexity for you (that supports both properties and yaml files out of the box). Reduces your configuration and gives you nice auto config out-of-the-box.
Upvotes: 1