Java 为什么不调用 PostConstruct?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18161682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is PostConstruct not called?
提问by Koray Tugay
I am working on a simple Java EE application.
我正在开发一个简单的 Java EE 应用程序。
I have class like this:
我有这样的课:
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);
}
}
So my managed bean calls this method. Until here no problems. But since the initialize method is not called, I am getting an NPE in em.persist.
所以我的托管 bean 调用了这个方法。直到这里没有问题。但是由于没有调用 initialize 方法,所以我在em.persist 中得到了一个 NPE 。
Why is the initialize method not being called? I am running this on Glassfish server.
为什么没有调用 initialize 方法?我在 Glassfish 服务器上运行它。
Regards.
问候。
采纳答案by chrylis -cautiouslyoptimistic-
The Java EE bean annotations such as @PostConstruct
only apply to container-managed beans. If you are simply calling new BlogEntryDao
yourself, the container isn't going to intercept the creation and call the @PostConstruct
method.
Java EE bean 注释@PostConstruct
仅适用于容器管理的 bean。如果您只是调用new BlogEntryDao
自己,则容器不会拦截创建并调用该@PostConstruct
方法。
(Furthermore, you'd be better off using @PersistenceContext
or @PersistenceUnit
instead of manually fetching the EntityManagerFactory
in your initialize()
method, and you should be creating an EntityManager
for each call to addNewEntry()
, since they're short-lived. Making these changes would eliminate the need for initialize()
at all.)
(此外,您最好在方法中使用@PersistenceContext
或@PersistenceUnit
而不是手动获取,并且您应该为每次调用创建,因为它们是短暂的。进行这些更改将完全不需要。 )EntityManagerFactory
initialize()
EntityManager
addNewEntry()
initialize()
回答by Alexander Taylor
Since this question comes up first on Google for "postconstruct not called", another reason a @PostConstruct
method might not be called besides using the new
keyword instead of putting @PostConstruct
in a Spring bean is if you have a circular dependency.
由于这个问题首先出现在 Google 上,因为“未调用 postconstruct”,因此@PostConstruct
除了使用new
关键字而不是放入@PostConstruct
Spring bean之外,可能不会调用方法的另一个原因是,如果您有循环依赖。
If this bean were to depend on another bean that depended on this bean, your other bean might call addNewEntry()
before BlogEntryDao
was initialized, even though BlogEntryDao is a dependency for that other bean.
如果此 bean 依赖于另一个依赖此 bean 的 bean,则您的另一个 bean 可能会addNewEntry()
在BlogEntryDao
初始化之前调用,即使 BlogEntryDao 是该其他 bean 的依赖项。
This is because Spring didn't know which bean you wanted to load first due to the circular reference. In this case, one can remove the circular reference or use @AutoWired
/@Value
constructor parameters instead of member values or setters, or if using xml configuration, maybe you can swap the order in which the beans are defined.
这是因为由于循环引用,Spring 不知道您要首先加载哪个 bean。在这种情况下,可以删除循环引用或使用@AutoWired
/@Value
构造函数参数代替成员值或 setter,或者如果使用 xml 配置,也许您可以交换定义 bean 的顺序。
回答by Tomasz Kubiak
I had the same problem in my application. You didn't post your bean context configuration xml file (so I'm not sure if it's the same issue) but in my case adding this line:
我在我的应用程序中遇到了同样的问题。你没有发布你的 bean 上下文配置 xml 文件(所以我不确定它是否是同样的问题)但在我的情况下添加这一行:
<context:annotation-config/>
Solved my problem.
You need either <context:annotation-config/>
or <context:component-scan/>
to enable @PostConstruct annotation.
解决了我的问题。您需要<context:annotation-config/>
或<context:component-scan/>
启用@PostConstruct 注释。
回答by divaylo
In my case @PostConstruct was not called because my initialize() method was static and was also throwing an exception. In either case the method is ignored. I hope it helps someone else who made the same mistake. This can be found in the console:
在我的例子中,@PostConstruct 没有被调用,因为我的 initialize() 方法是静态的并且也抛出了异常。在任何一种情况下,都会忽略该方法。我希望它可以帮助犯同样错误的其他人。这可以在控制台中找到:
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.