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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:56:06  来源:igfitidea点击:

Why is PostConstruct not called?

javajakarta-eeejb

提问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 @PostConstructonly apply to container-managed beans. If you are simply calling new BlogEntryDaoyourself, the container isn't going to intercept the creation and call the @PostConstructmethod.

Java EE bean 注释@PostConstruct仅适用于容器管理的 bean。如果您只是调用new BlogEntryDao自己,则容器不会拦截创建并调用该@PostConstruct方法。

(Furthermore, you'd be better off using @PersistenceContextor @PersistenceUnitinstead of manually fetching the EntityManagerFactoryin your initialize()method, and you should be creating an EntityManagerfor each call to addNewEntry(), since they're short-lived. Making these changes would eliminate the need for initialize()at all.)

(此外,您最好在方法中使用@PersistenceContext@PersistenceUnit而不是手动获取,并且您应该为每次调用创建,因为它们是短暂的。进行这些更改将完全不需要。 )EntityManagerFactoryinitialize()EntityManageraddNewEntry()initialize()

回答by Alexander Taylor

Since this question comes up first on Google for "postconstruct not called", another reason a @PostConstructmethod might not be called besides using the newkeyword instead of putting @PostConstructin a Spring bean is if you have a circular dependency.

由于这个问题首先出现在 Google 上,因为“未调用 postconstruct”,因此@PostConstruct除了使用new关键字而不是放入@PostConstructSpring bean之外,可能不会调用方法的另一个原因是,如果您有循环依赖。

If this bean were to depend on another bean that depended on this bean, your other bean might call addNewEntry()before BlogEntryDaowas 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/@Valueconstructor 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.