2009-03-06 24 views
11

Chúng ta đều biết rằng trong tầng web có khả năng chỉ có một cá thể duy nhất của một Servlet cụ thể tồn tại mà nhiều dịch vụ yêu cầu. Điều này có thể dẫn đến vấn đề luồng trong các biến mẫu.Có an toàn khi tiêm EJB vào một servlet như một biến mẫu không?

Câu hỏi của tôi là, có an toàn khi tiêm EJB bằng cách sử dụng chú thích @EJB vào một servlet làm biến mẫu không?

Bản năng ban đầu của tôi sẽ không, theo giả định rằng cùng một trường hợp của EJB sẽ phục vụ nhiều yêu cầu cùng một lúc. Có vẻ như đây cũng là bản năng của một số lập trình viên khác: Don't inject to servlets

Tuy nhiên, tôi đã đi đến kết luận sai. Rõ ràng những gì được tiêm vào servlet là một proxy, dưới mui xe hiện container thực sự phục vụ mỗi yêu cầu với một trường hợp khác nhau và duy trì an toàn thread? Vì diễn đàn này sẽ đề xuất: Do inject to servlets

Dường như có nhiều ý kiến ​​xung đột. ĐÚNG LÀ GÌ?

Trả lời

3

Tham chiếu "Không tiêm vào servlets" của bạn không đề cập gì về chú thích ejbs hoặc @ejb. Nó nói về không phải chủ đề an toàn chủ đề như PersistenceContext.

Mỗi thông số EJB, bạn có thể truy cập ejbs từ nhiều máy khách từ xa bao gồm servlets (Đặc tả EJB 3.0 (JSR-220) - Phần 3.1). Việc tiêm ejb bằng cách sử dụng chú thích @EJB là một phương thức lấy giao diện EJB thông qua việc tiêm phụ thuộc (phần 3.4.1), đây là phương pháp thay thế để tìm kiếm các đối tượng ejb trong vùng tên JNDI. Vì vậy, không có gì đặc biệt về chú thích @EJB đối với các EJB thu được.

Vì vậy, dựa trên EJB 3.0 Spec, đó là một thực hành tiêu chuẩn để có được ejbs từ các servlet bằng cách sử dụng chú thích @EJB.

+0

Câu trả lời này là chính xác như xa như nó đi, nhưng nó không giải quyết các mối quan tâm an toàn thread của OP. Tôi tin rằng câu trả lời của inferreddesign dưới đây phải là câu trả lời đúng. –

+0

Tôi đoán một EJB được tiêm với @Inject (CDI, JEE 6) sẽ an toàn, đúng không? – marcus

0

Tôi nghĩ câu trả lời đơn giản là bạn không được đảm bảo rằng nó an toàn.

Lý do cho điều này là không có gì rõ ràng trong đặc tả EJB cho biết giao diện nhà EJB phải là luồng an toàn. Spec chỉ phác họa hành vi của phần phía máy chủ. Những gì bạn có thể sẽ thấy là bộ xương của khách hàng thực sự là an toàn nhưng bạn cần phải xem chúng được thư viện bạn đang sử dụng như thế nào. Phần chú thích sẽ chỉ mở rộng thành một định vị dịch vụ để không mua cho bạn bất cứ thứ gì.

11

Sẽ an toàn khi tiêm EJB vào Servlet dưới dạng biến mẫu Servlet, miễn là EJB là không quốc tịch. Bạn KHÔNG BAO GIỜ tiêm một Bean stateful trong Servlet.

Bạn phải triển khai EJB không trạng thái ở chỗ nó không giữ bất kỳ biến mẫu nào mà chính nó chứa một giá trị trạng thái (như Persistence Context). Nếu bạn cần sử dụng bối cảnh persistence, thì bạn phải có được một cá thể của nó trong các phương thức của EJB. Bạn có thể làm điều đó bằng cách có một PersistenceContextFactory như một biến thể EJB và sau đó bạn nhận được một cá thể của trình quản lý thực thể từ Nhà máy trong phương thức của EJB.

PersistenceContextFactory là luồng an toàn, do đó nó có thể được tiêm vào một biến mẫu.

Chừng nào bạn tuân thủ các quy tắc nêu trên, nó phải là thread-an toàn để tiêm một quốc tịch Bean trong một Servlet

1

Đó là một túi hỗn hợp.

Hạt phiên không có trạng thái có thể được tiêm và an toàn.Điều này là bởi vì ngay cả khi một cá thể đơn lẻ được sử dụng, quyền truy cập vào các phương thức sẽ được tuần tự hóa bởi vùng chứa.

Tôi nghĩ rằng inferreddesign nói là không đúng. Nó không quan trọng nếu đậu phiên không trạng thái sử dụng một bối cảnh kiên trì. Chỉ có một người gọi sẽ truy cập một cá thể bean đơn cùng một lúc, vì vậy mặc dù bối cảnh kiên trì không phải là luồng an toàn, nhưng các EJB bảo vệ chống lại nhiều quyền truy cập vào nó. Hãy nghĩ về nó như thể mọi phương thức bean phiên đều có từ khóa đồng bộ được áp dụng cho nó.

Vấn đề chính khi tiêm EJB vào Servlet tôi nghĩ là hiệu suất. Ví dụ duy nhất sẽ trở thành một khu vực tranh chấp lớn khi nhiều yêu cầu đang xếp hàng trong khi chờ đợi một phương thức bean phiên được thực hiện cho chúng.

+0

Sơ khai sẽ được đồng bộ hóa, nhưng tôi hy vọng rằng nó sẽ nhanh chóng gửi đến một trong các EJB gộp lại để thực hiện công việc thực tế. Trừ khi cuống giữ khóa trong toàn bộ cuộc gọi, đó sẽ là một lựa chọn thực hiện rất xấu ... – marcus

Các vấn đề liên quan