Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @PostConstruct vs. init-method attribute

Tags:

spring

People also ask

What does @PostConstruct do in spring?

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.

Is @PostConstruct deprecated?

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

What is the @PostConstruct annotation used for?

Annotation Type PostConstruct 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.

What can I use instead of PostConstruct?

We can replace @PostConstruct with BeanFactoryPostProcessor and PriorityOrdered interface. The first one defines an action that ought to be executed after the object's instantiation. The second interface tells the Spring the order of the component's initialization.


No practically I don't think there is any difference but there are priorities in the way they work. @PostConstruct, init-method are BeanPostProcessors.

  1. @PostConstruct is a JSR-250 annotation while init-method is Spring's way of having an initializing method.
  2. If you have a @PostConstruct method, this will be called first before the initializing methods are called.
  3. If your bean implements InitializingBean and overrides afterPropertiesSet , first @PostConstruct is called, then the afterPropertiesSet and then init-method.

For more info you can check Spring's reference documentation.

Before JSR 250 specs , usage of init-method in xml was preferred way , as it decouples java classes (beans) from any spring specific classes/annotations.So if you are building a library that does not need to be dependent on spring infrastructure beans then use of init-method was preferred.During creation method u can specify the method that needs to be called as initialization method.

Now with introduction of JSR 250 specs in Java EE and spring support of these annotations , dependency on spring framework has been reduced to a certain extent.

But i have to admit that addition of these things increase the readability of code.So there are pros and cons both approaches.


There's no real difference. It's down to how you prefer to configure your system, and that's a matter of personal choice. Myself, I prefer to use @PostConstruct annotations for my own code (as the bean is only correctly configured after the method is called) and I use init-method when instantiating beans from non-Spring-aware libraries (can't apply annotations there, of course!) but I can totally understand people wanting to do it all one way or the other.


Full code here: https://github.com/wkaczurba/so8519187 (spring-boot)

Using annotations:

@Slf4j
@Component
public class MyComponent implements InitializingBean {

    @Value("${mycomponent.value:Magic}")
    public String value;

    public MyComponent() {
        log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
    }

    @PostConstruct
    public void postConstruct() {
        log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
    }

    @Override // init-method; overrides InitializingBean.afterPropertiesSet()
    public void afterPropertiesSet() {
        log.info("MyComponent in afterPropertiesSet: [{}]", value);  // (2) displays: Magic
    }   

    @PreDestroy
    public void preDestroy() {
        log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
    }
}

Gets us:

Refreshing org.springframework.context...

MyComponent in constructor: [null]
MyComponent in postConstruct: [Magic]
MyComponent in afterPropertiesSet: [Magic]
...

Registering beans for JMX exposure on startup
Started DemoApplication in 0.561 seconds (JVM running for 1.011)
Closing org.springframework.context... Unregistering JMX-exposed beans on shutdown

...
MyComponent in preDestroy: [Magic]


@postconstruct is not part of the spring. It is part of javax package. Both are the same. using init-method we need to added in xml file.If you use @postconstruct adding in xml is not required. Check out the below article .

http://answersz.com/spring-postconstruct-and-predestroy/


As you can see in the below diagram of Bean Creation Life-Cycle Callback.

Bean Creation Life-Cycle Callback

This 3 step happens in the Bean Creation Life-Cycle Callback:

  1. It is mentioned that @PostConstruct will be called.
  2. If InitializingBean is implemented, then afterPropertiesSet() will be called.
  3. If bean definition contains init-method or @Bean(initmethod="..") then it calls the init method.

This diagram is from Pro Spring 5: An In-Depth Guide to the Spring Framework and Its Tools