在构造函数上注入属性

时间:2013-10-21 08:38:56

标签: spring spring-mvc

我必须使用REST api,它遵循所有可检索对象的通用语法:

baseUrl + domainObjectName + qualifier

E.g。 “http://myweb.com/api/”+“cities”+“/ {id}”

我为我的数据层创建了一个BaseDao,我想在DAO实例化中为每个域对象(baseUrl + domainObjectName)设置基本URL。问题是我在属性文件中定义了我的api Base url(并且希望保持这种方式),并且它在DAO构造函数中不可用。

这就是我所拥有的:

public abstract class BaseDao {

    protected static final String ID_QUALIFIER = "/{id}";
    protected String domainObjectName = "";
    protected String doBaseUrl = "";

    @Value("#{config['baseUrlRest']}")
    public String apiBaseUrl;

    public GenericDaoRestImpl(String domainObjectName) {
        this.domainObjectName = domainObjectName;
        this.doBaseUrl = apiBaseUrl + domainObjectName;
    }

}

当我的dao被实例化时,apiBaseUrl仍为null,尽管在创建之后它确实注入了baseUrl属性。

有没有办法解决这个问题,比如将属性作为静态常量注入?

1 个答案:

答案 0 :(得分:2)

这是因为Java在调用构造函数之前不允许设置类的字段。所以Spring无法注入价值。有两种解决方案:

  1. 将值传递给构造函数(例1)
  2. 使用@PostConstruct(示例2)
  3. 示例1:

    public GenericDaoRestImpl(
        @Value("#{config['baseUrlRest']}") String apiBaseUrl
        String domainObjectName
    ) {
        ...
    }
    

    示例2:

    @Value("#{config['baseUrlRest']}")
    public String apiBaseUrl;
    
    public GenericDaoRestImpl(String domainObjectName) {
        this.domainObjectName = domainObjectName;
    }
    
    @PostConstruct
    public void init() {
        this.domainObjectName = domainObjectName;
        this.doBaseUrl = apiBaseUrl + domainObjectName;
    }
    

    我更喜欢@PostConstruct,因为构造函数注入最终导致构造函数具有许多参数,这使得它们变得难以处理。

    如果您不喜欢,则第三个选项是builder pattern使用fluent interface