annotation - post construct java
¿Por qué no se llama PostConstruct? (4)
Estoy trabajando en una aplicación Java EE simple.
Tengo clase como esta:
import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
@Stateless
public class BlogEntryDao {
EntityManager em;
@PostConstruct
public void initialize(){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("Persistence");
em = emf.createEntityManager();
}
public void addNewEntry(){
Blogentry blogentry = new Blogentry();
blogentry.setTitle("Test");
blogentry.setContent("asdfasfas");
em.persist(blogentry);
}
}
Así que mi bean gestionado llama a este método. Hasta aquí no hay problemas. Pero como no se llama al método de inicialización, obtengo un NPE en em.persist .
¿Por qué no se llama al método de inicialización? Estoy ejecutando esto en el servidor Glassfish.
Saludos.
Dado que esta pregunta aparece primero en Google para "postconstruct not @PostConstruct
", otra razón por la que no se puede llamar a un método @PostConstruct
además de usar la new
palabra clave en lugar de poner @PostConstruct
en un bean Spring es si tiene una dependencia circular.
Si este bean dependiera de otro bean que dependiera de este bean, su otro bean podría llamar addNewEntry()
antes de que se BlogEntryDao
, aunque BlogEntryDao es una dependencia para ese otro bean.
Esto se debe a que Spring no sabía qué bean quería cargar primero debido a la referencia circular. En este caso, se puede eliminar la referencia circular o usar los parámetros del constructor @AutoWired
/ @Value
lugar de los valores de los miembros o los establecedores, o si usa la configuración xml, tal vez pueda intercambiar el orden en el que se definen los beans.
En mi caso, no se llamó a @PostConstruct porque mi método initialize () era estático y también lanzaba una excepción. En cualquier caso, el método se ignora. Espero que ayude a alguien que haya cometido el mismo error. Esto se puede encontrar en la consola:
WARNING: JSF1044: Method ''<XXX>'' marked with the ''javax.annotation.PostConstruct'' annotation cannot be static. This method will be ignored.
WARNING: JSF1047: Method ''<XXX>'' marked with the ''javax.annotation.PostConstruct'' annotation cannot declare any checked exceptions. This method will be ignored.
Las anotaciones del bean Java EE, como @PostConstruct
solo se aplican a los beans administrados por contenedor. Si simplemente llama new BlogEntryDao
mismo a new BlogEntryDao
, el contenedor no interceptará la creación y llamará al método @PostConstruct
.
(Además, sería mejor usar @PersistenceContext
o @PersistenceUnit
lugar de buscar manualmente el EntityManagerFactory
en su método initialize()
, y debería crear un EntityManager
para cada llamada a addNewEntry()
, ya que son de corta duración. Hacer estos cambios eliminaría la necesidad de initialize()
en absoluto.
Tuve el mismo problema en mi aplicación. No publicó su archivo xml de configuración de contexto de bean (así que no estoy seguro de si es el mismo problema) pero en mi caso, agregando esta línea:
<context:annotation-config/>
Resolví mi problema. Necesita <context:annotation-config/>
o <context:component-scan/>
para habilitar la anotación @PostConstruct.