Spring IDREF 用法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14607142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:41:30  来源:igfitidea点击:

Spring IDREF usage

spring

提问by yapkm01

I have a spring.xml defined as per below:

我有一个 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>

The Pointclass is basically a class with 2 private int members. My problem is i'm getting the error on IDREF as per below:

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

As far as i understand, the purpose of the IDREF (in the above case) that bean PointAexists (error check) for bean triangle. So i did supply the name of bean PointA(string) in the IDREF element. Why do i get the above error?

Why is it trying to convert a string to Point when i thought it is just checking the existence of a bean (PointA) by just supplying its name?

据我所知,IDREF(在上述情况下)的目的是beanPointA存在(错误检查)bean三角形。所以我确实PointA在 IDREF 元素中提供了 bean (字符串)的名称。为什么会出现上述错误?

当我认为它只是PointA通过提供它的名称来检查 bean ( )的存在时,为什么它试图将字符串转换为 Point ?

I'm really confused. Please help. Thanks.

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

采纳答案by Micha? Politowski

idrefis used to pass the name (identifier)of a bean (that is, a String).

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

<idref bean="pointA">is exactly the same as just the string value pointA, except that Spring will complain if such a bean is not defined.

<idref bean="pointA">与仅字符串 value 完全相同pointA,除了如果没有定义这样的 bean,Spring 会抱怨。

See the Spring documentationfor details.

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

To pass the actual bean just use ref, exactly as you do for pointBand pointC.

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

回答by Praveen Kumar

The idref element is simply an error-proof way to pass the id (string value - not a reference) of another bean in the container to a or element.

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

In simple the idref element is used to pass a string value and using the idref tag allows the container to validate at deployment time that the referenced, named bean actually exists.

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

consider the below example

考虑下面的例子

class FirstBean

class FirstBean

class SecondBean

class SecondBean

Bean definition in the application context

Bean definition in the application context

the calling code for instantiating the beans

the calling code for instantiating the beans

output in the console

output in the console

Notice the output in the console when we invoke secondBean.getSecondMessage() the value is firstBean which was set using the idref attribute.

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

note: A common place where the element brings value is in the configuration of AOP interceptors in a ProxyFactoryBean bean definition. Using elements when you specify the interceptor names prevents you from misspelling an interceptor id.

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

回答by Hari Krishna

By using ‘idref' tag, you can validate at deployment time that the referenced, named bean actually exists or not.

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

For Example,

例如,

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

If you define your validator bean like below, Spring validates the beans with ids osho and Paulo at deployment time. If any bean not found in the configuration file, then spring throws BeanDefinitionStoreException.

如果您像下面这样定义验证器 bean,Spring 会在部署时使用 ids 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>

Following is the complete working application.

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

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

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

    }

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="osho" />
        </property>

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

</beans>

Run HelloWorld.java, you don't get any exceptions.

运行 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();
        }
    }

Now update myConfiguration.xml like below.

现在更新 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>

As you see the configuration file, validatorBean check for the bean with id ‘Krishna'.

当您看到配置文件时,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>

Since the bean with id ‘Krishna' don't exists, you will end up in following error.

由于 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.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)

回答by BennyL

I'm a little bit perplex I must say. In the example you provide praveen it will work because the attribute in your class is of type String but in the example of yapkm01 the attribut is of type Point and you will get the exception mentioned. In order to be able to use idref it seems that he would have to introduce yet another attribute of type String, here "message", and then the code would look something like this:

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

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

<property name="pointA" ref="zeroPoint"/>

回答by user6069813

You are not doing anything wrong. You should be using <ref>in your code and not <idref>. The <idref>tag is used to create a String-typed value equal to the ID of the referred bean and is intended for validation purposes.

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