現在,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