使用 Spring 注解读取文件属性 [英] Read file properties using Spring annotations
问题描述
我正在尝试学习如何使用 spring 读取属性文件.在互联网搜索之后,我发现我可以使用 @value
和 @PropertySource
注释来实现这一点.我创建了一个具有以下结构和类代码的项目:
I'm trying to learn how to read properties file using spring. After an internet searching I found that I can use @value
and @PropertySource
annotations to achieve that. I created a project which has the following structure and classes codes:
项目结构:
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;
}
}
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());
}
}
我正在读取的名为 config.properties 的属性文件,它包含以下几行:
The properties file that I'm reading from called config.properties, it contains the following lines:
mongodb.url=1.2.3.4
mongodb.db=dataBase
我测试了这个小项目,得到了一个包含以下异常的堆栈跟踪:
I tested this small project and I got a stack trace that contains the following exception:
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
是Spring调用bean的问题吗?或者可能是属性文件路径的问题还是其他什么?
Is it a problem of Spring calling beans? Or maybe is it a problem of properties file path or something else?
推荐答案
我可以看到代码中有几个问题.
I can see several issues in the code.
1) 值的占位符应该采用 ${mogodb.url}
的形式,而不是 #{mongodb.url}
.#"有不同的含义(参见 Spring Expressions).
1) Your place holders for values should be in the form ${mogodb.url}
, not #{mongodb.url}
. The "#" has a different meaning (See Spring Expressions).
2) 您将需要一个 PropertySourcesPlaceholderConfigurer
bean 来执行值的注入
2) You are going to need a PropertySourcesPlaceholderConfigurer
bean to do the injection of the values
3) 迟早你会有许多 Bean 漂浮在周围,我会使用 @ComponentScan
让上下文知道这些,而不必一一提及它们
3) Sooner or later you are going to have a number of Beans floating around, and in I would use @ComponentScan
to allow the context to know these without you having to mention them one by one
4) 如果你使用 ComponentScan
来获取 bean,你将不得不提供 AppConfigMongoDB
bean 一次
4) If you use ComponentScan
to get the beans, you are going to have to provide AppConfigMongoDB
bean once
在完成所有这些之后,我最终获得了这些课程:
I end up with these classes after doing all that:
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;
}
}
这篇关于使用 Spring 注解读取文件属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!