1

Given the following code:

public class MyService implements InitializingBean {

  @Autowired
  private Set<MyDep> allDeps;

  @Override
  public void afterPropertiesSet() {
    ... use 'allDeps' here ...
  }
}

MyDep is an interface with three different implementations all of which also implement InitializingBean (by extending the same abstract base class).

When I go to use allDeps during set up of MyService only 2 out of the 3 injected instances are themselves fully initialized. One of the instances is constructed and injected, but it's afterPropertiesSet() has not yet been run. In the other two instances it has been run.

It's been my understanding that Spring will run afterPropertiesSet() on a bean only after all of its dependencies are injected, and they will only be injected once they're fully initialized. Perhaps my understanding is wrong? Is this a bug in Spring? I've also tried using getBeansOfType(MyDep.class) with the same results.

FWIW, looks like there's an similar unanswered question from 2 years ago. So perhaps it's time to re-ask? Spring dependency injection not completing in time

Community
  • 1
  • 1
pedorro
  • 3,079
  • 1
  • 24
  • 24
  • 1
    I recommend to not implement the InitilizingBean interface. Instead look at the @PostConstruct annotation and use that. – codesalsa Oct 29 '15 at 16:31
  • Thanks for the suggestion, but no luck. In general I do prefer @PostConstruct. But it this case it doesn't help anyway. I think those methods are actually invoked at the same life-cycle point as (and actually prior to) any 'afterPropertiesSet()' method, so in terms of waiting for full initialization that's not going to make a difference. See http://stackoverflow.com/questions/8519187/spring-postconstruct-vs-init-method-attribute – pedorro Oct 29 '15 at 16:59
  • 1
    Do any of the beans that were not picked up have a dependency on `MyService`? – ESala Oct 29 '15 at 17:29
  • Doh! I thought I considered that thoroughly. But I just now re-checked it and there it is. That's exactly what it is. A cyclic dependency (several layers deep) that was just luckily being avoided during context creation in the past. Doh I say!!!! – pedorro Oct 29 '15 at 17:41

1 Answers1

0

Given that it turns out there is a cyclic dependency in my bean definitions, the solution is to wait until the full context is created before doing the initialization in MyService.

Perhaps not the best solution, given that anything that depends on MyService in its set-up could have problems, but I don't currently have any of those. So, this seems to do the trick for me:

public class MyService implements ApplicationListener<ContextRefreshedEvent> {

  @Autowired
  private Set<MyDep> allDeps;

  @Override
  public void onApplicationEvent(ContextRefreshedEvent event) {
    ... now I can use 'allDeps' here ...
  }
}
pedorro
  • 3,079
  • 1
  • 24
  • 24