2011-01-27 33 views
8

Tôi là người duy trì duy nhất trên một cơ sở mã nơi đăng nhập được thực hiện bằng cách sử dụng đăng nhập Apache commons.Nhật ký không tĩnh có thể được chứng minh không?

Tất cả các lớp chứa hai hàng nhập khẩu sau đây:

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

Sau đó, rất nhiều lớp chứa không instantiation log tĩnh như thế này:

/** The log. */ 
private Log log = LogFactory.getLog(Xyz.class); 

thể này là hợp lý?

Tôi có thể thay đổi an toàn tất cả những điều này thành cuộc gọi tĩnh không?

CHỈNH SỬA Về các trường hợp đặc biệt có thể (rõ ràng) tiện dụng: câu hỏi của tôi thực sự là nhiều hơn "Nhật ký không tĩnh trên toàn bộ codebase có được biện minh không?"

Trả lời

5

Bạn phải cẩn thận hơn khi có trình ghi nhật ký không tĩnh khởi tạo cách đoạn mã của bạn đang hoạt động trong các lớp Serializable.

Thứ nhất là vì Log không thể tuần tự hóa được, vì vậy mọi nỗ lực tuần tự hóa lớp học của bạn cũng sẽ không thành công. Nếu bạn khai báo logger của mình transient thì đó là điều hợp lý cần làm, trường log của bạn sẽ không được khởi tạo sau khi hủy tuần tự hóa, vì vậy bạn sẽ nhận được NPE khi cố đăng nhập nội dung. Không phải là một tình huống rất tốt đẹp.

Vì vậy, để tổng hợp, bạn có thể có nhật ký không tĩnh nếu bạn thích, nhưng hãy đảm bảo chúng được khởi tạo trước khi bạn sử dụng chúng. Nhưng ngoài ra, tôi sẽ không lo lắng nhiều về logger không tĩnh, hầu hết các triển khai đăng nhập sẽ luôn luôn trả về cùng một đối tượng logger anyway (log4j chắc chắn không).

8

Điều đó tùy thuộc. Đây là từ số documentation:

Lưu ý rằng đối với mã ứng dụng, khai báo thành viên nhật ký là "tĩnh" hiệu quả hơn vì một đối tượng Nhật ký được tạo cho mỗi lớp và được khuyến nghị. Tuy nhiên, điều này không an toàn đối với một lớp có thể được triển khai thông qua bộ nạp lớp "được chia sẻ" trong một thùng chứa servlet hoặc j2ee hoặc môi trường tương tự. Nếu lớp có thể kết thúc bằng các giá trị luồng-lớp-trình nạp lớp-bối cảnh khác nhau được thiết lập thì thành viên đó không được khai báo tĩnh. Do đó, việc sử dụng "tĩnh" nên tránh trong mã trong bất kỳ dự án kiểu "thư viện" nào.

+0

Sau khi đọc tài liệu đó, nó không phải là rõ ràng với tôi những gì là sai với tuyên bố một lĩnh vực Log như tĩnh ngay cả trong môi trường classloader chia sẻ. Tham số lớp LogFactory.getLog() có thể được thay đổi thành một String (Xyz.class.getName()) cho một điều, và ngoài việc đó, tác hại của logger được truy cập từ các lớp với các trình nạp lớp ngữ cảnh chủ đề khác nhau là gì? Tuy nhiên, phương thức đăng nhập phải an toàn cho luồng và nếu bạn không gặp phải vấn đề lớn hơn. Có ai có thể cung cấp mô tả rõ ràng về những gì có thể xảy ra sai với tham chiếu nhật ký tĩnh không? –

+1

@Dov Wasserman Câu hỏi hay, nhưng phải trung thực với bạn, tôi thậm chí không hiểu được điểm của việc đăng nhập commons. :) – biziclop

2

Một thể hiện là một trình ghi nhật ký không tĩnh là một số loại lớp cơ sở cung cấp một cá thể log cho các lớp con (như một sự thuận tiện). Hãy xem xét ví dụ sau:

public abstract class Pet 
{ 
    protected Log log; 

    public Pet() 
    { 
     log = LogFactory.getLog(this.getClass()); 
    } 

    public void wash() 
    { 
     log.info("Get the hose."); 
    } 
    ... 
} 

public class Cat extends Pet 
{ 
    ... 
    public void doSomethingUseful() 
    { 
     log.warn("I can't, I am a cat."); 
    } 
} 

Trong ví dụ này, ghi nhật ký sẽ là từ bản sao nhật ký "Mèo". Đây có phải là một quy tắc hợp lệ vì không sử dụng trình ghi nhật ký tĩnh không? Có thể không cho các thư được ghi lại từ lớp Cat, nhưng các thư được ghi lại từ lớp Pet trong cá thể bản ghi của Cát có thể hữu ích.

0

Đây là một bài viết ngụ ý ngược lại. Trong thực tế, trong các tình huống phức tạp, các vấn đề tải lớp có thể phát sinh với các logger tĩnh trong các thư viện. Vì vậy, có, logger không tĩnh có thể được biện minh.

Tuy nhiên xem xét các trường hợp khi một lớp học sử dụng "private static Log log = ..." được triển khai thông qua một ClassLoader đó là trong tổ tiên của nhiều "ứng dụng" được cho là độc lập. Trong trường hợp này, thành viên nhật ký là được khởi tạo chỉ một lần, bởi vì chỉ có một bản sao của lớp. Sự khởi tạo đó (thường) xảy ra lần đầu tiên bất kỳ mã nào cố gắng để khởi tạo lớp đó hoặc gọi một phương thức tĩnh trên đó. Khi khởi tạo của lớp xảy ra, thành viên đăng nhập nào sẽ được đặt ?

http://wiki.apache.org/commons/Logging/StaticLog

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