Spring : 如何从模型中的属性文件中获取值 class

Spring : how to get values from properties file in Model class

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

我在 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 class。

@Service
class ServiceTest(){

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

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

这里是 ControllerHome Class :

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

在模型 class 中 fname 变空,而在控制器和服务中 class 值正常。

有人遇到这样的问题吗?

我是这样做的:

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

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

如果是,那class是通过反射调用普通的构造函数创建的。它不是 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 引用将保持不变,但代理的使用会将方法调用转移到由 [= 创建的 ModelTest 的新实例43=],根据要求。