Nov 05 2012

Learning Spring, part IV

Category: TechnicalIuliana @ 13:05

<ref local=””/> vs. <ref bean=””/>

So, when should we use one or the other and why?

First, I’ll offer you a link to the official Spring reference documentation related to this subject.  Basically:

Specifying the target bean through the bean attribute of the tag is the most general form, and allows creation of a reference to any bean in the same container or parent container, regardless of whether it is in the same XML file. The value of the bean attribute may be the same as the id attribute of the target bean, or as one of the values in the name attribute of the target bean.

And:

Specifying the target bean through the local attribute leverages the ability of the XML parser to validate XML id references within the same file. The value of the local attribute must be the same as the id attribute of the target bean. The XML parser issues an error if no matching element is found in the same file. As such, using the local variant is the best choice (in order to know about errors as early as possible) if the target bean is in the same XML file.

Then we will play with some source code.

Here are the beans:

//MyBean.java
public class MyBean {

    private OtherBean otherBean;

    public OtherBean getOtherBean() {
       return otherBean;
    }

    public void setOtherBean(OtherBean otherBean) {
        this.otherBean = otherBean;
    }

    @Override
    public String toString() {
       return otherBean.toString();
    }
}
//OtherBean.java
public class OtherBean {
    // nothing here, we just need the simplest bean ever :)
}

Here are the configuration files:

<!-- app-config_1.xml =-->
<bean id="myBean" class="MyBean">
        <property name="otherBean"><ref local="otherBean"/></property>
</bean>
<!-- app-config_2.xml =-->
<bean id="otherBean" class="OtherBean"/>

And here is the test class:

//RefLocalTest.java
public class RefLocalTest {
    public static void main(String... args){
        String[] configLocations = new String[] {"classpath:META-INF/app-config_1.xml", "classpath:META-INF/app-config_2.xml"};
        BeanFactory beanFactory = new FileSystemXmlApplicationContext(configLocations);
        MyBean myBean = beanFactory.getBean(MyBean.class);
       System.out.println(myBean.toString());
   }
}

We will be testing the following cases:

  1. <ref local="otherBean"/> ; <bean id="otherBean"/> in different configuration files.
  2. <ref local="otherBean"/> ; <bean name="otherBean"/> in different configuration files.
  3. <ref bean="otherBean"/> ; <bean id="otherBean"/> in different configuration files.
  4. <ref bean="otherBean"/> ; <bean name="otherBean"/> in different configuration files.
  5. <ref local="otherBean"/> ; <bean id="otherBean"/> in the same configuration file.
  6. <ref local="otherBean"/> ; <bean name="otherBean"/> in the same configuration file.
  7. <ref bean="otherBean"/> ; <bean id="otherBean"/> in the same configuration file.
  8. <ref bean="otherBean"/> ; <bean name="otherBean"/> in the same configuration file.

I used a BeanFactory in my example, but I got the same results for an ApplicationContext, which was totally expected.Let’s see what happens:

  1. [WTF test case]We expect for the code not to compile, as the referenced bean is in a different xml file, so it’s not local, we expect an XML parser error. But, actually the code compiles, and when executed the otherBean property of MyBean is correctly initialized.
  2. [WTF test case]We expect for the code not to compile, as the referenced bean is referred in the <ref local=””/> element by its name, not it’s id. So again, we expect to get anXML parser error, but again, nothing happens. The code compiles, and when executed the otherBean property of MyBean is correctly initialized.
  3. As expected, the code compiles, and when executed the otherBean property of MyBean is correctly initialized.
  4. As expected, the code compiles, and when executed the otherBean property of MyBean is correctly initialized.
  5. As expected, the code compiles, and when executed the otherBean property of MyBean is correctly initialized.
  6. [WTF test case]We expect for the code not to compile, as the referenced bean is referred in the <ref local=””/> element by its name, not it’s id. So again, we expect to get anXML parser error, but again, nothing happens. The code compiles, and when executed the otherBean property of MyBean is correctly initialized.
  7. As expected, the code compiles, and when executed the otherBean property of MyBean is correctly initialized.
  8. As expected, the code compiles, and when executed the otherBean property of MyBean is correctly initialized.

So, anybody can explain this? Is this a known bug?

Tags:

One Response to “Learning Spring, part IV”

  1. Wild thoughts » Learning Spring, part V says:

    […] here is the conclusion of this post, which was debated with my friend MARIANUL […]

Leave a Reply