@PostConstruct annotation and spring lifecycle
Solution 1
If you are asking is injection of given class happening after @PostConstruct
in that bean is called, then the answer is yes - @PostConstruct
is executed before bean is considered as "injectable"
If you are asking if @PostConstruct
on given bean is executed after all injections has been done (on the same bean) - then yes - @PostConstruct
is executed after injections are commited to given bean. This is the reason it exists. Normally you could put @PostConstruct
actions into the constructor. However, when new object is created (constructor is called) injections are not performed yet - so any initialization that depends on injected objects would fail due to NPE. That is why you need @PostConstruct
Solution 2
The handling of annotations such as @PostConstruct
, @Resource
, @PreDestroy
is done via a BeanPostProcessor, in this case the CommonAnnotationBeanPostProcessor. You can see in the following diagram from Spring that these BPP's are handled after Dependency Injection but before Bean Ready For Use
(Which means as much as injectable).
Solution 3
Yes. Bean creation workflow is:
- constructior call
-
@Autowired
fields -
@Autowired
setters - BeanPostProcessor's
postProcessBeforeInitialization()
, i.e.@PostConstruct
called byCommonAnnotationBeanPostProcessor
InitializingBean.afterPropertiesSet()
- BeanPostProcessor's
postProcessAfterInitialization()
- Bean is ready and can be injected to other bean
Daniele
Updated on May 26, 2021Comments
-
Daniele almost 3 years
I'm new to Spring, I would like to know:
I have a java class annotated with
@Component
(spring) and inside I have a method annotated with@PostConstruct
. The class is then referenced by@Autowired
annotated field in another class. Can I assume that the class is only injected after@PostConstruct
is called?@Component class AuthenticationMetrics { private static final MetricRegistry metrics = new MetricRegistry(); final Counter requestsTotal; final Meter guestLogins; final Meter kfUserLogins; final Timer guestLoginResponseTime; final Timer kfLoginResponseTime; @PostConstruct public void populateMetricsRegistry() { metrics.counter("authentication.requests.totals"); } }
-
Daniele almost 7 yearsHi, yes I'm asking if @PostConstruct is executed before bean is considered as "injectable", that what I wanted to know. Thanks!
-
Daniele almost 7 yearsyou can remove this part: "If you are asking if @PostConstruct execution means that bean is injected somewhere - then no." I will accept the answer.
-
Sebastiaan van den Broek almost 5 yearsSo does this mean that there is absolutely no use case for @PostConstruct when doing constructor injection?
-
Kalanka almost 5 yearswhat will be the next life cycle step after
@PostConstruct
? i want to append user details fromprincipal
to therequest header
through a custominterceptor
..please help -
rogerdpack over 3 years@Kalanka maybe ask a new question for it? And link back to it here.;. :)
-
sjakovac over 2 yearsYou're missing
init()
or other custom initialization method between steps 5 and 6