【问题标题】:How to read value from bean in applicationContext.xml?如何从 applicationContext.xml 中的 bean 读取值?
【发布时间】:2014-02-14 18:24:02
【问题描述】:

我需要在我的applicationContext.xml中设置一个参数值接口IP地址

我从属性文件中读取此设置并以这种方式使用它:

<bean id="hazelcastInterface" class="com.hazelcast.config.InterfacesConfig">
        <property name="interfaces">
            <list>
                <value>${interface.ip_address}</value>
            </list>
        </property>
        <property name="enabled" value="true" />
    </bean>

现在我需要从命令行参数中获取这个值。我使用 Apache Commons CLI 解析器,解析参数并从中创建我自己的 bean commandLineConf 并将其设置为 ApplicationContext。

ExternalBeanReferneceFactoryBean.setInstance("commandLineConf", conf);
beanFactory.registerBeanDefinition(
    "commandLineConf",
    BeanDefinitionBuilder.rootBeanDefinition(
        ExternalBeanReferneceFactoryBean.class)
        .getBeanDefinition());

GenericApplicationContext rootAppContext = new GenericApplicationContext(
    beanFactory);
rootAppContext.refresh();

但我不知道如何从 applicationContext.xml 中的这个 bean 获取值。我尝试了很多方法,例如但这对我不起作用。

<bean id="hazelcastInterface" class="com.hazelcast.config.InterfacesConfig">
        <property name="interfaces">
            <list>
                <value>#{commandLineConf.ipAddress}</value>
            </list>
        </property>
        <property name="enabled" value="true" />
    </bean>

我做错了什么?

【问题讨论】:

标签: java xml spring


【解决方案1】:

我使用适当的类测试了您的 xml 应用程序上下文,并且我从该主服务器获得了预期的 ipAddress:

public static void main(String[] args) {

        CommandLineConf conf = new CommandLineConf();
        conf.setIpAddress("127.0.0.1");
        // create root beanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        // register bean definition for the command line
        ExternalBeanReferneceFactoryBean.setInstance("commandLineConf", conf);
        beanFactory.registerBeanDefinition(
            "commandLineConf",
            BeanDefinitionBuilder.rootBeanDefinition(
                ExternalBeanReferneceFactoryBean.class)
                .getBeanDefinition());

        GenericApplicationContext rootAppContext = new GenericApplicationContext(
            beanFactory);
        rootAppContext.refresh();

        // create the application context
        ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { 
            "/applicationContext.xml"
        }, rootAppContext);

        InterfacesConfig hazelcastInterface = (InterfacesConfig)appContext.getBean("hazelcastInterface");
        System.out.println(hazelcastInterface.getInterfaces().get(0));

    }

所以您使用正确的语法来引用地址,即:#{commandLineConf.ipAddress}

这让我觉得问题出在 conf 变量中。您的代码没有显示它是如何填写的,我怀疑缺少 ipAddress。我不能确定,因为你没有在你的片段中包含解析的参数。 在开始构建 spring 上下文之前确保 ipAddress 存在于 conf 变量中(即通过打印它)。

我包括了你可能需要有一个工作代码的其余类:

  • InterfacesConfig.java

    public class InterfacesConfig {
        private List<String>interfaces;
        private boolean enabled;
    
        public List<String> getInterfaces() {
            return interfaces;
        }
    
        public void setInterfaces(List<String> interfaces) {
            this.interfaces = interfaces;
        }
        public boolean isEnabled() {
            return enabled;
        }
    
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    
    }
    
  • CommandLineConf.java

    public class CommandLineConf {
        private String ipAddress;
        public String getIpAddress() {
            return ipAddress;
        }
    
        public void setIpAddress(String ipAddress) {
            this.ipAddress = ipAddress;
        }
    }
    
  • ExternalBeanReferneceFactoryBean.java

    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.config.AbstractFactoryBean;
    
    public class ExternalBeanReferneceFactoryBean extends AbstractFactoryBean implements BeanNameAware {
    
        private static Map<String, Object> instances = new HashMap<String, Object>();
        private String beanName;
    
        /**
         * @param instance the instance to set
         */
        public static void setInstance(String beanName, Object instance) {
            instances.put(beanName, instance);
        }
    
        @Override
        protected Object createInstance() 
            throws Exception {
            return instances.get(beanName);
        }
    
        @Override
        public Class<?> getObjectType() {
            return instances.get(beanName).getClass();
        }
    
        @Override
        public void setBeanName(String name) {
            this.beanName = name;
        }
    
    }
    
  • applicationContext.xml

    <?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:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <bean id="hazelcastInterface" class="com.hazelcast.config.InterfacesConfig">
            <property name="interfaces">
                <list>
                    <value>#{commandLineConf.ipAddress}</value>
                </list>
            </property>
            <property name="enabled" value="true" />
        </bean>
    </beans>
    

【讨论】:

  • 不,它不起作用...我已将代码简化到最大,问题是当我尝试从ClassPathXmlApplicationContext 对象获取bean 时。 Spring 抛出该 bean 不存在的错误 - Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'clc' is defined 。但是代码和你的完全一样:)我不知道它有什么问题。
  • 看起来您正在引用一个未声明的 bean。我需要查看您的 applicationContext.xml 来帮助您。可以发一下吗?
  • 我正在使用非常空的 applicationContext.xml 文件。这就是问题所在,我正在尝试获取的 bean (clc) 以您提到的相同方式在 Java 代码中声明。这很奇怪。
  • applicationContext.xml 不应为空。我包括了我使用的所有文件。你现在应该可以让它工作了。
  • 好吧,applicationContext 可以是空的(“空”是指没有 bean,不是空文件!),我这样做是因为我必须尽量减少副作用。但它不起作用,代码和你的完全一样。稍后我会再试一次,但我不知道出了什么问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
  • 2012-09-05
  • 2011-08-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
相关资源
最近更新 更多