如何将弹簧注入值置于静态场中

时间:2012-07-04 07:32:04

标签: java spring configuration app-config

我知道这可能看起来像是一个先前提出的问题,但我在这里遇到了一个不同的问题。

我有一个只有静态方法的实用程序类。我没有,我也不会从中获取实例。

public class Utils{
    private static Properties dataBaseAttr;
    public static void methodA(){

    }

    public static void methodB(){

    }
}

现在我需要Spring用数据库属性填充dataBaseAttr属性.Spring配置为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

<util:properties id="dataBaseAttr"
        location="file:#{classPathVariable.path}/dataBaseAttr.properties" />
</beans>

我已经在其他bean中完成了但是这个类(Utils)中的问题不是bean,如果我把它变成bean没什么变化我仍然不能使用变量,因为类不会被实例化和变量总是等于null。

3 个答案:

答案 0 :(得分:105)

您有两种可能性:

  1. 静态属性/字段的非静态setter;
  2. 使用org.springframework.beans.factory.config.MethodInvokingFactoryBean调用静态setter。
  3. 在第一个选项中,您有一个带有常规setter的bean,而是设置一个实例属性,您可以设置静态属性/字段。

    public void setTheProperty(Object value) {
        foo.bar.Class.STATIC_VALUE = value;
    }
    

    但是为了做到这一点,你需要有一个bean的实例来公开这个setter(它更像是解决方法)。

    在第二种情况下,它将按如下方式完成:

    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="foo.bar.Class.setTheProperty"/>
        <property name="arguments">
            <list>
                <ref bean="theProperty"/>
            </list>
       </property>
    </bean>
    

    在你的情况下,你将在Utils类上添加一个新的setter:

    public static setDataBaseAttr(Properties p)
    

    在您的上下文中,您将使用上面举例说明的方法对其进行配置,或多或少像:

    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="foo.bar.Utils.setDataBaseAttr"/>
        <property name="arguments">
            <list>
                <ref bean="dataBaseAttr"/>
            </list>
       </property>
    </bean>
    

答案 1 :(得分:21)

我有类似的要求:我需要将一个Spring管理的存储库bean注入我的Person实体类(“实体”,如“带有标识的东西”,例如JPA实体)。 Person实例有朋友,并且对于此Person实例返回其朋友,它将委托给其存储库并在那里查询朋友。

@Entity
public class Person {
    private static PersonRepository personRepository;

    @Id
    @GeneratedValue
    private long id;

    public static void setPersonRepository(PersonRepository personRepository){
        this.personRepository = personRepository;
    }

    public Set<Person> getFriends(){
        return personRepository.getFriends(id);
    }

    ...
}

@Repository
public class PersonRepository {

    public Person get Person(long id) {
        // do database-related stuff
    }

    public Set<Person> getFriends(long id) {
        // do database-related stuff
    }

    ...
}

那么我如何将PersonRepository单例注入Person类的静态字段?

我创建了一个@Configuration,它在 Spring ApplicationContext构建时中被选中。这个@Configuration注入了我需要作为静态字段注入其他类的所有bean。然后使用@PostConstruct注释,我抓住一个钩子来执行所有静态场注入逻辑。

@Configuration
public class StaticFieldInjectionConfiguration {

    @Inject
    private PersonRepository personRepository;

    @PostConstruct
    private void init() {
        Person.setPersonRepository(personRepository);
    }
}

答案 2 :(得分:0)

由于这些答案很旧,这是我喜欢的答案,非常干净,仅适用于Java批注:

  

要修复此问题,请创建一个“无静态设置器”以为静态变量分配注入值。例如:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class GlobalValue {

public static String DATABASE;

@Value("${mongodb.db}")
public void setDatabase(String db) {
    DATABASE = db;
}
}

https://www.mkyong.com/spring/spring-inject-a-value-into-static-variables/