0

All,

I'm setting up a Spring IOC container using dependency injection, etc. I'm running into a very bizarre behavior where it seems that some beans in a collection get fully initialized before use while others don't. The weird part is that all of these beans share the same superclass and the failed dependency injection is happening in one of the superclass dependencies. Here is the example:

@Component
class Bar {
  void doSomething() {
  // do something
  }
}

class Foo {
  @Autowired Bar bar
}

@Component
class FooSubclass1 extends Foo {
}

@Component
class FooSubclass2 extends Foo {
}

@Component
class FooManager implements InitializingBean {
  @Autowried Collection<Foo> myFoos

  void afterPropertiesSet() {
    for (Foo foo : myFoo) {
      foo.bar.doSomething()
    }
  }
}

During startup the above code would successfully 'doSomething' when iterating over the instance of FooSubclass1 but throw a null point when iterating over the instance of FooSubclass2 when trying to access bar.doSomething() as bar is null.

Of note is that if I don't use InitializingBean as a startup marker I don't run into this problem. If I simply wait for the application to load and then iterate over the collection of Foos all is well. So there appears to be some sort of issue with timing -- the instance of FooSubclass2 has bean created and added to the context but has not bean fully injected.

My understanding of spring is that a given object should be fully created/injected before it is added to the context and that AfterPropertiesSet should only be run after all dependencies have been satisfied. As such I'm not really sure where to start debugging this issue.

A few notes: I'm running this on a Groovy+Grails setup though I don't think that's related to the issue. It's all core spring under the covers and this is clearly something that is happening at the spring level. Also the example above is a bit dumbed down from my real example. I am injecting a collection of a few dozen DAO type objects into the Autowired collection. The injection makes it through several of the DAOs successfully but always fails on the same one. If I remove that DAO from the list it fails on the next one in the list.

Glenn Filson
  • 384
  • 3
  • 10
  • 2
    You don't have any subclass in the above, and Foo is not annotated. Please fix your question. – JB Nizet Nov 03 '12 at 16:34
  • Apologies forgot the extends :) – Glenn Filson Nov 03 '12 at 17:04
  • Though of course the naming as FooSubclassN might have given you some clues... – Glenn Filson Nov 03 '12 at 17:10
  • Have you checked [this question?](http://stackoverflow.com/questions/7655214/spring-autowiring-of-parameterized-collection) If you're trying to auto wire a collection with annotations, then use Resource instead of Autowired. – ElderMael Nov 03 '12 at 17:19
  • Mael, I don't think that's accurate. If you want a collection object as a bean then yes. If you actually want a collection of autowired objects then you use autowired. In any case I've tried it both w/ autowired as well as with context.getBeansOfType(Foo) so it's not an issue w/ the annotation. The collection of Foos is getting put together properly. It's just that some of the Foos don't actually have their Bar dependencies properly injected when AfterPropertiesSet is called. – Glenn Filson Nov 04 '12 at 07:45

0 Answers0