2011-02-10 39 views
12

tôi đã được sử dụng khá nhiềuGetPropertyAction vs System.getProperty trong việc có được các biến hệ thống

System.getProperty("property") 

để có được thông tin về môi trường. Tuy nhiên, có vẻ như với tôi rằng Sun thích như sau:

(String) java.security.AccessController.doPrivileged(
       new sun.security.action.GetPropertyAction("property")); 

Điều lạ là mã này liên quan đến một dàn diễn viên và kết quả là nên hơi chậm hơn so với việc thực hiện

System.getProperty

, chỉ sử dụng trình quản lý bảo mật và sau đó lấy ngay thuộc tính từ đạo cụ biến thể hiện. Câu hỏi của tôi là tại sao Sun đã chọn để sử dụng phương pháp thứ hai để có được hầu hết các biến môi trường trong mã của họ trong nội bộ, trong khi

System.getProperty

có vẻ như cách nhanh hơn để đi đâu?

Trả lời

1

Tôi khuyên bạn nên gắn bó với System.getProperty()sun.security.action.GetPropertyAction dường như là độc quyền cho SUN và sẽ không hoạt động trên tất cả các triển khai Java VM. Ngay cả các trình biên dịch cảnh báo bạn về nó như:

cảnh báo: sun.security.action.GetPropertyAction là Sun API độc quyền và có thể được gỡ bỏ trong một thông cáo trong tương lai

Để hiểu những gì nó thực sự có nghĩa là thấy this answer.

+1

tôi biết ý nghĩa của nó và tôi biết rằng nó không được khuyến khích để sử dụng nó, đặc biệt là kể từ khi nó liên quan đến một dàn diễn viên và tạo ra một đối tượng mới. Tuy nhiên, những gì tôi đã tự hỏi là tại sao Sun sử dụng nó trong các triển khai của họ thay vì chỉ xung quanh System.getProperty trong một cuộc gọi đặc quyềnAction. –

8

Cả hai phương pháp đều có ý nghĩa khác nhau và do đó, phương thức phù hợp phải được sử dụng tùy thuộc vào mã hiện tại cần làm.

System.getProperty("property") nói "Hãy cho tôi giá trị của thuộc tính, nếu ngữ cảnh bảo mật hiện tại cho phép tôi đọc nó".

Mã sử ​​dụng doPrivileged cho biết "Hãy cho tôi giá trị của thuộc tính, nếu lớp hiện tại (nơi dòng mã này ở trong) được phép đọc nó."

Sự khác biệt có hiệu lực khi miền bảo vệ của lớp hiện tại khác với ngữ cảnh bảo mật hiện đang hoạt động.

Ví dụ: hãy xem xét một khung thực thi mã của plugin, không đáng tin cậy. Vì vậy, khung công tác sử dụng SecurityManager để hạn chế các hành động của mã plugin không đáng tin cậy. Nhưng tất nhiên plugin có thể gọi một số phương thức của khung công tác và giả sử rằng một trong các phương thức này cần phải đọc một thuộc tính. Bây giờ khi phương thức được gọi từ mã bị giới hạn không tin cậy, nó bị hạn chế và do đó việc đọc thuộc tính sẽ thất bại. Nhưng tất nhiên, khuôn khổ tin tưởng chính nó và muốn chính nó để có thể đọc tài sản đó, ngay cả trong trường hợp một nơi nào đó trong ngăn xếp cuộc gọi là mã không đáng tin cậy. Đó là khi bạn cần sử dụng doPrivileged. Về cơ bản nó nói "không có vấn đề gì là có trong ngăn xếp cuộc gọi, tôi là một đoạn mã khuôn khổ, và tôi được phép làm bất cứ điều gì mã khuôn khổ được phép làm". Vì vậy, đọc thuộc tính bằng cách sử dụng phương thức thứ hai thành công.

Tất nhiên, bạn cần cẩn thận khi sử dụng doPrivileged để không cho phép mã gọi (không đáng tin cậy) hoạt động nhiều.Nếu, ví dụ, đoạn code framework cung cấp các phương pháp sau đây để các plugin:

public String getProp(String key) { 
    return (String) java.security.AccessController.doPrivileged(
      new sun.security.action.GetPropertyAction(key)); 
} 

này hoàn toàn sẽ làm mất hiệu lực chủ trương rằng mã không tin cậy không được phép đọc thuộc tính hệ thống, bởi vì nó chỉ có thể sử dụng phương pháp của bạn.

Vì vậy, chỉ sử dụng phương pháp này khi bạn biết điều đó là an toàn để thực hiện và chỉ khi bạn cần nó (tức là khi bạn muốn mã của bạn có thể thực hiện nhiều hơn một số mã khác thì có thể thực hiện trực tiếp). Bên trong một ứng dụng bình thường (thường chạy không có SecurityManager hoặc cùng một ngữ cảnh bảo mật cho tất cả các mã), không có sự khác biệt và phương thức đầu tiên nên được sử dụng.

-1

Lý do sử dụng lớp như sun.security.action.GetPropertyAction là để tránh tải một số lớp cơ bản giống hệt nhau.

Nếu bạn đã viết:

(String) java.security.AccessController.doPrivileged(
    new java.security.PrivilegedAction<java.lang.String>() { 
     String run() { 
     System.getProperty("property"); 
     } 
    } 
); 

Mỗi khi bạn muốn để có được một tài sản của hệ thống, bạn sẽ nạp một lớp mới cho mỗi cuộc gọi getProperty. Mỗi lớp học lấy tài nguyên hệ thống và cuộc sống miễn là lớp chứa ClassLoader (mãi mãi cho bootclassloader).

Check-out đầu ra javap để biết thêm chi tiết:

javap -c -v -p sun.security.action.GetPropertyAction 
Các vấn đề liên quan