2010-01-17 144 views

回答

9

的「國家」一詞在這方面是有點誤導。它指的是會話狀態,這意味着如果客戶端進行多次調用,會話bean無法知道。想象一下呼叫序列:

  • reserveSeatsOnFlight();
  • chooseMealPreference();
  • confirmBooking()

你在那裏有什麼會話狀態,這意味着第二個調用必須與第一個調用相同的bean進行,否則它就沒有意義。這就是有狀態會話bean所做的事情。

無狀態會話bean可以有實例變量,但實質上是全局的。如果您有一個無狀態會話Bean池(您可能會也可能不會取決於容器決定做什麼),那些實例變量可能會或可能不會從一次調用到另一次調用。所以通常避免實例變量。這種事情還有其他的機制。

讓我給你舉個例子。在無狀態會話bean想象一下這樣的電話:

public void bookFlight(List<Passsenger> passengers, FlightNumber flight, Date date) { 
    ... 
} 

,如果你把一個實例變量來計算訂單的數量,並增加它在每次調用然後後續調用可能會調用不同的豆類所以會看到不同的值。這就是我的意思,它不一定有意義。

所以回到第一個例子,來處理這一個辦法是通過國家返回給調用者:

public interface ReservationSystem { 
    public int createNewBooking(); 
    public int reserveSeatsOnFlight(int bookingId, int seats); 
    public int chooseMealPreference(int bookingId, ...) 
    ... 
} 

如何看上面不再有會話狀態?它的確如此,但它現在封裝在您傳遞的bookingId中。無狀態會話bean可以檢索預訂並從另一個地方繼續。

1

我經常看到無狀態會話bean使用局部變量作爲維護bean中的「全局」狀態的一種方法(以避免將數據從對象內的一個方法調用傳遞給另一個方法)。儘管如此,這些基本上是你的對象中的全局變量,並且適合濫用(因爲他們在我見過的大多數情況下也是如此)。我傾向於建議避免它們。

可能有些情況下,他們是有用的,雖然......你有一個特定的用例?

1

無狀態bean可以像任何其他對象一樣擁有實例變量。它只是不能使用它們來維護特定於特定客戶端的值...

0

怎樣持有final在SLSB啓動時(即在構造函數中)初始化的實例變量。 我想這是在SLSB的構造函數實例化的DAO屬性的,就像這樣:

@Stateless 
    public class MyStatelessBean() {  
    private final CustomerDAO customerDAO; 

     public MyStatelessBean() { 
       // Initialization code goes here 
       this.customerDAO = new CustomerDAO(); 
     } 
    ... 
    } 

所以DAO可以直接在SLSB的方法使用,並且不被每次創建的DAO是需要的。當然提供DAO是無狀態的,通常情況下是這樣。與數據庫的連接當然會按需提供,並且永遠不會存儲在SLSB本身中。