我可以在glassfish V3上拥有单一的生命周期webservice吗?

时间:2010-08-30 13:14:11

标签: web-services singleton glassfish lifecycle

我有一个使用Netbeans 6.5创建的简单Web服务,并部署到2个glassfish服务器 V2.1和V3 。 ws有一个基本方法GetInstanceID,我从客户端调用了3次。

@WebService()
public class FirstWS {

private long m_instanceID = 0;   //instance id

//Log
private void WriteLog(String cadena){
    String msg = "";
    DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss:SSS");
    Date fecha = new Date();
    msg = dateFormat.format(fecha) + " ***** " + this.getClass().getName() + " (m_instanceID=" + m_instanceID + "): " + cadena +
          "           " + "ThreadID=" + Thread.currentThread().getId() + " ThreadName=" + Thread.currentThread().getName();
    Logger.getLogger(this.getClass().getName()).log(Level.INFO,msg);
}

//Constructor
public FirstWS() {
    Random rnd = new Random();
    m_instanceID = rnd.nextLong();
    WriteLog("Executing Constructor");
}

//PostConstruct
@PostConstruct
public void ThisIsThePostConstruct() {
    WriteLog("Executing PostConstruct");
}

//PreDestroy
@PreDestroy
public void ThisIsThePreDestroy() {
    WriteLog("Executing PreDestroy");
}

//Method
@WebMethod(operationName = "GetInstanceID")
@WebResult(name="InstanceID")
public long GetInstanceID() {
    //TODO write your implementation code here:
    WriteLog("Executing GetInstanceID");
    return m_instanceID;
}

}

我总是认为Web服务默认是单例。

glassfish V2.1 服务器上,ws按预期工作,具有单例生命周期:

  • 只创建了一个实例。
  • 只执行一次构造函数方法。
  • 如果postconstructor方法只执行一次。
  • 取消部署ws时,只执行一次predestroy方法。

客户端日志

InstanceID = -4747957096764272596

InstanceID = -4747957096764272596

InstanceID = -4747957096764272596

服务器日志

26/08/2010 13:08:15:146 ***** first.test.FirstWS(m_instanceID = -4747957096764272596):执行构造函数ThreadID = 68 ThreadName = httpSSLWorkerThread-8080-0

26/08/2010 13:08:15:161 ***** first.test.FirstWS(m_instanceID = -4747957096764272596):执行PostConstruct ThreadID = 68 ThreadName = httpSSLWorkerThread-8080-0

26/08/2010 13:08:15:364 ***** first.test.FirstWS(m_instanceID = -4747957096764272596):执行GetInstanceID ThreadID = 69 ThreadName = httpSSLWorkerThread-8080-1

26/08/2010 13:08:15:380 ***** first.test.FirstWS(m_instanceID = -4747957096764272596):执行GetInstanceID ThreadID = 69 ThreadName = httpSSLWorkerThread-8080-1

26/08/2010 13:08:15:396 ***** first.test.FirstWS(m_instanceID = -4747957096764272596):执行GetInstanceID ThreadID = 69 ThreadName = httpSSLWorkerThread-8080-1

26/08/2010 13:08:38:849 ***** first.test.FirstWS(m_instanceID = -4747957096764272596):执行PreDestroy ThreadID = 626 ThreadName = Thread-540

但是在 glassfish V3 服务器上,ws没有按预期工作,因为为每次调用GetInstanceID创建了一个新的ws实例:

  • 为每次通话创建一个实例。
  • 每次调用都执行一次构造函数方法。
  • 每次通话的两个(!?!?!)执行postconstructor方法。
  • 取消部署ws时不会调用predestroy方法。

客户端日志

InstanceId = 7754248300017958713

InstanceId = -1714184485890589231

InstanceId = -4156829683887899017

服务器日志

INFO:26/08/2010 15:16:11:429 ***** first.test.FirstWS(m_instanceID = 7754248300017958713):执行构造函数ThreadID = 103 ThreadName = http-thread-pool-8080-(2 )

