2013-05-10 44 views
4

我正在Glassfish 4.0-b87下運行一個簡單的.war文件,該文件是在Eclipse Kepler M6中使用M2E創建的,作爲添加了動態Web模塊方面的簡單項目,使用Oracle Java 7 JDK/JVM。爲什麼在@Singleton上@PostConstruct調用兩次

基本上有一個類,我期望post_construct方法只能被調用一次。但是它被調用了兩次,第一次在應用程序部署時,第一次也是僅在第一次HTTP請求時多了一次。

下面是類(日誌輸出如下):

package com.example.main; 

import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 
import javax.ejb.LocalBean; 
import javax.ejb.PostActivate; 
import javax.ejb.PrePassivate; 
import javax.ejb.Singleton; 
import javax.ejb.Startup; 
import javax.enterprise.inject.spi.PassivationCapable; 
import javax.ws.rs.ApplicationPath; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.core.Application; 

@Singleton 
@Startup 
@LocalBean 
@ApplicationPath("/rest") 
@Path("/life") 
public class Life extends Application implements PassivationCapable { 

    @PostConstruct 
    public void post_construct() { 
    System.out.println("hello world!"); 
    } 

    @PreDestroy 
    public void pre_destroy() { 
    System.out.println("so long and thanks for the fish!"); 
    } 

    @PrePassivate 
    public void pre_passivate() { 
    System.out.println("taking a break"); 
    } 

    @PostActivate 
    public void post_activate() { 
    System.out.println("back from break"); 
    } 

    @Override 
    public String getId() { 
    return "life"; 
    } 

    @GET 
    public String greet() { 
    return "hi"; 
    } 
} 

日誌輸出是用虛線分開第一HTTP調用和HTTP調用後的部分之前的部分如下:

[2013-05-09T19:42:26.660-1000] [glassfish 4.0] [INFO] [NCLS-DEPLOYMENT-00027] [javax.enterprise.system.tools.deployment.autodeploy] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546660] [levelValue: 800] [[ 
    Selecting file /usr/local/glassfish4/glassfish/domains/domain1/autodeploy/singleton.war for autodeployment]] 

[2013-05-09T19:42:26.692-1000] [glassfish 4.0] [INFO] [] [javax.enterprise.system.tools.deployment.common] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546692] [levelValue: 800] [[ 
    visiting unvisited references]] 

[2013-05-09T19:42:26.702-1000] [glassfish 4.0] [INFO] [] [javax.enterprise.system.tools.deployment.common] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546702] [levelValue: 800] [[ 
    visiting unvisited references]] 

[2013-05-09T19:42:26.706-1000] [glassfish 4.0] [INFO] [] [javax.enterprise.system.tools.deployment.common] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546706] [levelValue: 800] [[ 
    visiting unvisited references]] 

[2013-05-09T19:42:26.709-1000] [glassfish 4.0] [INFO] [] [javax.enterprise.system.tools.deployment.common] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546709] [levelValue: 800] [[ 
    visiting unvisited references]] 

[2013-05-09T19:42:26.749-1000] [glassfish 4.0] [INFO] [ejb.portable_jndi_names] [javax.enterprise.system.container.ejb.com.sun.ejb.containers] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546749] [levelValue: 800] [[ 
    EJB5181:Portable JNDI names for EJB Life: [java:global/singleton/Life, java:global/singleton/Life!com.example.main.Life]]] 

[2013-05-09T19:42:26.959-1000] [glassfish 4.0] [WARNING] [] [org.jboss.weld.Bootstrap] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546959] [levelValue: 900] [[ 
    WELD-001473 javax.enterprise.inject.spi.Bean implementation [email protected] declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.]] 

[2013-05-09T19:42:26.970-1000] [glassfish 4.0] [INFO] [] [] [tid: _ThreadID=59 _ThreadName=Thread-3] [timeMillis: 1368164546970] [levelValue: 800] [[ 
    hello world!]] 

