Jun*_*aid 5 jsf scope managed-bean
我有2个JSF托管bean A
,B
我需要A
在2分钟B
后和5分钟后过期/销毁/销毁.我检查了这个相关的问题,从一个bean中定时,但是整个会话到期了.我不想让整个会话到期.
如何使用自定义范围实现此目的?
鉴于您正在使用JSF bean管理工具(因此不需要CDI,这需要完全不同的答案),您可以实现此目的@CustomScoped
.该@CustomScoped
值必须引用Map
更广泛的,通常存在的范围中的实现.
就像是:
@ManagedBean
@CustomScoped("#{timeoutScope}")
public class TimeoutBean {}
Run Code Online (Sandbox Code Playgroud)
由于@CustomScoped
注释不支持传递其他参数,因此只能通过下面的其他自定义注释来设置超时:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Timeout {
/** Minutes. */
int value();
}
Run Code Online (Sandbox Code Playgroud)
@ManagedBean
@CustomScoped("#{timeoutScope}")
@Timeout(5) // Expires after 5 minutes.
public class TimeoutBean {}
Run Code Online (Sandbox Code Playgroud)
现在,这是一个启动示例#{timeoutScope}
,包括@PostConstruct
支持(自动)和@PreDestroy
支持(手动):
@ManagedBean
@SessionScoped
public class TimeoutScope extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
@Override
public Object put(String name, Object bean) {
Timeout timeout = bean.getClass().getAnnotation(Timeout.class);
if (timeout == null) {
throw new IllegalArgumentException("@Timeout annotation is required on bean " + name);
}
Long endtime = System.nanoTime() + (timeout.value() * (long) 6e10);
Object[] beanAndEndtime = new Object[] { bean, endtime };
return super.put(name, beanAndEndtime);
}
@Override
public Object get(Object key) {
Object[] beanAndEndtime = (Object[]) super.get(key);
if (beanAndEndtime == null) {
return null;
}
Object bean = beanAndEndtime[0];
Long endtime = (Long) beanAndEndtime[1];
if (System.nanoTime() > endtime) {
String name = (String) key;
ScopeContext scope = new ScopeContext("timeoutScope", Collections.singletonMap(name, bean));
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().publishEvent(context, PreDestroyCustomScopeEvent.class, scope);
return null;
}
return bean;
}
}
Run Code Online (Sandbox Code Playgroud)
你看,它的会话范围和实现Map
.至于范围,这种方式与特定用户会话相关联,而不是与整个应用程序相关联.如果您确实想要在应用程序中的所有用户会话中共享bean,那么请将其作为应用程序作用域.至于,当Map
JSF需要找到托管bean时,它首先尝试get()
.如果它返回null
(即bean还不存在),那么它将自动创建托管bean实例并执行put()
.
在内部put()
,这是提取和计算超时并将其存储在地图中的问题.在内部get()
,您只需检查超时并返回null
以指示JSF该bean不再存在.然后,JSF将自动创建它并返回put()
,等等.
请注意我使用System#nanoTime()
而不是System#currentTimeMillis()
因为后者与操作系统(操作系统)时间相关,而不是硬件时间(因此它对于DST和最终用户控制的时间变化敏感).
归档时间: |
|
查看次数: |
1145 次 |
最近记录: |