【问题标题】:How to Inject property values into a static property or method of an enum or normal class using Spring?如何使用 Spring 将属性值注入枚举或普通类的静态属性或方法?
【发布时间】:2014-06-10 07:13:06
【问题描述】:

由于某种情况,我遇到了严重的麻烦。这是我的问题。

问题:需要在来自 spring config XML 的枚举类中注入一个简单的静态字符串字段 /property。 这是我测试过的一些类似代码:

public enum AppProperty {
    NUMBER_OF_ACCOUNTS("accounts"), NUMBER_OF_USERS("users");

    private AppProperty(String cuser) {
        this.current_user = cuser;
    }

    private final String current_user;
    private static final String PROPERTY_FILE = "application.properties";

    static {
        init();
    }

    public static String appContext; // **PROBLEM** : need to populate this ONLY
                                        // from spring config XML via property
                                        // injection.

    public static void init() {

        if (appContext.equals("statement")) {
            // do something..... generate statement et...
        } else {
            // do some other process... generate balance etc
        }
    }

    ..........  few more static methods...
    ..... few more non-static methods
}// end of class

对于这个简单的问题,我几乎尝试了所有方法,但奇怪的是 Spring 3.1 似乎没有任何效果:(

通过属性设置器等注入属性根本不起作用.. 字符串 appContext 总是结果为 NULL... 试过了..

 @Autowired(required = true)
   setAppConfig( String context){
AppProperty.appContext = context
)
}

并尝试了所有的连线和自动连线......大多数情况下要么返回 null 要么返回异常“AppProperties.init() 不能被称为没有默认构造函数......” (看在上帝的份上,甚至尝试了一个默认构造函数,但不起作用......!!!

所以我们想从一个属性文件中获取这个单一属性并完成它,但这也不起作用,同样的问题。

<context:component-scan base-package="com.my.package" /> 
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:application.properties</value>
        </list>
    </property>
</bean>

并在 java 类中使用 this over property .. @Value("${appContext}")

这也需要实例化 AppProperty.init(),这是我无法实现的。

我认为从配置 xml 注入属性的唯一方法似乎是使用 MethodInvokingFactoryBean (How to make spring inject value into a static field)

我也尝试过,但我的运气不好,它也不起作用!!!! 唯一我认为我可能做错的事情是没有正确使用@value 标签

在我使用的配置文件中:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod" value="com.my.package.setAppContext"/>
    <property name="arguments"  value ="testing"/>
</bean>

在我使用的java文件AppProperty中

public static  String appContext;
  public void setAppContext(String appContext) {
    AppProperty.appContext = appContext;
    }

请求:请提供我可以使用的确切代码的答案,因为我可能使用了正确的解决方案,但缺少 Syntex 和配置.. 我应该在我的 AppProperty 类上使用@Component 吗?等等...请提供详细信息并得到我的祝福...

注意:我需要通过 Spring Config XML 注入此属性,以便我可以在运行时更改上下文。因为我不允许更改此类的现有实现。 所以请不要建议用其他东西删除枚举类...... 提前致谢。

【问题讨论】:

  • 抱歉,你运气不好,Spring 可以在创建类的实例之后注入任何东西。在此之前,Spring 没有这种控制权。你可以做的是通过反射来破解这个字段,以从 Spring 中注入所需的值(但它是如此肮脏和讨厌,你应该避免它)。
  • @LuiggiMendoza 其实我也试过了..它奏效了......我所做的是......在 AppProperty 类本身中,我使用 InputStream/Java IO 等读取了属性文件......我是能够读取属性...我的应用程序的要求是更改在运行时加载此类的行为..
  • 但在 UAT 我有不同的 spring 配置文件和生产我有另一个 .我想将此属性添加到 Spring XML,以便我可以从它部署的环境的 xml 中读取它。
  • 这是一个徒劳的要求,用Spring做不到,换个策略。期间。
  • @LuiggiMendoza 我的朋友,没有什么是不可能的。请参阅下面的解决方案。经过测试,现在可以正常工作。有时我们必须为现有代码提供功能......因此需要根据现有代码库调整解决方案......无论好坏......只是无法重构应用程序以将解决方案带入一段代码......尤其是当您是该工作的新入职者时:)

标签: java spring configuration dependency-injection static


【解决方案1】:

在没有得到 SO 的帮助之后..做了一些自我斗争并找到了以下解决方案,如果它可以帮助某人:

我意识到 Spring Context 甚至在静态块之前就已经被初始化了。

所以为了间接获取上下文,创建了一个类来获取上下文。

public class SpringBean  {

@Autowired
private  ApplicationContext applicationContext;

private static SpringBean bean = new SpringBean();

public static SpringBean getInstance() {
    return bean;
}


public ApplicationContext getApplicationContext() {
    return applicationContext;
}

public Object getBean(String beanName) {
    if (applicationContext == null) {
        throw new IllegalStateException("No context  initialised.");
    }
    return applicationContext.getBean(beanName);
} 

} 

注意:同样的类可以通过 SpringBean 实现 ApplicationContextAware 接口。

在 spring 配置文件中声明为:

  <context:annotation-config/>      
  <bean    class="com.db.icestation.server.pd.common.SpringBean"
    factory-method="getInstance"/>

还在 spring config 中创建了一个 String SWITCH 变量“appContext”,这是我在 AppProperty 类中注入的变量。

   <bean id="appContext" class="java.lang.String"> 
   <constructor-arg value="Atlast..Injecting this string in a static block..."/> 
    </bean> 

最后......在上面的主类“AppProperty”中获取这个值......

public static String appContext;    // My problem .. see question above...now resolved

 static{
  appContext = SpringBean.getInstance().getBean("appContext").toString();
  init();
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    相关资源
    最近更新 更多