【问题标题】:Spring : how to get values from properties file in Model classSpring:如何从模型类的属性文件中获取值
【发布时间】:2016-01-03 03:20:27
【问题描述】:

我正在为项目使用 Spring MVC。我有一些常量值存储在属性文件中,我想从属性文件中获取。 问题我无法从属性文件中获取模型类中的值。它变得空了

我在 servlet-context.xml 中设置了属性文件位置

 <context:property-placeholder location="classpath:myproperties.properties" />

现在通过使用 @Value 注释,我从属性文件中注入值。

@Component
class ModelTest {

     @Value("${fname}")
     private String fname;

     // Default Constructor
     public ModelTest(){
          Sysout(fname);      // getting null here
     }

     @PostConstruct
     public void initMembers(){
          Sysout(fname)      // Prints fname value properly    
     }

     public void setFname(String fname){
          this.fname=fname;
     }

     public String getFname(){
          return fname;
     }

     @Override
     public String toString() {
          Sysout(fname);
          return "ModelTest [variableFirst=" + variableFirst + "]"; 
     }
}

这里是 ServiceTest 类。

@Service
class ServiceTest(){

    @Value("${fname}")
    private String fname;

    public String printTest(){
         sysout(fname);           // Prints fname value
         return new ModelTest().toString() // Prints null
    }
}

这是 ControllerHome 类:

@Controller
public class ControllerHome {

     @Value("${fname}")
     private String fname;

     @Autowired
     private ServiceTest service;

     @RequestMapping("/")
     public @ResponseBody String printData(){
          sysout(fname);           // Prints fname value
          return service.printTest();  // Print null
     }
}

在模型类中,fname 为空,而在控制器和服务类中的值正常。

有人遇到这样的问题吗?

【问题讨论】:

  • ModelTest 是你的模特班吗?有没有像@Entity...这样的其他注释?
  • 是的,它是虚拟模型类。不,没有@entity 注释。
  • 什么是组件扫描包路径?它应该是 *.alert
  • @MiteshParmar 抱歉,我认为不会有关于组件扫描的任何问题。在 controllerHome 中,ServiceTest 类运行良好。但仅在模型类中,它不起作用,这是我的问题。 base-package 和你写的一样。

标签: java spring properties-file


【解决方案1】:

当您说模型类时,您是指传递给@ModelAttribute指示的控制器方法的值吗?

如果是这样,则该类是由普通构造函数通过反射调用创建的。它不是 spring bean,因此 @Value 什么都不做。

针对您的编辑,我认为对 Spring 的工作原理存在一些根本性的误解。

@Service
class ServiceTest(){

    @Value("${fname}")
    private String fname;

    public String printTest(){
        sysout(fname);           // Prints fname value
        // Calling new here means Spring does nothing
        // ModelTest is not a Spring bean
        // `@Component`, `@PostConstruct` and `@Value` in ModelTest mean nothing.
        return new ModelTest().toString() // Prints null
    }
}

相反,您必须这样做:

@Service
class ServiceTest(){

    @Value("${fname}")
    private String fname;

    @Autowired
    private ModelTest modelTest;

    public String printTest(){
        sysout(fname);           // Prints fname value
        // modelTest is now a Spring bean
        return modelTest.toString() // Should not print null
    }
}

现在,Spring 将创建 ModelTest@Component@PostConstruct@Value 将被 Spring 授予。

但是,@Component 本身具有默认的单例范围。因此,您将始终拥有相同的modelTest

所以,你必须这样做:

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
class ModelTest {
    // ...
}

现在,虽然 ServiceTest 中的 modelTest 引用将保持不变,但使用代理会将方法调用转移到由 Spring 根据请求创建的 ModelTest 的新实例。

【讨论】:

  • 这是您的问题:new ModelTest().toString()。您直接调用new,因此ModelTest 不是Spring bean。 @Value 注释什么也不做。
  • 对不起,我没有得到你。这里 Object 是使用 new 创建的。它与@postconstruct 方法一起调用了构造函数,最后将调用toString 方法。
  • 假设您希望每个请求都有一个新的 ModelTest 实例,请添加 @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)。这告诉 Spring 在开始处理新请求时创建一个新的 ModelTest 实例。然后,使用@Autowire 指定ModelTest 作为字段并返回值而不是调用new。代理允许一个值代表多个请求。
  • 您正在使用new 创建ModelTest。因此,ModelTest 完全不涉及 Spring。因此ModelTest 中的@Value 没有意义。
【解决方案2】:

这就是我的做法:

@Component
@PropertySource("classpath:myproperties.properties") // <-Add this.
class ModelTest {

     @Autowired
     private Environment env; 

     public void test(){
        String name = env.getProperty("name"); //Assuming you have a 'name' key in your myproperties.property
     }
}

【讨论】:

  • 环境对象为空。所以它抛出空异常
  • 这里有点不对劲。你有Autowired Environment 对象,你的ModelTest 类用@Component 注释。当应用程序启动时,IOC 容器将初始化这些类。我又试了一次,它对我有用。我希望你正在导入“正确的”环境类。 import org.springframework.core.env.Environment;
  • Okey 我正在处理它,为什么环境变量会变空。你检查过模型类中的@value 属性吗?
猜你喜欢
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 2010-10-26
  • 1970-01-01
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
相关资源
最近更新 更多