【问题标题】:Spring MVC, how to read and access application.properties?Spring MVC,如何读取和访问application.properties?
【发布时间】:2016-06-03 19:20:58
【问题描述】:

我正在使用 Spring MVC(和 Hibernate)开发一个应用程序,并且对配置问题感到有些困惑。有这么多设置和配置 Spring 应用程序的方法并没有让事情变得更简单,有时甚至在整个教程中混在一起......

我使用带有纯 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[] {"/"};
}
}

我们看到有 2 个根配置类,分别用于加载 Hibernate 和 Service 配置类,以及一个用于加载 Service config 类(实际上只是扫描 ~.service 包下的组件)。

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

如我们所见,属性在包含@PropertySource 注解的配置文件中使用。 但很有可能其他配置文件也需要访问 application.properties。此外,我计划在这个文件中定义更多属性,例如存储用户图像的目录。 Controller 方法中将需要此信息,因此我需要一种更全局的方式来访问 application.properties。

所以我的问题是:

  • 注入的环境是否只允许访问属性文件 如果 @PropertyResource 在相同的配置中定义 班级?
  • 当多个@Configuration 类需要访问时 application.properties,我们是否需要将@PropertyResources 添加到 所有这些(迫使我们重复属性文件的名称)
  • 我们如何在没有控制器类的情况下访问属性文件 显式加载它,重复它的名字?

未来,可能会有多个版本的属性文件用于测试和实时部署。

【问题讨论】:

  • Environment 不够全球化怎么办。所有@PropertySource 注释都被解析并放入其中。您可以在任何地方访问Environment 并访问所有加载的属性。所以简而言之,1.不,2不,3使用Environment
  • 感谢您的回答,这是否意味着我可以使用 @PropertySource 仅注释一个配置类,然后将 Environment 注入任何其他类?我认为为此目的使用额外的通用配置类也会更好,因为现在注释在 Hibernate 配置类上,但是当 application.properties 文件也将不包含与 Hibernate 相关的属性时,它不应该加载到Hibernate 专用配置类...
  • 这取决于你,你如何以及在哪里放置注释,不管 Environment 将包含它们全部。

标签: java spring spring-mvc


【解决方案1】:

按问题顺序:

  • 没有。 @PropertyResource 添加到您的配置中,您可以访问 从任何应用程序 bean 到这个属性文件。豆前 创建,Spring收集所有配置的所有属性源, 并将其放入应用程序上下文的单一环境中。
  • 不,我们不需要将@PropertyResources 添加到所有这些。你 可以将属性源添加到一个配置并在 另一个。因此,您不需要重复属性文件的名称。 声明一次,随处使用。
  • 正如您在控制器中猜到的那样,它在其他 bean 中的工作原理也一样。你 只需在配置中声明@PropertyResources,将此配置添加到 你上下文,并在控制器中使用属性。当然,你可以 autowire Environment,就像你在你的例子中所做的那样,得到 来自它的属性。但在我看来,使用 @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();
        }
    }
    

在控制器中也是如此:

    @Controller
    public class MyController{

        //spring will automatically bind value of property
        @Value("${my.property}")
        private String myProperty;

        @RequestMapping("/mapping")
        public String controllerMethod(){
             ...
        }
    }

【讨论】:

  • 谢谢,这确实让我们更清楚了!
  • 太棒了!我只是添加:@PropertySource(value= {"classpath:config.properties"}) @RestController public class XController{ @RequestMapping("${upload.multiFile}") public ResponseEntity uploadMulti(){}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 2020-06-29
  • 2018-01-07
  • 1970-01-01
  • 2021-05-12
相关资源
最近更新 更多