When using frameworks that manage the lifecycle of your classes, such as Spring, it is always important to understand that a framework-managed instance is not an 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 NullPonterException
on line meuDao.atualizarBanco()
, since the meuDao
attribute will be null.
A normal object is not managed by Spring.
So whenever you use a Spring Bean you should let Spring give you the instance, either through annotation, injection through XML, etc.
Builder vs. Post-Builder
When Spring starts the context ( Spring Context ), which contains all the beans, it creates instances of the beans annotated or declared in the configuration, processes the notes, injects the dependencies and a few more things.
After properly initializing everything, it calls the method that is annotated with @PostConstruct
.
Note that at the time the instance is created, nothing is injected or initialized.
So the code below would also result in a NullPointerException
:
@Service
public class MeuServico {
@Autowired MeuDao meuDao;
public MeuServico() {
meuDao.iniciarAlgumaCoisaNoBanco();
}
}
See, Spring will not be able to inject meuDao
before instantiating the class. So 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-builder, which allows you to perform some action right after the Spring startup, but before the system performs some user action.