[2013-05-09T19:42:26.982-1000] [glassfish 4.0] [INFO] [] [org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546982] [levelValue: 800] [[ 
    Registering the Jersey servlet application, named com.example.main.Life, at the servlet mapping /rest/*, with the Application class of the same name.]] 

[2013-05-09T19:42:26.988-1000] [glassfish 4.0] [INFO] [AS-WEB-GLUE-00172] [javax.enterprise.web] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164546988] [levelValue: 800] [[ 
    Loading application [singleton] at [/singleton]]] 

[2013-05-09T19:42:27.003-1000] [glassfish 4.0] [INFO] [] [javax.enterprise.system.core] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164547003] [levelValue: 800] [[ 
    singleton was successfully deployed in 332 milliseconds.]] 

[2013-05-09T19:42:27.006-1000] [glassfish 4.0] [INFO] [NCLS-DEPLOYMENT-00035] [javax.enterprise.system.tools.deployment.autodeploy] [tid: _ThreadID=59 _ThreadName=AutoDeployer] [timeMillis: 1368164547006] [levelValue: 800] [[ 
    [AutoDeploy] Successfully autodeployed : /usr/local/glassfish4/glassfish/domains/domain1/autodeploy/singleton.war.]] 

------------------------------第一次HTTP通話後----------- -------------------

[2013-05-09T19:42:44.940-1000] [glassfish 4.0] [INFO] [] [] [tid: _ThreadID=21 _ThreadName=Thread-3] [timeMillis: 1368164564940] [levelValue: 800] [[ 
    hello world!]] 

[2013-05-09T19:42:44.940-1000] [glassfish 4.0] [INFO] [] [org.glassfish.jersey.server.ApplicationHandler] [tid: _ThreadID=21 _ThreadName=http-listener-1(4)] [timeMillis: 1368164564940] [levelValue: 800] [[ 
    Initiating Jersey application, version Jersey: 2.0-rc2 2013-04-23 12:04:25...]] 

[2013-05-09T19:42:44.956-1000] [glassfish 4.0] [INFO] [] [org.glassfish.jersey.gf.ejb.EjbComponentProvider] [tid: _ThreadID=21 _ThreadName=http-listener-1(4)] [timeMillis: 1368164564956] [levelValue: 800] [[ 
    The Jersey EJB interceptor is bound. JAX-RS EJB integration support is enabled.]] 
+0

答案已更新。 – necromancer 2013-05-15 08:06:09

回答

1

<update>這是一個錯誤的Glassfish https://java.net/jira/browse/GLASSFISH-20505</update>

似乎@Singleton,並@ApplicationPath + extends Application打得並不好看彼此。也許這種行爲是正確的,因爲JAX-RS需要實例化Application類,EJB需要實例化@Singleton一次,但是直到有人指出標準的相關部分,最好將其視爲一個錯誤。澤西島應識別@Singleton註釋並尋找extends Application類,而不是創建它自己的。

可能的澤西島錯誤的解決方法是不使用相同的類作爲@Singleton和澤西Application類。

+0

這不是一個錯誤。基本上,您將Web服務和業務服務緊密結合在一個類中。你最終得到兩個完全分離的同一類的實例,這兩個實例用於兩個完全不同的目的。換句話說,這只是糟糕的設計手段。只需將Web服務邏輯和業務服務邏輯分成兩個獨立的類,然後在web服務中將業務服務注入@EJB。 – BalusC 2013-05-10 20:46:30

+0

@BalusC你的意思是@Application + @Singleton耦合?或@ApplicationPath + @Path耦合?或@Singleton + @Path。我完全同意糟糕的設計,但糟糕的設計很可能暴露出Glassfish的實現錯誤。我認爲在一個類中將@Path分隔成一個類和@Singleton + @ApplicationPath可以顯着改進設計,但我敢打賭,它仍然會暴露Glassfish實現bug,它在實例已經存在時創建實例化一個新的'extends Application'類。謝謝你的評論! – necromancer 2013-05-10 21:12:27

+0

看看這些註釋來自哪些包。 'javax.ws.rs'是JAX-RS webservice API。 'javax.ejb'是EJB businessservice API。 – BalusC 2013-05-10 21:38:34

相關問題