`

jee6 学习笔记 6.1 - Singleton EJB

    博客分类:
  • JEE
阅读更多
The idea of the test is to print the instance of the singleton ejb for different requests. The singleton ejb is referenced in the request scoped backing bean.

the screen shot of the test page:




the page: "/tst/testSingleton.xhtml"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    
<h:head>
    <title>Test EJB3.1 @Singleton</title>
</h:head>

<h:body>
	<h:form>
	    <p:panel header="Test EJB3.1 @Singleton" toggleable="true" style="width:60%">
	    	<h:panelGrid columns="1">
	        	Click "Test" to see if it's the same instance:
	        	<h:outputText id="out" value="#{st.message}" escape="false"/>
	        </h:panelGrid>
	        <p:separator/>
	        <p:commandButton value="Test" action="#{st.test}" update="out"/>
	        <p:spacer width="7"/>
	        <p:commandButton value="Clear" actionListener="#{st.reset}" update="out"/>
	    </p:panel>
    </h:form>
</h:body>
</html>


the backing bean
package com.jxee.action.test.ejb31;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import org.apache.log4j.Logger;

import com.jxee.ejb.test.singleton.SingletonEJB;

@ManagedBean(name="st")
@RequestScoped
public class SingletonTestBean implements Serializable {

  @EJB // inject the singleton ejb
  private SingletonEJB single;
  
  // the message to build up and display. this is a bit over kill anyway.
  private static final AtomicReference<StringBuffer> message = new AtomicReference<StringBuffer>();
  
  // this backing bean instances counter
  private static final AtomicInteger beanCount = new AtomicInteger();
  
  private static final Logger log = Logger.getLogger(SingletonTestBean.class);

  
  @PostConstruct
  public void init() {
    log.debug(String.format(">>> PostConstruct: backing bean inited: %s", this));
  }
  
  public String getMessage() {
    return message.get() != null ? message.get().toString() : "";
  }

  private void buildMessge(String toappend, boolean reset) {
    StringBuffer newmsg = new StringBuffer();
    while(true) {
      StringBuffer oldmsg = message.get();
      if(!reset) {
        if(oldmsg != null) {
          newmsg.append(oldmsg);
        }
        if(toappend != null) {
          newmsg.append(toappend);
        }
      }
      if(message.compareAndSet(oldmsg, newmsg)) {
        log.debug(">>> new message appended ok");
        return;
      }
    }
  }
  
  public String test() {
    StringBuffer newmsg = new StringBuffer();
    newmsg.append("----- request arrived(sec): ")
          .append(new Date().getTime()/1000)
          .append("<br/> >>> the backing bean [")
          .append(beanCount.incrementAndGet()).append("]: ").append(this)
          .append("<br/> >>> the singleton ejb: ")
          .append(this.single.getInstance())
          .append("<br/>");
    this.buildMessge(newmsg.toString(), false);
    return null;
  }
  
  public void reset() {
    this.buildMessge(null, true);
  }
}


the singleton ejb:
package com.jxee.ejb.test.singleton;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;

import org.apache.log4j.Logger;

@Singleton
public class SingletonEJB {
  
  private static final Logger log = Logger.getLogger(SingletonEJB.class);
  
  @PostConstruct
  public void init() {
    log.debug(">>> PostConstruct: SingletonEJB");
  }
  
  public String getInstance() {
    return this.toString();
  }
}



Now take a look at concurrency control of singleton session beans.

The the container makes sure that singleton session bean can only instantiate once. But the @Singleton does not say anything about concurrency control. JEE 6 has annotations to address this issue: @ConcurrencyManagement and @Lock.

@ConcurrencyManagement applies to the singleton class and has too options ConcurrencyManagementType.CONTAINER(default) and ConcurrencyManagementType.BEAN.

When using the default, annotation @Lock(LockType.READ | LockType.WRITE) can be used to further control the access levels of shared data.

package com.jxee.ejb.test.singleton;

import javax.annotation.PostConstruct;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;

import org.apache.log4j.Logger;


/**
 * Test @Singleton session ejb.
 * 
 * ConcurrencyManagementType.CONTAINER is the default concurrency control.
 * Under container managed concurrency control, @Lock(LockType) can be used
 * to define READ/WRITE access types.
 * 
 * Alternative is ConcurrencyManagementType.BEAN. With this option, the bean
 * developer has to provide control over concurrent accesses to shared data.
 * Therefore, you can use keyword "synchronized" etc, and i guess, the classes
 * in package "java.util.concurrent".
 */
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) // the default
@Singleton
public class SingletonEJB {
  
  private static final Logger log = Logger.getLogger(SingletonEJB.class);
  
  private static Integer counter = new Integer(1);
  
  @PostConstruct
  public void init() {
    log.debug(">>> PostConstruct: SingletonEJB inited");
  }
  
  /**
   * LockType.READ: For read-only operations. Allows simultaneous access 
   * to methods designated as READ, as long as no WRITE lock is held. 
   */
  @Lock(LockType.READ)
  public Integer getCounter() {
    return counter;
  }

  /**
   * LockType.WRITE: For exclusive access to the bean instance. 
   * A WRITE lock can only be acquired when no other method with 
   * either a READ or WRITE lock is currently held. 
   */
  @Lock(LockType.WRITE)
  public void setCounter(Integer c) {
    counter = c;
  }
  
  /**
   * a convenience method
   */
  @Lock(LockType.WRITE)
  public void increment() {
    counter++;
  }
  
  public String getInstance() {
    return this.toString();
  }
}



结论:

We can see from the result that the container instantiated different backing bean instance for each request, but the injected singleton ejb was always the same instance. So we can say that the @Singleton does its trick.

The singleton EJB has all the ejb services available. It can be used to maintain application wide state, such as caching application static data, i suppose?

  • 大小: 42.9 KB
分享到:
评论

相关推荐

    开发工具 eclipse-jee-mars-2-win32

    开发工具 eclipse-jee-mars-2-win32开发工具 eclipse-jee-mars-2-win32开发工具 eclipse-jee-mars-2-win32开发工具 eclipse-jee-mars-2-win32开发工具 eclipse-jee-mars-2-win32开发工具 eclipse-jee-mars-2-win32...

    eclipse-jee-mars-1-win32-x86_64.7z

    eclipse-jee-mars-1-win32-x86_64.7z eclipse-jee-mars-1-win32-x86_64.zip 我打的 7z 压缩包 关于有 Alt + / 不起作用解决办法: window -&gt; General -&gt; Keys -&gt; Content Assist -&gt; Binding: 改为 Alt + / When:...

    jee6 学习笔记 6.3 - @Asynchronous

    `@Asynchronous`是Java EE 6引入的EJB 3.1规范的一部分,它可以应用在无状态会话bean(Stateless Session Bean)的方法上。当一个带有`@Asynchronous`的方法被调用时,调用者会立即返回,而实际的方法执行将在另一...

    eclipse-jee-2023-09-R-linux-gtk-x86-64.tar.gz

    "eclipse-jee-2023-09-R-linux-gtk-x86_64.tar.gz" 文件是Eclipse专为Java企业版(Java EE)开发者设计的2023年9月版本,适用于64位的Linux操作系统。这个版本包含了对Java EE开发所需的全部工具和功能,如Web服务器...

    eclipse-jee-2022-06-R-win32-x86_64.zip

    在解压eclipse-jee-2022-06-R-win32-x86_64.zip后,我们会得到一个名为“eclipse”的文件夹,这个文件夹包含了整个IDE的所有组件和配置。启动Eclipse IDE,用户会看到熟悉的界面,包括工作区(Workspace)、透视图...

    eclipse-jee-2021-12-R-win32-x86_64

    eclipse-jee-2021-12-R-win32-x86_64 eclipse-jee-2021-12-R-win32-x86_64 eclipse-jee-2021-12-R-win32-x86_64

    eclipse-jee-neon-1a-win_64

    eclipse-jee-neon-1a-win_64

    eclipse-jee-2020-09-R-win32-x86_64.zip

    标题中的“eclipse-jee-2020-09-R-win32-x86_64.zip”指的是Eclipse IDE for Java EE Developers的2020年9月版本,适用于Windows 32位和64位系统的安装包。Eclipse是一款著名的开源集成开发环境(IDE),广泛用于...

    eclipse-jee-2023-06-R-win32-x86-64.zip

    在Eclipse JEE版本中,这些功能得到了进一步增强,特别是对于Java EE应用程序的开发,如Web服务、Java服务器页面(JSP)、JavaServer Faces(JSF)以及Enterprise JavaBeans(EJB)等,提供了全面的工具集和模板。...

    eclipse-jee-2018-09-win32-x86_64.zip

    标题 "eclipse-jee-2018-09-win32-x86_64.zip" 提供的信息表明这是一款针对Java企业级开发的Eclipse集成开发环境(IDE)的2018年9月版本,适用于Windows 32位操作系统、x86_64架构的计算机。Eclipse是一个开源的、跨...

    eclipse-jee-2020-12-R-win32-x86_64

    《Eclipse IDE for Java开发者:深入解析eclipse-jee-2020-12-R-win32-x86_64》 Eclipse IDE,全称集成开发环境(Integrated Development Environment),是全球广泛使用的开源Java开发工具。该版本"eclipse-jee-...

    eclipse-jee-2021-12-R-win32-x86_64.zip

    Eclipse IDE for Enterprise Java and Web Developers (eclipse-jee-2021-12-R-win32-x86_64.zip)适用于Windwos x86_64

    eclipse-jee-mars-R-win32-x86_64位官方绿色版.zip

    Eclipse-jee-mars-R-win32-x86_64位官方绿色版.zip是一个针对Windows平台的64位版本的Eclipse集成开发环境(IDE)的压缩包,特别为Java企业级(J2EE)应用程序开发设计。该版本发布于2015年6月30日,是当时Eclipse ...

    jee6 学习笔记 5 - Struggling with JSF2 binding GET params

    这篇"jee6 学习笔记 5 - Struggling with JSF2 binding GET params"主要探讨了开发者在使用JSF2绑定GET参数时可能遇到的挑战和解决方案。 JSF2是一个基于MVC(模型-视图-控制器)设计模式的Java框架,用于创建交互...

    eclipse-jee-2023-09-R-macosx-cocoa-x86-64.dmg

    eclipse-jee-2023-09-R-macosx-cocoa-x86_64.dmg 适用于macOS Intel芯片系统

    eclipse-jee-oxygen-3-win32.rar

    "eclipse-jee-oxygen-3-win32.rar" 是一个针对Windows 32位系统的Eclipse版本,专为Java企业级开发(JEE)设计。这个版本是Eclipse Oxygen系列的第三个发布版,它包含了众多开发者所需的工具和特性,旨在提升开发...

    eclipse-jee-2019-03-R-win32-x86-64.zip

    Eclipse-JEE-2019-03-R-win32-x86-64.zip 是一个专门为Windows 64位系统设计的Eclipse版本,包含了Web开发所需的插件。 这个版本是2019年的第三个发布版(Release),通常每个版本都会带来性能优化、新功能和修复...

    eclipse-jee-2022-09-R-win32-x86-64.zip

    开始使用Eclipse JEE 2022-09 R,首先需要下载"eclipse-jee-2022-09-R-win32-x86_64.zip"压缩包,解压后运行“eclipse.exe”。初次启动,用户需要配置工作空间,选择Java开发工具,以及根据项目需求添加服务器...

    jee6 学习笔记 1 - 开发环境的配置

    NULL 博文链接:https://jxee.iteye.com/blog/1575432

    eclipse-jee-oxygen-R-win32.7z.003

    eclipse-jee-oxygen-R-win32.7z.003

Global site tag (gtag.js) - Google Analytics