簡體   English   中英

如果@Singleton bean中有一個@Stateless字段,將會發生什么?

[英]What will happen if @Singleton bean would have a @Stateless field in it?

我不確定@EJB注釋如何分配字段等。

假設我們有3個類:

  • A- 無狀態 (具有@EJB注釋的B字段)
  • B- 單例 (具有@EJB批注的C字段)
  • C- 無狀態

在這種情況下,當用戶嘗試訪問Bean時會發生什么?

  1. 用戶1訪問bean(第一次)
    1. A已創建,需要B才能工作
    2. B已創建,需要C才能工作
    3. C創建
  2. 用戶2連接並
    1. 創建A的原因是用戶1仍在使用他的A
    2. B是必需的,但它是一個單例,因此返回唯一的實例
    3. 未創建C,因為Singleton B已經為其分配了引用

這是否意味着如果@Singleton需要任何其他bean,它將用作@Singleton嗎? @Stateless將充當單例)

不必要。 如果單例允許使用@Lock(READ)@ConcurrencyManagement(BEAN)進行多個並發調用, @Lock(READ)創建多個C bean,每個調用者線程一個與A bean相同。 但是,如果單例bean將@ConcurrencyManagement(CONTAINER)的默認並發與@Lock(WRITE) ,則可以,bean C實際上也將是一個單例(假設在其他地方未訪問它)。

我已經為您的問題創建了示例實現。 您可以在GitHub上找到它: https : //github.com/StefanHeimberg/stackoverflow-28194928

使用NetBeans 8.0.2打開此項目,並將其部署(運行)在Glassfish 4.1上。

部署后將創建以下日志:

