Spring:如何从Model类

时间:2015-10-06 09:12:49

标签: java spring properties-file

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

Project Explorer

我在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变为null,而In控制器和服务类值正常。

有人面临这样的问题吗?

2 个答案:

答案 0 :(得分:0)

我就是这样做的:

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

答案 1 :(得分:0)

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

如果是这样,那个类是通过普通的构造函数调用通过反射创建的。它不是一个春天的豆子,因此@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 {
    // ...
}

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