如何使弹簧注入值进入静态场

2022-08-31 14:09:51

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

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

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

    }

    public static void methodB(){

    }
}

现在我需要Spring用数据库属性Fills填充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。


答案 1

您有两种可能性:

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

在第一个选项中,您有一个具有常规 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>

在你的情况下,你将在类上添加一个新的 setter: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>

答案 2

我有一个类似的要求:我需要将Spring管理的存储库bean注入到我的实体类中(“实体”,如“具有身份的东西”,例如JPA实体)。一个实例有好友,对于这个实例,要返回其好友,它应该委托到其存储库并查询那里的好友。PersonPersonPerson

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

    ...
}

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

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

@Configuration
public class StaticFieldInjectionConfiguration {

    @Inject
    private PersonRepository personRepository;

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

推荐