Spring MVC,如何读取和访问application.properties?

时间:2016-02-22 11:26:29

标签: java spring spring-mvc

我正在使用Spring MVC(和Hibernate)处理应用程序,并对配置问题感到有点困惑。设置和配置Spring应用程序的方法有很多简单,这有点简单,有时甚至会在整个教程中混合......

我使用Spring 4和纯Java配置,因此没有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配置类(实际上除了扫描~.service包下的conponents之外)。

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。

所以我的问题是:

  • 注入的Environment是否仅授予对属性文件的访问权限 如果@PropertyResource是在同一个配置中定义的 类?
  • 当多个@Configuration类需要访问时 application.properties,我们需要添加@PropertyResources 所有这些(强制我们重复属性文件的名称)
  • 如何在没有的情况下从Controller类访问属性文件 明确加载它,重复它的名字?

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

1 个答案:

答案 0 :(得分:10)

按顺序排列:

  • 否。添加到@PropertyResource配置可让您访问 来自任何应用程序bean的属性文件。之前豆 创建,Spring收集所有配置的所有属性源, 并将其置于单一的应用程序环境中。
  • 不,我们不需要为所有人添加@PropertyResources。您 可以将属性源添加到一个配置并在其中使用它 另一个。因此,您不需要重复属性文件的名称。 声明一次,并在任何地方使用。
  • 正如您在控制器中猜到的那样,它可以和其他bean一样工作。您 需要在config中声明@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(){
             ...
        }
    }