2014-09-28 11 views
7

Sau khi đọc tài liệu mongo cho biết mỗi cá thể của MongoClient xử lý việc gộp nhóm riêng của nó, làm cách nào tôi chỉ có một cá thể trên toàn bộ ứng dụng của mình?Sử dụng một MongoClient duy nhất trên dịch vụ web JavaEE

Điều này có vẻ như nó có thể là một kịch bản để sử dụng một hạt đơn, nhưng điều này có vẻ như nó sẽ đánh bại mục đích của kết nối tổng hợp. Nếu chỉ một người dùng có thể truy cập vào bean có chứa cá thể MongoClient tại một thời điểm, chắc chắn nhiều kết nối trong nhóm sẽ không bao giờ được sử dụng cùng một lúc.

Tôi có hiểu biết về những sai sót của người độc thân không, hay đó thực sự là một cách phù hợp để thực hiện nó?

+0

nó sẽ đánh bại mục đích kết nối tổng hợp – ControlAltDel

+0

Bạn đang sử dụng Spring để tạo ứng dụng khách mongo ?? – Suvasis

+0

Không, tôi không sử dụng Spring Tôi đang sử dụng JavaEE, xin lỗi tôi nên đặt câu hỏi đó (tôi đã thêm nó vào thẻ và sẽ cập nhật tiêu đề câu hỏi) –

Trả lời

9

nhưng điều này có vẻ như nó sẽ đánh bại mục đích kết nối pooling.If chỉ một người dùng sẽ có thể truy cập vào đậu mà chứa dụ MongoClient cùng một lúc, chắc chắn nhiều kết nối trong hồ bơi sẽ không bao giờ được sử dụng cùng một lúc.

Các javadoc nói:

Người tài xế Java MongoDB là chủ đề an toàn. Nếu bạn đang sử dụng trong một môi trường phục vụ web, ví dụ, bạn nên tạo một cá thể đơn MongoClient và bạn có thể sử dụng nó trong mọi yêu cầu. Đối tượng MongoClient duy trì một nhóm kết nối nội bộ với cơ sở dữ liệu (kích thước nhóm tối đa mặc định là 100). Đối với mọi yêu cầu đến DB (tìm, chèn, v.v.), chuỗi Java sẽ nhận được kết nối từ hồ bơi, thực hiện thao tác và giải phóng kết nối. Điều này có nghĩa là kết nối (ổ cắm) được sử dụng có thể khác nhau mỗi lần.

Vì vậy, khi bạn tạo một singleton với ứng dụng khách trong đó. Nó có thể được tái sử dụng như đã đề cập trong Javadoc. Không cần đồng bộ hóa vì nó là an toàn.

Tôi làm cách nào để chỉ có một ví dụ trên toàn bộ ứng dụng của mình?

Một trong những triển khai có thể là:

public enum ConnectionFactory { 
    CONNECTION; 
    private MongoClient client = null; 

    private ConnectionFactory() { 
     try { 
      client = new MongoClient(); 
     } catch (Exception e) { 
      // Log it. 
     } 
    } 

    public MongoClient getClient() { 
     if (client == null) 
      throw new RuntimeException(); 
     return client; 
    } 
} 

và sử dụng máy khách như, trong suốt ứng dụng. Connection pooling sẽ được xử lý theo số MongoClient như được ghi lại.

MongoClient client = ConnectionFactory.CONNECTION.getClient(); 

hoặc sử dụng các chú thích @Singleton:

@Singleton 
public class SingletonA { 

} 

Tham khảo: http://tomee.apache.org/singleton-example.html

+1

Cảm ơn câu trả lời, điều gì sẽ là sự khác biệt giữa việc làm điều này và sử dụng chú thích '@ Singleton' để tạo ra một hạt đơn là gì? Nó có tác dụng tương tự không? –

+0

@MattWilliams - Đầu tiên là một 'thực hiện' của một mẫu đơn và có thể được sử dụng cả trong một ứng dụng java bình thường và một ứng dụng Java EE,' @ singleton' tóm tắt việc triển khai singleton từ nhà phát triển. Vì vậy, khuôn khổ cơ bản sẽ chăm sóc thực hiện một cá thể đơn cho lớp. Đã cập nhật câu trả lời của tôi cho ý kiến ​​của bạn. – BatScream

+0

@BatScrem - Rực rỡ, cảm ơn vì đã dọn dẹp. Vì vậy, trong lớp 'ConnectionFactory' (hoặc bất kỳ thứ gì tôi gọi nó) sử dụng chú thích, tôi có thể có một biến MongoClient riêng, khởi tạo nó trong hàm tạo và có một trình rút gọn đơn giản. Có thể đây chỉ là một phương pháp đường dây, ví dụ: trong constructor 'client = new MongoClient();' như chú thích và việc tiêm xử lý trường hợp bạn có thể gọi getter khi nó chưa được khởi tạo, hay tôi vẫn cần phải xử lý ngoại lệ? –

3

Kể từ khi bạn đang ở trong một môi trường Java EE, cách tốt nhất để thực hiện điều này sẽ được sử dụng sản xuất CDI:

@Stateless 
public class ConnetionFactory { 

    @ApplicationScoped 
    @Produces 
    public MongoClient mongoClient() { 
    return new MongoClient(); 
    } 
} 

Sau đó, trong mỗi đậu bạn muốn sử dụng nó trong:

@Stateless 
public class MyServiceBean { 

    @Inject 
    private MongoClient mongoClient; 
} 
+0

Tôi đồng ý rằng đây là cách để đi trong môi trường JavaEE. –

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