【问题标题】:Can not read properties file value in Spring Configuration class无法读取 Spring Configuration 类中的属性文件值
【发布时间】:2017-01-15 10:59:01
【问题描述】:

我正在尝试一个简单的 spring 程序,它有一个名为 PersistenceConfig 的类,并用 @Configuration 注释

   @Configuration
   @PropertySource("classpath:application.properties")
   public class PersistanceConfig {
        @Value("${dbPassword}")
        private String dbPassword;

        // Set of Beans and Code

        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            dataSource.setUrl("jdbc:sqlserver://localhost;databaseName=GovernmentPayment;integratedSecurity=false;");
            dataSource.setUsername("sa");
            dataSource.setPassword(dbPassword);
            return dataSource;
        } 


        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
            return new PropertySourcesPlaceholderConfigurer();
        }
   }

当我运行我的程序时,值 dbPassword 始终为空,但如果我尝试在我的控制器中读取相同的值,它会毫无问题地读取该值。 我已经尝试自动装配环境变量并使用它而不是 @Value 但它也不起作用。 (Spring 没有向环境变量注入值)

我正在使用 Spring 4

基本上想要的是将数据库用户名和密码外部化到一个单独的属性文件中。

【问题讨论】:

  • 您是否在控制台中遇到任何错误?发布堆栈跟踪
  • 我得到的唯一错误是无法打开与数据库的连接,因为我的用户名和密码为空。 com.microsoft.sqlserver.jdbc.SQLServerException:用户“”登录失败。 ClientConnectionId:8cf68ac0-9c5c-4fa8-94df-ee64e5cb8319
  • 任何警告?发布完整的堆栈跟踪,它有助于确定根本原因。

标签: java spring configuration


【解决方案1】:

我没有发现给定代码有任何问题。我为您的班级编写了一个简单的单元测试来证明它有效。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=PersistanceConfig.class)
public class PersistanceConfigTest {

    @Autowired
    private DriverManagerDataSource dataSource;

    private final String password = "mydbPassword";


    @Test
    public void testDriverManagerDataSourcePassword() {
        System.out.println("dataSource Password :: " + dataSource.getPassword());
        assertNotNull(dataSource);
        assertTrue(password.equals(dataSource.getPassword()));
    }

}

假设您在 src/main/resources 中有 application.properties,并且该文件中显示了 dbPassword=mydbPassword。

【讨论】:

  • 值注释当我在除使用配置注释注释的类之外的任何地方使用它时工作正常。可以在配置类中读取属性文件吗?我是 Spring 新手。
  • 值应该可以在任何地方工作,包括配置类。你能在你的项目中创建上面的测试并运行会发生什么吗?
【解决方案2】:

感谢 Chad Darby

这是 Spring 版本的问题。

如果您使用的是 Spring 4.2 及更低版本,则需要添加带有 (**) 标记的代码。

package com.luv2code.springdemo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@Configuration
// @ComponentScan("com.luv2code.springdemo")
@PropertySource("classpath:sport.properties")
public class SportConfig {
    
    // add support to resolve ${...} properties
  **@Bean
    public static PropertySourcesPlaceholderConfigurer
                    propertySourcesPlaceHolderConfigurer() {
        
        return new PropertySourcesPlaceholderConfigurer();
    }**
    
    // define bean for our sad fortune service
    @Bean
    public FortuneService sadFortuneService() {
        return new SadFortuneService();
    }
    
    // define bean for our swim coach AND inject dependency
    @Bean
    public Coach swimCoach() {
        SwimCoach mySwimCoach = new SwimCoach(sadFortuneService());
        
        return mySwimCoach;
    }
    
}
````
In Spring 4.3 and higher, they removed this requirement. As a result, you don't need this code.

【讨论】:

    【解决方案3】:

    我已经通过将这两个注释移动到主文件来解决这个问题。

    package com.luv2code.springdemo;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ComponentScan(basePackages = "com.luv2code.springdemo.SportConfig")
    public class SwimJavaConfigDemoApp {
    
        public static void main(String[] args) {
    
            // read spring config java class
            AnnotationConfigApplicationContext context = 
                    new AnnotationConfigApplicationContext(SportConfig.class);
            
            // get the bean from spring container
            Coach theCoach = context.getBean("swimCoach", Coach.class);
            
            // call a method on the bean
            System.out.println(theCoach.getDailyWorkout());
                    
            // call method to get the daily fortune
            System.out.println(theCoach.getDailyFortune());
                        
            // close the context
            context.close();
            
        }
    
    }
    

    配置主文件。

    使用组件扫描并指定配置类的路径。

    接下来,将一些 Bean 写入配置文件。

    package com.luv2code.springdemo;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    public class SportConfig {
        
    //  define a bean for sad fortune service
        @Bean
        public FortuneService sadFortuneService() {
            return new SadFortuneService();
        }
        
    //  define bean for our swim coach and inject dependency
        @Bean
        public Coach swimCoach() {
            return new SwimCoach(sadFortuneService());
        }
    }
    

    进一步学习:Component Scan.

    【讨论】:

      猜你喜欢
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 2020-07-22
      • 2020-02-14
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多