Information:   visiting unvisited references
Information:   visiting unvisited references
Information:   Portable JNDI names for EJB C: [java:global/mavenproject1/C!com.mycompany.mavenproject1.C, java:global/mavenproject1/C]
Schwerwiegend:   C[uuid=e1c73e4b-998c-4666-bac9-4825556aa20a] => created
Information:   Portable JNDI names for EJB Bootstrap: [java:global/mavenproject1/Bootstrap!com.mycompany.mavenproject1.Bootstrap, java:global/mavenproject1/Bootstrap]
Information:   Portable JNDI names for EJB A: [java:global/mavenproject1/A, java:global/mavenproject1/A!com.mycompany.mavenproject1.ARemote]
Information:   Glassfish-specific (Non-portable) JNDI names for EJB A: [com.mycompany.mavenproject1.ARemote, com.mycompany.mavenproject1.ARemote#com.mycompany.mavenproject1.ARemote]
Information:   Portable JNDI names for EJB B: [java:global/mavenproject1/B!com.mycompany.mavenproject1.B, java:global/mavenproject1/B]
Schwerwiegend:   B[uuid=868f15c0-728d-4079-b90a-2b55ae413c33] => created
WARN:   WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN:   WELD-000411: Observer method [BackedAnnotatedMethod] public org.glassfish.jms.injection.JMSCDIExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN:   WELD-000411: Observer method [BackedAnnotatedMethod] org.glassfish.sse.impl.ServerSentEventCdiExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
Schwerwiegend:   ========================
Schwerwiegend:   Bootstrap.init()
Schwerwiegend:   ========================
Information:   mavenproject1 was successfully deployed in 419 milliseconds.

現在僅運行重點測試方法ARemoteIT.client1()。 生成以下輸出:

Schwerwiegend:   A[uuid=9be077f8-945a-4db2-ba3e-ea0003692c0f] => created ()
Schwerwiegend:   A[uuid=9be077f8-945a-4db2-ba3e-ea0003692c0f] => B of type com.mycompany.mavenproject1.__EJB31_Generated__B__Intf____Bean__ injected
Schwerwiegend:   A[uuid=9be077f8-945a-4db2-ba3e-ea0003692c0f] => ready to use 
Schwerwiegend:   A[uuid=9be077f8-945a-4db2-ba3e-ea0003692c0f] [client1] => doSomething() called
Schwerwiegend:   B[uuid=ce1be5f1-0b82-4990-a9b5-153a2540a891] => created
Schwerwiegend:   B[uuid=ce1be5f1-0b82-4990-a9b5-153a2540a891] => C of type com.mycompany.mavenproject1.__EJB31_Generated__C__Intf____Bean__ injected
Schwerwiegend:   B[uuid=ce1be5f1-0b82-4990-a9b5-153a2540a891] => ready to use
Schwerwiegend:   B[uuid=ce1be5f1-0b82-4990-a9b5-153a2540a891] [client1]   => doSomething() called
Schwerwiegend:   C[uuid=5f1bed5c-80e8-41c8-b524-51cac3e3de0f] => created
Schwerwiegend:   C[uuid=5f1bed5c-80e8-41c8-b524-51cac3e3de0f] => ready to use
Schwerwiegend:   C[uuid=5f1bed5c-80e8-41c8-b524-51cac3e3de0f] [client1]     => doSomething() called

在C.doeSomething()內部,現在有1分鍾的超時...

在此超時內,不能並發訪問單例bean B,因為默認鎖定類型為Write(@Lock(WRITE))。

如果您在1分鍾超時內立即開始使用功能強大的測試方法ARemoteIT.client2(),則會生成以下輸出:

Schwerwiegend:   A[uuid=c358e9f3-8687-4d76-a9ca-38b31357649b] => created ()
Schwerwiegend:   A[uuid=c358e9f3-8687-4d76-a9ca-38b31357649b] => B of type com.mycompany.mavenproject1.__EJB31_Generated__B__Intf____Bean__ injected
Schwerwiegend:   A[uuid=c358e9f3-8687-4d76-a9ca-38b31357649b] => ready to use 
Schwerwiegend:   A[uuid=c358e9f3-8687-4d76-a9ca-38b31357649b] [client2] => doSomething() called

在這里,您可以看到client2是Waitung,以便B調用B.doSomething。 1分鍾的超時完成后。 可以訪問單例bean,client2可以跟隨B.doSomething。

這是client1 C.doSomething超時后的日志:

Schwerwiegend:   C[uuid=5f1bed5c-80e8-41c8-b524-51cac3e3de0f] [client1]     => doSomething() finished
Schwerwiegend:   B[uuid=ce1be5f1-0b82-4990-a9b5-153a2540a891] [client1]   => doSomething() finished
Schwerwiegend:   A[uuid=9be077f8-945a-4db2-ba3e-ea0003692c0f] [client1] => doSomething() finished
Schwerwiegend:   B[uuid=ce1be5f1-0b82-4990-a9b5-153a2540a891] [client2]   => doSomething() called
Schwerwiegend:   C[uuid=5f1bed5c-80e8-41c8-b524-51cac3e3de0f] [client2]     => doSomething() called
Schwerwiegend:   C[uuid=5f1bed5c-80e8-41c8-b524-51cac3e3de0f] [client2]     => doSomething() finished
Schwerwiegend:   B[uuid=ce1be5f1-0b82-4990-a9b5-153a2540a891] [client2]   => doSomething() finished
Schwerwiegend:   A[uuid=c358e9f3-8687-4d76-a9ca-38b31357649b] [client2] => doSomething() finished

附加功能:

如你看到的。 注入的實際上不是B或C的實例! 相反,這些僅僅是代理。 但您還可以看到glassfish部署后會自動創建B a C的新實例。

使用@Stateless,您不能保證您會收到所需EJB的相同實例。 也可能是每次您在代理上調用方法時,都會收到所需EJB的另一個實例。 容器正在對此進行管理。 有一個EJB池,容器在其中使用一個容器,或者如果所有EJB都在使用中,則創建一個新實例。

在日志中,您看到B僅在調用A.doSomething()之后創建。 那個男人在調用代理的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM