2012-07-04 27 views
55

我知道这可能看起来像一个以前问过的问题,但我在这里面临一个不同的问题。如何让弹簧注入一个静态字段的值

我有一个只有静态方法的工具类。我不会,我也不会从中得到一个实例。

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

    } 

    public static void methodB(){ 

    } 
} 

现在我需要Spring来填补dataBaseAttr与数据库属性Properties.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> 

我已经在其他豆类做了,但是在这个类(utils的)这里的问题是不一个bean,如果我使它成为一个bean,则不会改变我仍然不能使用该变量,因为该类不会被实例化,并且变量总是等于null。

回答

93

你有两种可能性:

  1. 静态属性/字段非静态的制定者;
  2. 使用org.springframework.beans.factory.config.MethodInvokingFactoryBean来调用一个静态setter。

在第一个选项中,你有一个常规setter的bean,而是设置一个实例属性来设置静态属性/字段。

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

但为了做到这一点,你需要有一颗豆,将暴露此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类的新二传:

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> 
+0

非常感谢,你真的救了我一天。 –

+0

欢迎您! –

+0

我没有尝试第一种解决方案,因为我不太了解它。我尝试了第二种解决方案,它效果很好。 –

20

我也有过类似的要求:我需要一个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); 
    } 
} 
+0

你怎么可能从一个静态方法访问它?我不相信这是可能的!不应该是Person.personRepository = personRepository? –

+3

@JonasGeiregat它是可能的,因为该方法是静态的,它正在访问静态变量 –

+3

我想知道如何在静态上下文中通过'this'引用一个静态变量? – Kripz