在J2SE应用程序中模拟CDI的会话和请求范围

我们目前正在考虑将Naked Objects框架重构为使用JSR-330(依赖注入)和面向EE的老大哥JSR-299(CDI)。 使用香草JSR-330是不费吹灰之力的,但是我们想利用JSR-299中的一些不错的功能(例如事件和装饰器)。 障碍? 裸对象还必须在J2SE环境中透明运行。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值