现在,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) {// bootstraporg.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的会话和请求范围 。
相关文章 :
- Spring Singleton,请求,会话Bean和线程安全
- 什么是CDI,它与@EJB和Spring有什么关系?
- Java EE6 CDI,命名组件和限定符
- Java EE6装饰器:在注入时装饰类
- Java EE6事件:JMS的轻量级替代品
翻译自: https://www.javacodegeeks.com/2012/01/simulating-cdis-session-and-request.html