15

我有一个 spring.xml 定义如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="triangle" class="org.tutorial.spring.Triangle">
    <property name="pointA">
        <idref bean="pointA"/>
    </property>
    <property name="pointB" ref="pointB"/>
    <property name="pointC" ref="pointC"/>
</bean>
<bean id="pointA" class="org.tutorial.spring.Point">
    <property name="x" value="0"/>
    <property name="y" value="0"/>
</bean>
<bean id="pointB" class="org.tutorial.spring.Point">
    <property name="x" value="100"/>
    <property name="y" value="200"/>
</bean>
<bean id="pointC" class="org.tutorial.spring.Point">
    <property name="x" value="-100"/>
    <property name="y" value="-200"/>
</bean>
</beans>

该类Point基本上是一个具有 2 个私有 int 成员的类。我的问题是我在 IDREF 上收到错误,如下所示:

Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.tutorial.spring.Point' for property 'pointA'; 
nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.tutorial.spring.Point] for property 'pointA': no matching editors or conversion strategy found

据我了解,PointAbean 三角形存在的IDREF(在上述情况下)的目的(错误检查)。所以我确实PointA在 IDREF 元素中提供了 bean 的名称(字符串)。为什么我会收到上述错误?当我认为它只是通过提供其名称来

检查 bean ( ) 的存在时,为什么它试图将字符串转换为 Point ?PointA

我真的很困惑。请帮忙。谢谢。

4

5 回答 5

13

idref用于传递一个bean(即一个String)的名称(标识符)。

<idref bean="pointA">与字符串 value 完全相同,只是pointA如果没有定义这样的 bean,Spring 会报错。

有关详细信息,请参阅Spring 文档

要传递实际的 bean,只需使用ref,就像您为pointBand所做的那样pointC

于 2013-01-30T16:18:25.280 回答
13

idref 元素只是将容器中另一个 bean 的 id(字符串值 - 不是引用)传递给 or 元素的一种防错方法。

简单来说,idref 元素用于传递字符串值,并且使用 idref 标记允许容器在部署时验证所引用的命名 bean 是否实际存在。

考虑下面的例子

类 FirstBean

类 SecondBean

应用程序上下文中的 Bean 定义

实例化 bean 的调用代码

在控制台输出

请注意当我们调用 secondBean.getSecondMessage() 时控制台中的输出,该值是使用 idref 属性设置的 firstBean。

注意:元素带来价值的常见地方是在 ProxyFactoryBean bean 定义中的 AOP 拦截器配置中。在指定拦截器名称时使用元素可防止您拼错拦截器 ID。

于 2013-08-30T18:17:28.710 回答
1

通过使用 'idref' 标记,您可以在部署时验证所引用的命名 bean 是否实际存在。

例如,

<bean id="paulo" class="com.sample.pojo.Author">
    <property name="firstName" value="Paulo" />
    <property name="lastName" value="Coelho" />
    <property name="dateOfBirth" value="24 August 1947" />
    <property name="country" value="India" />
</bean>

如果您像下面这样定义验证器 bean,Spring 会在部署时验证 id 为 osho 和 Paulo 的 bean。如果在配置文件中没有找到任何 bean,那么 spring 会抛出 BeanDefinitionStoreException。

<bean id="validatorBean" class="com.sample.test.BeansValidator">
    <property name="author1">
        <idref bean="osho" />
    </property>

    <property name="author2">
        <idref bean="paulo" />
    </property>
</bean>

以下是完整的工作应用程序。

package com.sample.pojo;

public class Author {
    private String firstName;
    private String lastName;
    private String dateOfBirth;
    private String country;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(String dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Author [firstName=").append(firstName).append(", lastName=").append(lastName)
                .append(", dateOfBirth=").append(dateOfBirth).append(", country=").append(country).append("]");
        return builder.toString();
    }

}

BeansValidator.java

package com.sample.test;

    public class BeansValidator {
        private String author1;
        private String author2;

        public String getAuthor1() {
            return author1;
        }

        public void setAuthor1(String author1) {
            this.author1 = author1;
        }

        public String getAuthor2() {
            return author2;
        }

        public void setAuthor2(String author2) {
            this.author2 = author2;
        }

    }

我的配置.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="osho" class="com.sample.pojo.Author">
        <property name="firstName" value="Osho" />
        <property name="lastName" value="Jain" />
        <property name="dateOfBirth" value="11 December 1931" />
        <property name="country" value="India" />
    </bean>

    <bean id="paulo" class="com.sample.pojo.Author">
        <property name="firstName" value="Paulo" />
        <property name="lastName" value="Coelho" />
        <property name="dateOfBirth" value="24 August 1947" />
        <property name="country" value="India" />
    </bean>

    <bean id="validatorBean" class="com.sample.test.BeansValidator">
        <property name="author1">
            <idref bean="osho" />
        </property>

        <property name="author2">
            <idref bean="paulo" />
        </property>
    </bean>

</beans>

运行 HelloWorld.java,你不会得到任何异常。

package com.sample.test;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class HelloWorld {
        public static void main(String args[]) {
            ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "myConfiguration.xml" });

            ((ClassPathXmlApplicationContext) context).close();
        }
    }

现在更新 myConfiguration.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="osho" class="com.sample.pojo.Author">
        <property name="firstName" value="Osho" />
        <property name="lastName" value="Jain" />
        <property name="dateOfBirth" value="11 December 1931" />
        <property name="country" value="India" />
    </bean>

    <bean id="paulo" class="com.sample.pojo.Author">
        <property name="firstName" value="Paulo" />
        <property name="lastName" value="Coelho" />
        <property name="dateOfBirth" value="24 August 1947" />
        <property name="country" value="India" />
    </bean>

    <bean id="validatorBean" class="com.sample.test.BeansValidator">
        <property name="author1">
            <idref bean="Krishna" />
        </property>

        <property name="author2">
            <idref bean="paulo" />
        </property>
    </bean>

</beans>

当您看到配置文件时,validatorBean 检查 id 为“Krishna”的 bean。

<bean id="validatorBean" class="com.sample.test.BeansValidator">
        <property name="author1">
            <idref bean="Krishna" />
        </property>

        <property name="author2">
            <idref bean="paulo" />
        </property>
    </bean>

由于 id 为“Krishna”的 bean 不存在,您最终会出现以下错误。

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validatorBean' defined in class path resource [myConfiguration.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean name 'Krishna' in bean reference for bean property 'author1'
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
    at com.sample.test.HelloWorld.main(HelloWorld.java:8)
于 2016-10-21T11:42:10.903 回答
0

我必须说我有点困惑。在您提供 praveen 的示例中,它将起作用,因为您的类中的属性是 String 类型,但在 yapkm01 的示例中,属性是 Point 类型,您将得到提到的异常。为了能够使用 idref,他似乎必须引入另一个 String 类型的属性,这里是“message”,然后代码看起来像这样:

<property name="message">
    <idref bean="zeroPoint" />
</property>

<property name="pointA" ref="zeroPoint"/>
于 2013-12-02T13:43:48.837 回答
-1

你没有做错任何事。您应该<ref>在代码中使用而不是<idref>. 该<idref>标记用于创建一个字符串类型的值,该值等于所引用 bean 的 ID,并且用于验证目的。

于 2016-05-04T08:45:24.857 回答