Today when I was trying to do some TDD test, I wrote a test file and used the following code:

The test code:

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class CommandParserTest {
    @Autowired
    private CommandParser parser;
    @Autowired
    private ISaleEventListener listener;

    @Test
    public void test1(){
        fail("nothing");
    }
}

Here “CommandParser” is a normal class and ISaleEventListener is an interface, the implementation of them are not important.

The spring context file:

<?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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
    default-lazy-init="true">

    <bean id="parser" class="com.stanley.check.CommandParser">
    </bean>
    <bean id="listener" class="org.easymock.EasyMock"
        factory-method="createMock" lazy-init="false">
        <constructor-arg value="com.stanley.check.ISaleEventListener"></constructor-arg>
    </bean>
    <bean id="test" class="com.stanley.check.CommandParserTest"
        lazy-init="false">
    </bean>
</beans>

For the above code, the output will be a simple JUnit fail;

But if you change the “lazy-init” for the bean “listener” to be true, you’ll get some error warns you that it cannot do the autowiring because it cannot find some ISaleEventListener;

If you move the declaration of the “test” bean to the top of the context file, you’ll also get the error that cannot find the ISaleEventListener;

So our explanation for this situation is that:

  • Before the bean “listener” is initialized, the Spring doesn’t know its type; so if you change the “laze-init” to be true, spring will not initialize it at the start time, so when the test want to do the autowiring, it report that it cannot find ISaleEventListener;
  • For the other one, spring read the context file in order and will do initializing in the same order if there’s no dependencies; so if the “test” bean is at the top of the context file, it will be initialized first, before the initializing of the “listener” bean. At that time, spring will try to find if there’s some other beans defined in the context file match the autowiring scenario, if found, the dependent bean will be initialized and injected to the “test” bean; but in this case, spring don’t know that the “listener” will be of the type “ISaleEventListener”, so it reports that it cannot do the autowiring.

These are concluded from the phenomenon, not from any formal spring documentations. So if you have any thoughts on this, please leave your comments.