如何强制应用程序范围的bean在应用程序启动时实例化? [英] How do I force an application-scoped bean to instantiate at application startup?

查看:127
本文介绍了如何强制应用程序范围的bean在应用程序启动时实例化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎找不到找到一种方法来强制在启动Web应用程序时实例化/初始化应用程序范围的托管Bean.似乎应用程序范围的Bean在第一次访问该Bean时就被延迟实例化,而不是在Web应用程序启动时被实例化.对于我的Web应用程序,这是在第一个用户首次在Web应用程序中打开页面时发生的.

I can't seem to find a way to force an application-scoped managed bean to be instantiated/initialized when the web app is started. It seems that application-scoped beans get lazy-instantiated the first time the bean is accessed, not when the web app is started up. For my web app this happens when the first user opens a page in the web app for the first time.

我想避免这种情况的原因是因为在我的应用程序范围的bean初始化期间发生了许多耗时的数据库操作.它必须从持久性存储中检索一堆数据,然后缓存一些将以ListItem元素等形式频繁显示给用户的数据.我不希望所有数据在第一个用户连接时发生,因此造成很长的延迟.

The reason I want to avoid this is because a number of time-consuming database operations happen during the initialization of my application-scoped bean. It has to retrieve a bunch of data from persistent storage and then cache some of it that will be frequently displayed to the user in the form of ListItem elements, etc. I don't want all that to happen when the first user connects and thus cause a long delay.

我的第一个想法是使用旧样式的ServletContextListener contextInitialized()方法,然后使用ELResolver手动请求我的托管bean的实例(从而强制进行初始化).不幸的是,由于ELResolver需要FacesContext并且FacesContext仅在请求的生命周期中存在,因此我无法在此阶段使用ELResolver来触发初始化.

My first thought was to use an old style ServletContextListener contextInitialized() method and from there use an ELResolver to manually request the instance of my managed bean (thus forcing the initialization to happen). Unfortunately, I can't use an ELResolver to trigger the initialization at this stage because the ELResolver needs a FacesContext and the FacesContext only exists during the lifespan of a request.

有人知道实现此目的的另一种方法吗?

Does anyone know of an alternate way to accomplish this?

我将MyFaces 1.2用作JSF实现,目前无法升级到2.x.

I am using MyFaces 1.2 as the JSF implementation and cannot upgrade to 2.x at this time.

推荐答案

我的第一个想法是使用旧样式的ServletContextListener contextInitialized()方法,然后使用ELResolver手动请求我的托管bean的实例(因此强制进行初始化).不幸的是,由于ELResolver需要FacesContext并且FacesContext仅在请求的生命周期中存在,因此我无法在此阶段使用ELResolver来触发初始化.

不必太复杂.只需实例化bean并将其放入相同受管bean名称作为关键字的应用程序范围中即可.当范围中已经存在JSF时,它将重用该bean.在Servlet API之上使用JSF的情况下,ServletContext代表应用程序范围(因为HttpSession代表会话范围,而HttpServletRequest代表请求范围,每个都有setAttribute()getAttribute()方法).

It doesn't need to be that complicated. Just instantiate the bean and put it in the application scope with the same managed bean name as key. JSF will just reuse the bean when already present in the scope. With JSF on top of Servlet API, the ServletContext represents the application scope (as HttpSession represents the session scope and HttpServletRequest represents the request scope, each with setAttribute() and getAttribute() methods).

这应该做,

public void contextInitialized(ServletContextEvent event) {
    event.getServletContext().setAttribute("bean", new Bean());
}

其中"bean"应该与faces-config.xml中应用程序范围的bean的<managed-bean-name>相同.

where "bean" should be the same as the <managed-bean-name> of the application scoped bean in faces-config.xml.

仅作记录,在JSF 2.x上,您要做的就是在@ApplicationScoped bean上将eager=true添加到@ManagedBean.

Just for the record, on JSF 2.x all you need to do is to add eager=true to @ManagedBean on an @ApplicationScoped bean.

@ManagedBean(eager=true)
@ApplicationScoped
public class Bean {
    // ...
}

然后它将在应用程序启动时自动实例化.

It will then be auto-instantiated at application startup.

或者,当您通过CDI @Named管理备用bean时,请抓住 OmniFaces

Or, when you're managing backing beans by CDI @Named, then grab OmniFaces @Eager:

@Named
@Eager
@ApplicationScoped
public class Bean {
    // ...
}

这篇关于如何强制应用程序范围的bean在应用程序启动时实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