web-dev-qa-db-de.com

Lesen Sie Dateieigenschaften mit Spring-Anmerkungen

Ich versuche zu lernen, wie man die Eigenschaften-Datei mit Spring liest. Nach einer Internet-Suche habe ich festgestellt, dass ich @value- und @PropertySource-Annotationen verwenden kann, um dies zu erreichen. Ich habe ein Projekt erstellt, das folgende Struktur und Klassencodes hat:

Struktur des Projekts:

enter image description here

AppConfigMongoDB.Java-Implementierung:

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;
}
}

SpringConfiguration.Java-Implementierung:

 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());
  }
}

Die Eigenschaftendatei, aus der ich lese, hat den Namen config.properties. Sie enthält folgende Zeilen:

mongodb.url=1.2.3.4
mongodb.db=dataBase

Ich habe dieses kleine Projekt getestet und erhielt eine Stack-Ablaufverfolgung, die die folgende Ausnahme enthält:

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

Ist es ein Problem, wenn Spring Beans ruft? Oder ist es vielleicht ein Problem mit dem Dateipfad der Eigenschaften oder etwas anderem?

10
Kallel Omar

Ich kann mehrere Probleme im Code sehen.

1) Ihre Platzhalter für Werte sollten die Form ${mogodb.url} haben, nicht #{mongodb.url}. Das "#" hat eine andere Bedeutung (Siehe Spring Expressions ). 

2) Sie benötigen eine PropertySourcesPlaceholderConfigurer-Bean, um die Werte zu injizieren

3) Früher oder später werden Sie eine Reihe von Beans haben, und ich würde @ComponentScan verwenden, um den Kontext zu erkennen, ohne dass Sie sie einzeln erwähnen müssen

4) Wenn Sie ComponentScan verwenden, um die Beans zu erhalten, müssen Sie AppConfigMongoDB bean einmal angeben

Ich habe am Ende mit diesen Kursen zu tun, nachdem ich all das getan habe:

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;
  }
}
21
ISparkes

Schöne Antwort von @Ian Sparkes. Hier einige meiner Eingaben hinzufügen. Das Konfigurieren des PropertySourcesPlaceholderConfigurer ist nicht obligatorisch. Ich bin in der Lage, den Wert aus meiner Eigenschaftendatei abzurufen und ihn ohne ihn auf die Feldvariable meiner Hauptkonfigurationsklasse festzulegen. 

Es gibt auch eine andere Möglichkeit, die Werte Ihrer Schlüssel in der Eigenschaftendatei abzurufen. Verwenden Sie die Klasse org.springframework.core.env.Environment. Diese Klasse lädt automatisch alle Schlüssel/Wert-Paare in der Eigenschaftendatei, die sich im Klassenpfad befindet. 

Beispiel: 

@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;
	}
}

0
Ayaskant