Java Spring MVC,如何读取和访问application.properties?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35552402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC, how to read and access application.properties?
提问by klausch
I am working on an application with Spring MVC (and Hibernate) and feel a bit confused about configuration issues. It does not make it simpler that there are so many ways of setting up and configuring Spring application, which are sometimes even mixed throughout tutorials...
我正在使用 Spring MVC(和 Hibernate)开发一个应用程序,并且对配置问题感到有些困惑。设置和配置 Spring 应用程序的方法有很多,有时甚至在整个教程中混合使用,这并没有让事情变得更简单……
I use Spring 4 with a pure Java-based configuration, so free of XML configuration files. The entry point for the application is a subclass of AbstractAnnotationConfigDispatcherServletInitializer:
我使用带有纯 Java 配置的 Spring 4,因此没有 XML 配置文件。应用程序的入口点是 AbstractAnnotationConfigDispatcherServletInitializer 的子类:
public class MvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {
HibernateConfig.class,
ServiceConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {MvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
We see that there are 2 root configuration classes, for loading the Hibernate and the Service config classes respectively, and one for loading the Service config class (which actually does nothing more than scanning for conponents under the ~.service package).
我们看到有 2 个根配置类,分别用于加载 Hibernate 和 Service 配置类,一个用于加载 Service 配置类(实际上只是扫描 ~.service 包下的组件)。
The HibernateConfig is the only one which needs properties from the application.properties file, so this file is read as a PropertySource and used in the class as follows:
HibernateConfig 是唯一需要 application.properties 文件中的属性的文件,因此该文件被读取为 PropertySource 并在类中使用,如下所示:
package nl.drsklaus.activiteitensite.configuration;
//imports
@Configuration
@EnableTransactionManagement
@ComponentScan({"nl.mydomain.activiteitensite.dao"})
@PropertySource(value= {"classpath:application.properties"})
public class HibernateConfig {
@Autowired
private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory() {
//code
return sessionFactory;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
//TODO connection pooling configuration
return properties;
}
}
As we see, the properties are used in the configuration file containing the @PropertySource annotation. But it is very well possible that also other configuration files will need to accesss application.properties. And moreover, I plan to define more properties in this file, for example the directory where user images will be stored. This information will be needed in Controller methods, so I need to have a more global way of acceessing application.properties.
如我们所见,这些属性用于包含@PropertySource 注释的配置文件中。但是很可能其他配置文件也需要访问 application.properties。此外,我计划在此文件中定义更多属性,例如将存储用户图像的目录。Controller 方法中将需要此信息,因此我需要有一种更全局的方式来访问 application.properties。
So my questions are:
所以我的问题是:
- Does the injected Environment only give access to the property file if the @PropertyResource is defined in the very same configuration class?
- When more than one @Configuration classes need access to application.properties, do we need to add the @PropertyResources to all of them (forcing us to repeat the name of the property file)
- How can we access the property file from the Controller classes without loading it explicitly, repeating its name?
- 如果@PropertyResource 是在同一个配置类中定义的,注入的环境是否只允许访问属性文件?
- 当多个@Configuration 类需要访问application.properties 时,我们是否需要将@PropertyResources 添加到所有类中(强制我们重复属性文件的名称)
- 我们如何从 Controller 类访问属性文件而不显式加载它,重复其名称?
In the future, there will possibly multiple versions of the property file for testing and live deployment.
将来,可能会有多个版本的属性文件用于测试和实时部署。
采纳答案by Ken Bekov
In order of questions:
按问题排序:
- No.
@PropertyResource
added to you configuration gives you access to this property file from any bean of application. Before beans creation, Spring collects all property sources of all configurations, and puts it into single Environment of Application context. - No, we don't need to add the
@PropertyResources
to all of them. You can add property source to one configuration and use it in the another one. So, you don't need to repeat name of the property file. Declare it once, and use anywhere. As you guessed in controllers it works as well as in other beans. You need just declare
@PropertyResources
in config, add this config to you context, and use properties in controller. Of cause, you can autowireEnvironment
, as you did in your example, and get properties from it. But in my opinion using of@Value
annotation little bit more convenient:@Configuration @PropertySource(value= {"classpath:application.properties"}) public class MyConfig{ //spring will automatically bind value of property @Value("${my.property}") private String myProperty; //this bean needed to resolve ${property.name} syntax @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() { return new PropertySourcesPlaceholderConfigurer(); } }
- 否。
@PropertyResource
添加到您的配置中,您可以从应用程序的任何 bean 访问此属性文件。在创建 bean 之前,Spring 会收集所有配置的所有属性源,并将其放入 Application 上下文的单个 Environment 中。 - 不,我们不需要将
@PropertyResources
全部添加到它们中。您可以将属性源添加到一种配置并在另一种配置中使用它。因此,您不需要重复属性文件的名称。声明一次,随处使用。 正如您在控制器中猜测的那样,它在其他 bean 中也能正常工作。您只需
@PropertyResources
在配置中声明,将此配置添加到您的上下文中,并在控制器中使用属性。当然,您可以 autowireEnvironment
,就像您在示例中所做的那样,并从中获取属性。但在我看来,使用@Value
注解更方便一点:@Configuration @PropertySource(value= {"classpath:application.properties"}) public class MyConfig{ //spring will automatically bind value of property @Value("${my.property}") private String myProperty; //this bean needed to resolve ${property.name} syntax @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() { return new PropertySourcesPlaceholderConfigurer(); } }
Same way in controllers:
在控制器中的相同方式:
@Controller
public class MyController{
//spring will automatically bind value of property
@Value("${my.property}")
private String myProperty;
@RequestMapping("/mapping")
public String controllerMethod(){
...
}
}