¿Por qué usar @PostConstruct?

En un bean administrado, se llama a @PostConstruct después del constructor de objetos Java @PostConstruct .

¿Por qué debería usar @PostConstruct para inicializar por bean, en lugar del propio constructor normal?

  • porque cuando se llama al constructor, el bean aún no se ha inicializado, es decir, no se han inyectado dependencias. En el método @PostConstruct , el bean está totalmente inicializado y puede usar las dependencias.

  • porque este es el contrato que garantiza que este método se invocará solo una vez en el ciclo de vida del frijol. Puede suceder (aunque poco probable) que un bean sea instanciado varias veces por el contenedor en su funcionamiento interno, pero garantiza que @PostConstruct se invocará solo una vez.

Las otras respuestas, especialmente la de @ Bozho, ya explicaron el problema principal (entre otros):

en un constructor, la inyección de las dependencias aún no se ha producido .

En caso de que alguien todavía tenga dudas sobre lo que esto significa, este es un ejemplo del mundo real que me acaba de pasar:

 public class Foo { @Inject Logger LOG; @PostConstruct public void fooInit(){ LOG.info("This will be printed; LOG has already been injected"); } public Foo() { LOG.info("This will NOT be printed, LOG is still null"); // NullPointerException will be thrown here } } 

Espero que ayude.

Si su clase realiza toda su inicialización en el constructor, entonces @PostConstruct es de hecho redundante.

Sin embargo, si su clase tiene sus dependencias inyectadas usando métodos setter, entonces el constructor de la clase no puede inicializar completamente el objeto, y algunas veces es necesario realizar una inicialización después de haber llamado a todos los métodos setter, de ahí el caso de uso de @PostConstruct .

Considere la siguiente situación:

 public class Car { @Inject private Engine engine; public Car() { engine.initialize(); } ... } 

Como el Automóvil tiene que ser instanciado antes de la inyección de campo, el motor del punto de inyección sigue siendo nulo durante la ejecución del constructor, lo que da como resultado una NullPointerException.

Este problema se puede resolver mediante la inyección de JSR-330 Dependency Injection para Java o las anotaciones comunes JSR 250 para la anotación del método Java @PostConstruct.

@PostConstruct

JSR-250 define un conjunto común de anotaciones que se ha incluido en Java SE 6.

La anotación PostConstruct se utiliza en un método que debe ejecutarse después de realizar la inyección de la dependencia para realizar cualquier inicialización. Este método DEBE invocarse antes de poner en servicio la clase. Esta anotación DEBE ser compatible con todas las clases que admitan la dependency injection.

JSR-250 Chap. 2.5 javax.annotation.PostConstruct

La anotación @PostConstruct permite la definición de métodos que se ejecutarán después de que la instancia se haya instanciado y se hayan realizado todas las inyecciones.

 public class Car { @Inject private Engine engine; @PostConstruct public void postConstruct() { engine.initialize(); } ... } 

En lugar de realizar la inicialización en el constructor, el código se mueve a un método anotado con @PostConstruct.

El procesamiento de los métodos post-construcción es una simple cuestión de encontrar todos los métodos anotados con @PostConstruct e invocarlos sucesivamente.

 private void processPostConstruct(Class type, T targetInstance) { Method[] declaredMethods = type.getDeclaredMethods(); Arrays.stream(declaredMethods) .filter(method -> method.getAnnotation(PostConstruct.class) != null) .forEach(postConstructMethod -> { try { postConstructMethod.setAccessible(true); postConstructMethod.invoke(targetInstance, new Object[]{}); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new RuntimeException(ex); } }); } 

El procesamiento de los métodos posteriores a la construcción debe realizarse después de completar la instanciación e inyección.

Además, la inicialización basada en el constructor no funcionará según lo previsto siempre que se trate de algún tipo de proxying o remoting.

Se llamará a la ct siempre que se deserialice un EJB, y siempre que se cree un nuevo proxy para ello …