现在,JSR-299(至少是Weld参考实现)可以在J2SE上运行,但是不可能使用标注为@SessionScoped或@RequestScoped的bean…确实不足为奇,因为没有HttpSession或HttpServletRequest钩入。 另一方面,至少在J2SE上下文中的Naked Objects框架中,我们确实能够将这些概念映射到其自身的内部生命周期中……例如,对于客户端应用程序,用户始终被视为正在运行在一个长时间的会议上。
那么,如何为这些作用域设置上下文,并使其在J2SE中运行时自动激活?
首先,让我们看一下我们要运行的代码:
package org.nakedobjects.experiments.cdi;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
import org.jboss.weld.environment.se.bindings.Parameters;
import org.jboss.weld.environment.se.events.ContainerInitialized;
@RequestScoped
public class HelloWorld {
public static void main(String[] args) {
// bootstrap
org.jboss.weld.environment.se.StartMain.main(new String[]{"JSR","299"});
}
public void printHello(@Observes ContainerInitialized event, @Parameters List<String> args) {
System.out.println("Hello " + args);
System.out.flush();
}
}
因为这是CDI bean,所以我们需要一个空的META-INF / beans.xml。
如果将上述类注释为@ApplicationScoped ,则将打印出“ Hello [JSR,299]”,但不会将其注释为@RequestScoped 。 因此,我们需要做的是编写扩展。 这有点hacky,但是可以用:
package org.jboss.weld.manager; // required for visibility to BeanManagerImpl#getContexts()
import java.lang.annotation.Annotation;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import org.jboss.weld.context.AbstractThreadLocalMapContext;
import org.jboss.weld.context.beanstore.HashMapBeanStore;
public class WeldServletScopesSupportForSe implements Extension {
public void afterDeployment(@Observes AfterDeploymentValidation event,
BeanManager beanManager) {
setContextActive(beanManager, SessionScoped.class);
setContextActive(beanManager, RequestScoped.class);
}
private void setContextActive(BeanManager beanManager,
Class<? extends Annotation> cls) {
BeanManagerImpl beanManagerImpl = (BeanManagerImpl) beanManager;
AbstractThreadLocalMapContext context = (AbstractThreadLocalMapContext) beanManagerImpl
.getContexts().get(cls).get(0);
context.setBeanStore(new HashMapBeanStore());
context.setActive(true);
}
}
像所有Weld扩展一样,它需要在META-INF / services中注册,在这种情况下, 应包含在包含完整类名的名为javax.enterprise.inject.spi.Extension的文件中。
现在,当我们运行应用程序时,将同时设置会话和请求范围,并且将触发我们的HelloWorld bean。
对于在Naked Objects中编写应用程序的开发人员,如果在非Web后端(例如,具有套接字级远程处理的-t服务器)上部署客户端( -t客户端或服务器),则他们需要包括对其他模块的依赖。后者,我们将需要包括一些技巧来弄清楚我们是否在Web应用程序中运行,并且仅在我们确定自己不在上下文中时才设置Context(例如,无法在Webapp上找到javax.servlet类)。类路径。
如果您想尝试一下代码,可以使用
svn co https://nakedobjects.svn.sourceforge.net/svnroot/nakedobjects/framework/trunk/experiments .
参考: Dan Haywood博客上的JCG合作伙伴 Dan Haywood在J2SE应用程序中模拟了CDI的会话和请求范围 。
相关文章 :
翻译自: https://www.javacodegeeks.com/2012/01/simulating-cdis-session-and-request.html