23

There are lots of initialization options available in spring bean life cycle.

init-method, PostConstruct annotation, afterPropertiesSet, Bean post-initialization and even class constructor. All these can be used for initializing a bean.

I got confused when to use one these over other. Moreover, is there any case we may need to use all these option in a single Bean? If yes please example would be good.

Really looking forward to get some great answers.

sabtharishi
  • 3,141
  • 5
  • 24
  • 27

3 Answers3

24

The difference between using the constructor and the other options is that the constructor code is the first to be executed, while the other options will be called only after dependencies were injected into the bean (either from @Autowired annotations or the XML file).

Code you write in the constructor will run while the bean's properties are still not initiated. All @Autowired fields would be null. Sometimes this is what you want, but usually you want the code to run after properties are set.

Other than this, I do not see a difference, other then order of execution. I do not think there is a case you would want to have all options in the same class.

alexander zak
  • 929
  • 6
  • 13
9

I would suggest that you only use the constructor where possible. There is one very very good reason to do so: testing

When you are going to unit test a Spring bean, you'll want to be able to construct the class with minimum fuss. That means that you should only need to call the constructor, and not have to deal with calling various life-cycle methods on your own. The last thing you want when creating the class to be tested, is to have to know how the object is property initialized.

With Spring's constructor injection support you can easily inject other other beans or project properties into the constructor therefor being able to cover almost every scenario.

geoand
  • 60,071
  • 24
  • 172
  • 190
  • Almost every scenario, except cases when you can't use constructor injection (i.e. cyclic dependencies). In this case the only way you can initialize bean is `@PostConstruct` and its alternatives. – hoaz Aug 27 '14 at 14:00
  • 2
    I think this [good] Answer is implying the use of "Constructor Injection", just to be clear... And if you do go this route, its probably unwise to additionally have any PostConstruct annotations (http://stackoverflow.com/a/3406690/1357094) in the same class. If it still did, the @PostConstruct method would not be called in [i.e:] vanilla JUnit testing because Spring is not involved there! – cellepo May 17 '17 at 00:43
0

I personally use init-method in the xml configuration just for mocking/unit testing. In many cases, I find myself in situations where I need different logic or different property values (i.e. mock data) in a bean for testing. Additionally, the mock data will often change depending on the test case. In these situations, I find it a lot cleaner to have multiple case-dependent versions a configuration. This way, they can be swapped out without having to change anything inside the classes themselves. Isn't this a main purpose of dependency injection to begin with?

When initializing your beans via constructor, you have to write test-dependent initialization concerns (such as initializing with mock values) into said constructor (or else write multiple constructors). By doing this, you are hard-coding your testing logic into your classes. Avoiding this type of practice is one of the main reasons that frameworks like Spring were created.

Nate T
  • 727
  • 5
  • 21