J'essaie d'apprendre à lire le fichier de propriétés à l'aide de spring. Après une recherche sur Internet, j'ai constaté que je pouvais utiliser les annotations @value
et @PropertySource
pour y parvenir. J'ai créé un projet qui a la structure et les codes de classes suivants:
Structure du projet:
Implémentation AppConfigMongoDB.Java:
package com.mongodb.properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
@PropertySource("classpath:config/config.properties")
public class AppConfigMongoDB {
@Value("#{mongodb.url}")
private String mongodbUrl;
@Value("#{mongodb.db}")
private String defaultDb;
public String getMongoDb()
{
return defaultDb;
}
public String getMongoDbUrl()
{
return mongodbUrl;
}
}
Implémentation SpringConfiguration.Java:
package com.mongodb.properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfiguration {
@Bean
public AppConfigMongoDB getAppConfigMongoDB(){
return new AppConfigMongoDB();
}
}
Main.Java
package com.mongodb.properties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);
AppConfigMongoDB mongo = applicationContext.getBean(AppConfigMongoDB.class);
System.out.println("db= "+mongo.getMongoDb());
System.out.println("URL= "+mongo.getMongoDbUrl());
}
}
Le fichier de propriétés que je lis s'appelle config.properties. Il contient les lignes suivantes:
mongodb.url=1.2.3.4
mongodb.db=dataBase
J'ai testé ce petit projet et une trace de pile contenant l'exception suivante:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getAppConfigMongoDB': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private Java.lang.String com.mongodb.properties.AppConfigMongoDB.mongodbUrl; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'mongodb' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.Java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.Java:1202)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:480)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.Java:84)
at com.mongodb.properties.Main.main(Main.Java:9)
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'mongodb' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.Java:226)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.Java:93)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.Java:81)
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.Java:51)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.Java:87)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.Java:120)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.Java:242)
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.Java:161)
... 18 more
Est-ce un problème de printemps appelant des haricots? Ou peut-être est-ce un problème de chemin du fichier de propriétés ou autre chose?
Je peux voir plusieurs problèmes dans le code.
1) Les espaces réservés aux valeurs doivent être au format ${mogodb.url}
et non pas au #{mongodb.url}
Le "#" a un sens différent (voir expressions de printemps ).
2) Vous allez avoir besoin d'un haricot PropertySourcesPlaceholderConfigurer
pour faire l'injection des valeurs
3) Tôt ou tard, vous allez avoir un certain nombre de Beans flottants, et j'utiliserais @ComponentScan
pour permettre au contexte de les connaître sans que vous ayez à les mentionner un par un
4) Si vous utilisez ComponentScan
pour obtenir les haricots, vous devrez fournir une fois AppConfigMongoDB
bean
Je me retrouve avec ces cours après avoir fait tout ça:
Main.Java
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);
AppConfigMongoDB mongo = applicationContext.getBean(AppConfigMongoDB.class);
System.out.println("db= "+mongo.getMongoDb());
System.out.println("URL= "+mongo.getMongoDbUrl());
}
}
SpringConfiguration.Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@Configuration
@ComponentScan
public class SpringConfiguration {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
AppConfigMongoDB.Java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:config/config.properties")
public class AppConfigMongoDB {
@Value("${mongodb.url}")
private String mongodbUrl;
@Value("${mongodb.db}")
private String defaultDb;
public String getMongoDb() {
return defaultDb;
}
public String getMongoDbUrl() {
return mongodbUrl;
}
}
Belle réponse donnée par @Ian Sparkes. Ajout de certaines de mes entrées ici. La configuration de PropertySourcesPlaceholderConfigurer n'est pas obligatoire. Je peux obtenir la valeur de mon fichier de propriétés et la définir sur la variable classée de ma classe de configuration principale sans celle-ci.
Il existe également un autre moyen d’obtenir les valeurs de vos clés dans le fichier de propriétés. Utilisez la classe org.springframework.core.env.Environment. Cette classe charge automatiquement toutes les paires clé-valeur dans le fichier de propriétés situé dans le chemin de la classe.
Exemple :
@Configuration
@ComponentScan(basePackages="com.easy.buy")
@PropertySource({"classpath:config.properties","classpath:props/db-${env}-config.properties",
"classpath:props/app-${env}-config.properties"})
public class CatalogServiceConfiguration {
Logger logger = LoggerFactory.getLogger(CatalogServiceConfiguration.class);
//This object loads & holds all the properties in it as key-pair values
@Autowired
private Environment env;
/**
* Instantiate the DataSource bean & initialize it with db connection properties
* @return
*/
@Bean(name="basicDataSource")
public BasicDataSource basicDataSource() {
String dbUrl = env.getProperty("db.url");
String dbUser = env.getProperty("db.user");
String dbPwd = env.getProperty("db.pwd");
String driver = env.getProperty("db.driver");
logger.info("Initializing CatalogServiceConfiguration");
logger.info("dbUrl=" + dbUrl);
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(driver);
ds.setUrl(dbUrl);
ds.setUsername(dbUser);
ds.setPassword(dbPwd);
return ds;
}
}