0

I have a bean like this:

@Component
@DependsOn("SomeType")
Class A{

@Autowired
SomeType one;

String two = one.someMethod();

int three;

}

In my application context xml, I have:

<bean id="two" class="a.b.c.SomeType"></bean>

<context:component-scan base-package="a.b.c"/>
<context:annotation-config/>

But while Spring instantiates the bean, it throws a NullPointerException. So I'm wondering if the field two is initialized before field one, causing the NPE. Can anyone tell me in which order fields are initialized in a bean?

broun
  • 2,483
  • 5
  • 40
  • 55

2 Answers2

3

Your class A declaration is compiled into this one:

class A {
    @Autowired 
    SomeType one;
    String two;
    int three;

    public A() {
        this.two = one.someMethod();
    }
}

So when Spring creates an instance of A to inject an instance of SomeType into it, it calls the A's default constructor and hence you get an NPE.

denis.solonenko
  • 11,645
  • 2
  • 28
  • 23
  • okay thanks for the response, Can you tell me what would happen if i have a no argument constructor in the class like public A(){}. Also is there a tool or something u used to get the compiled version ? – broun Mar 26 '13 at 02:53
  • 2
    @maver1k Your code `String two = one.someMethod();` is an instance variable initialization (http://stackoverflow.com/questions/1994218/instance-variable-initialization-in-java) and is embedded into constructor by compiler whenever your declared one manually or not. You can use `javap` to take a look at the resulting bytecode produced by compiler. – denis.solonenko Mar 26 '13 at 03:17
1

First I have to say that String two = one.someMethod(); this line of code is very very bad. Then let me explain how the NPE happens. When the Spring instants the beans, first it instant the bean: A, then try to bind the field one, at this time, the bean SomeType may not be instanted, so the Sping will mark it as await to instant and then goes on to bind the other field, it move to instant two, then cause problem.

OQJF
  • 1,350
  • 9
  • 12
  • Thanks. But you do you say that it is bad coding practice? Also I had missed out an important part "DependsOn" i have. I masked sure that the SomeType bean is created first. – broun Mar 26 '13 at 02:55
  • To be honest, that's really bad if you understand that you use Spring to maintain all the beans, And also Spring can't guarantee the order of bean instanstiation. And those 2 config are duplicated. – OQJF Mar 26 '13 at 02:58
  • Even if i annotate one of the beans in relation with "DependsOn" SPring cannot guarantee the order ? – broun Mar 26 '13 at 03:07
  • Definitely it can make sure the depended bean will be instantiated first, but somehow all of those annotations are for special purpose, if you have to use them, it means something in the code is not good. – OQJF Mar 26 '13 at 03:14