What is the difference between @Postconstruct and the constructor?

Asked

Viewed 10,051 times

9

What’s the difference of using the annotation @PostConstruct instead of using constructor method and its advantages? I ask based on these two versions of the same class that only differ by this annotation.

Before

@Repository
public class OldValidacaoDAO {

    MongoCollection mongoCollection;

    public OldValidacaoDAO() {
        this.mongoCollection = DBSingleton.getJongo().getCollection("validacao_validacoes");
    }
}

Afterward

@Repository
public class ValidacaoDAO {

    MongoCollection mongoCollection;

    @PostConstruct
    public void init(){
        this.mongoCollection = DBSingleton.getJongo().getCollection("validacao_validacoes");
    }

}

1 answer

7


When using frameworks that manage the lifecycle of your classes, as is the case with Spring, it is always important to understand that an instance managed by the framework is not just any instance.

An instance managed by Spring is called Spring Bean and is not a common object. He now has superpowers.

Common Instance vs. Spring Bean

Consider the following class:

@Service
public class MeuServico {

    @Autowired MeuDao meuDao;

    public void acao() {
       meuDao.atualizarBanco();
    }

}

What happens if you create the class manually?

MeuServico meuServico = new MeuServico();
meuServico.acao();

The result will be a NullPonterException on the line meuDao.atualizarBanco(), for the attribute meuDao will be void.

A normal object is not managed by Spring.

So whenever you wear one Spring Bean you should let Spring deliver you the instance, whether through an annotation, injection through XML, etc.

Constructor vs. Post-constructor

When Spring starts context (Spring Context), which contains all the Beans, it creates instances of the Beans annotated or declared in configuration, processes annotations, injects dependencies and some more.

After properly initializing everything, it calls the method that is annotated with @PostConstruct.

Note that at the moment the instance is created, there is nothing injected or initialized.

Therefore, the code below would also result in a NullPointerException:

@Service
public class MeuServico {

    @Autowired MeuDao meuDao;

    public MeuServico() {
       meuDao.iniciarAlgumaCoisaNoBanco();
    }

}

Look, Spring won’t be able to inject meuDao before instantiating the class. Therefore in any framework it is not possible to inject the dependency or do anything else in the class before calling some constructor.

The solution is to use the post-constructor, which then allows you to perform some action right after Spring startup, but before the system performs some user action.

  • 1

    This suggested edition in his reply, which in my view was correct, was rejected. I think it is something pertinent to take to the goal, don’t you think? http://answall.com/review/suggested-edits/28277

  • I don’t understand why a class called a service is a repository.

  • @Danielamarquesdemorais In my opinion its edition was valid and was rejected unfairly. The service should have @Service and the repository @Repository.

  • @Danielamarquesdemorais The edition was correct. The old note was a mess of mine because at first I copied your question code, but then I decided to modify it to improve the example and forgot to update the annotation.

  • @Victorstafusa editions can not change the meaning of the author’s response. In that case it is best to leave comment. The author may have a different idea than you. This edition is being discussed in the goal: http://meta.pt.stackoverflow.com/questions/2651/comor-lidar-com-usu%C3%A1rio-que-rejeita-Edi%C3%A7%C3%B5es-corretas

Browser other questions tagged

You are not signed in. Login or sign up in order to post.