INFO:26/08/2010 15:16:11:429 ***** first.test.FirstWS(m_instanceID = 7754248300017958713):执行PostConstruct ThreadID = 103 ThreadName = http-thread-pool-8080-(2 )

INFO:26/08/2010 15:16:11:429 ***** first.test.FirstWS(m_instanceID = 7754248300017958713):执行PostConstruct ThreadID = 103 ThreadName = http-thread-pool-8080-(2 )

INFO:26/08/2010 15:16:12:429 ***** first.test.FirstWS(m_instanceID = 7754248300017958713):执行GetInstanceID ThreadID = 103 ThreadName = http-thread-pool-8080-(2 )

INFO:26/08/2010 15:16:12:460 ***** first.test.FirstWS(m_instanceID = -1714184485890589231):执行构造函数ThreadID = 102 ThreadName = http-thread-pool-8080-( 1)

INFO:26/08/2010 15:16:13:429 ***** first.test.FirstWS(m_instanceID = -1714184485890589231):执行PostConstruct ThreadID = 102 ThreadName = http-thread-pool-8080-( 1)

INFO:26/08/2010 15:16:13:429 ***** first.test.FirstWS(m_instanceID = -1714184485890589231):执行PostConstruct ThreadID = 102 ThreadName = http-thread-pool-8080-( 1)

INFO:26/08/2010 15:16:14:429 ***** first.test.FirstWS(m_instanceID = -1714184485890589231):执行GetInstanceID ThreadID = 102 ThreadName = http-thread-pool-8080-( 1)

INFO:26/08/2010 15:16:14:445 ***** first.test.FirstWS(m_instanceID = -4156829683887899017):执行构造函数ThreadID = 103 ThreadName = http-thread-pool-8080-( 2)

INFO:26/08/2010 15:16:15:429 ***** first.test.FirstWS(m_instanceID = -4156829683887899017):执行PostConstruct ThreadID = 103 ThreadName = http-thread-pool-8080-( 2)

INFO:26/08/2010 15:16:15:429 ***** first.test.FirstWS(m_instanceID = -4156829683887899017):执行PostConstruct ThreadID = 103 ThreadName = http-thread-pool-8080-( 2)

INFO:26/08/2010 15:16:15:429 ***** first.test.FirstWS(m_instanceID = -4156829683887899017):执行GetInstanceID ThreadID = 103 ThreadName = http-thread-pool-8080-( 2)

信息:关闭Metro监控root:amx:pp = / mon / server-mon [server],type = WSEndpoint,name = / FirstWebApplication-FirstWSService-FirstWSPort

那么,为什么这种行为会对glassfish V3产生影响呢?我怎么能在glassfish V3上有单独的网络服务?

2 个答案:

答案 0 :(得分:0)

我认为这可能是规范问题(Java EE 5与Java EE 6),您可能需要使用@Stateless annotation

package com.sun.tutorial.javaee.ejb;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;

    @Stateless
    @WebService
    public class HelloServiceBean {
        private String message = "Hello, ";

        public void HelloServiceBean() {}

        @WebMethod
        public String sayHello(String name) {
            return message + name + ".";
        }
    }

更正:这适用于Glassfish V3。

答案 1 :(得分:0)

最后我发现了问题:项目的类型。在NetBeans中,我在“Web Aplication”项目中创建了Web服务,因此它被部署到Glassfish中的servlet容器中,@ Stateless和@Singleton注释不起作用。您必须在“EJB Moule”项目中创建ws,它将被部署到EJB容器中,以便@Stateless和@Singleton注释正常工作。

正如Java EE 6所说“Singleton会话bean提供与无状态会话bean类似的功能但与它们不同之处在于每个应用程序只有一个单独的会话bean,而不是无状态会话bean池,其中任何一个都可以响应与无状态会话bean一样,单例会话bean可以实现Web服务端点。“