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

Osa*_*Fel 67 java configuration spring app-config

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

我有一个只有静态方法的实用程序类.我没有,我不会从中得到一个实例.

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

    }

    public static void methodB(){

    }
}
Run Code Online (Sandbox Code Playgroud)

现在我需要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>
Run Code Online (Sandbox Code Playgroud)

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

Fra*_*eth 107

你有两种可能性:

  1. 静态属性/字段的非静态setter;
  2. 通过org.springframework.beans.factory.config.MethodInvokingFactoryBean调用静态的制定者.

在第一个选项中,您有一个带有常规setter的bean,而是设置一个instance属性,您可以设置static property/field.

public void setTheProperty(Object value) {
    foo.bar.Class.STATIC_VALUE = value;
}
Run Code Online (Sandbox Code Playgroud)

但是为了做到这一点,你需要有一个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>
Run Code Online (Sandbox Code Playgroud)

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

public static setDataBaseAttr(Properties p)
Run Code Online (Sandbox Code Playgroud)

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

<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>
Run Code Online (Sandbox Code Playgroud)

  • 绝对喜欢第一种选择中的第二种.每次创建实例时设置静态字段都是一种非常奇怪的模式. (5认同)

Abd*_*ull 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);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

.

@Repository
public class PersonRepository {

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

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

那么我是如何将该PersonRepository单例注入到类的静态字段中的Person呢?

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

@Configuration
public class StaticFieldInjectionConfiguration {

    @Inject
    private PersonRepository personRepository;

    @PostConstruct
    private void init() {
        Person.setPersonRepository(personRepository);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我想知道有人如何在静态上下文中通过'this'引用静态变量? (4认同)
  • @JonasGeiregat它是可能的,因为该方法是静态的,它正在访问静态变量 (3认同)