Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@PostConstruct spring does not get called without bean declaration

Why post construct does not get called without putting bean in applicationContext.xml

Here is my class which contains @PostConstruct annotation.

package org.stalwartz.config;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

@Singleton
public class PropertyLoader {

    @PostConstruct
    public void init() {
         System.out.println("PropertyLoader.init()");
    }
}

Below is my applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
 http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc.xsd 
 http://www.springframework.org/schema/tx 
 http://www.springframework.org/schema/tx/spring-tx.xsd 
 http://www.directwebremoting.org/schema/spring-dwr
 http://www.directwebremoting.org/schema/spring-dwr/spring-dwr-3.0.xsd">

<dwr:annotation-config />
<dwr:annotation-scan base-package="org.stalwartz" scanDataTransferObject="true" scanRemoteProxy="true" />
<dwr:url-mapping />

<!--  <bean id="proeprtyLoader" class="org.stalwartz.config.PropertyLoader"></bean>  -->

<dwr:controller id="dwrController" debug="false">
    <dwr:config-param name="activeReverseAjaxEnabled" value="true" />
</dwr:controller>

<context:annotation-config>
    <context:component-scan base-package="org.stalwartz" annotation-config="true"></context:component-scan>
</context:annotation-config>

<mvc:annotation-driven />
...
...
...
</beans>

Looks simple, but it does not work without uncommenting bean declaration.

like image 786
Jigar Naik Avatar asked Mar 29 '16 14:03

Jigar Naik


People also ask

When @PostConstruct is invoked?

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection.

Is @PostConstruct deprecated?

In jdk9 @PostConstruct and @PreDestroy are in java. xml. ws. annotation which is deprecated and scheduled for removal.

What is the use of @PostConstruct in spring boot?

When we annotate a method in Spring Bean with @PostConstruct annotation, it gets executed after the spring bean is initialized. We can have only one method annotated with @PostConstruct annotation. This annotation is part of Common Annotations API and it's part of JDK module javax.

How many times a @PostConstruct method is called?

2. @PostConstruct. Spring calls the methods annotated with @PostConstruct only once, just after the initialization of bean properties.


2 Answers

In Spring environment initialization callback method (the one annotated by @PostConstruct) make sense only on spring-managed-beans. To make instance(s) of your PropertyLoader class managed, you must do one of the following:

  1. Explicitly register your class in context configuration (as you did)
    <bean id="proeprtyLoader" class="org.stalwartz.config.PropertyLoader"></bean>
  2. Let component scanning do the work (as you nearly did), but classes must be annotated by one of @Component, @Repository, @Service, @Controller.

Note from Spring documentation: The use of <context:component-scan> implicitly enables the functionality of <context:annotation-config>. There is usually no need to include the <context:annotation-config> element when using <context:component-scan>.

like image 138
Lukas Risko Avatar answered Sep 29 '22 17:09

Lukas Risko


Because putting bean in applicationContext.xml you are adding bean to Spring container, which has interceptor for this annotation. When Spring inject beans it checks @PostConstruct annotation, between others.

When you call simple new PropertyLoader() JVM will not search for the @PostConstruct annotation.

From doc of @PostConstruct annotation:

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection. The method annotated with PostConstruct MUST be invoked even if the class does not request any resources to be injected.

like image 41
mommcilo Avatar answered Sep 29 '22 16:09

mommcilo