2011-02-10 15 views
12

Używam sporoGetPropertyAction vs System.getProperty w uzyskaniu zmienne systemowe

System.getProperty("property") 

w celu uzyskania informacji o środowisku. Jednak wydaje mi się, że Sun preferuje następujące:

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

Najdziwniejsze jest to, że kod ten obejmuje obsadę iw rezultacie powinna być nieco wolniejszy niż realizacja

System.getProperty

, używa tylko menedżera bezpieczeństwa, a następnie natychmiast pobiera właściwość z rekwizytów zmiennych instancji. Moje pytanie brzmi, dlaczego Sun zdecydował się skorzystać z drugiej metody, aby uzyskać większość zmiennych środowiskowych w ich kodzie Wewnętrznie natomiast

System.getProperty

Wygląda na szybszy sposób, aby przejść?

Odpowiedz

1

Polecam trzymać się z System.getProperty() od sun.security.action.GetPropertyAction wydaje się być własnością SUN i nie będzie działać na wszystkich implementacjach Java VM. Nawet kompilator ostrzega o tym, jak:

ostrzeżenie: sun.security.action.GetPropertyAction jest Sun zastrzeżonych API i może zostać usunięta w przyszłych wydaniach

Aby zrozumieć, co to oznacza w rzeczywistości zobaczyć this answer.

+1

wiem, co to znaczy, a ja wiem, że nie zaleca się go używać, zwłaszcza, że ​​wiąże się to z obsady i tworzenia nowego obiektu. Jednak zastanawiałem się, dlaczego Sun używa go w swoich implementacjach, zamiast tylko otaczać System.getProperty w wywołaniu privilegedAction. –

8

Obie metody mają różne znaczenie, dlatego należy użyć właściwego, w zależności od tego, co powinien zrobić obecny kod.

Kod System.getProperty("property") mówi "Podaj wartość właściwości, jeśli obecny kontekst zabezpieczeń pozwala mi ją odczytać."

Kod, który używa doPrivileged mówi "Podaj mi wartość właściwości, jeśli aktualna klasa (gdzie znajduje się ta linia kodu) może ją odczytać."

Ta różnica ma zastosowanie, gdy domena ochrony obecnej klasy różni się od aktualnie aktywnego kontekstu zabezpieczeń.

Weźmy na przykład framework, który wykonuje kod wtyczki, która jest niezaufana. Tak więc framework używa SecurityManagera, aby ograniczyć działania niezaufanego kodu wtyczki. Oczywiście wtyczka może nazywać niektóre metody architektury i przypuszczać, że jedna z tych metod wymaga odczytania właściwości. Teraz, gdy metoda jest wywoływana z niezaufanego kodu ograniczonego, jest ona sama w sobie ograniczona i dlatego odczytanie właściwości zakończy się niepowodzeniem. Ale oczywiście framework ufa sobie i chce, aby był w stanie odczytać tę właściwość, nawet w przypadku, gdy gdzieś w stosie wywołań jest niezaufany kod. Wtedy musisz użyć doPrivileged. Zasadniczo mówi "bez względu na to, co jest tam w stosie wywołań, jestem fragmentem kodu ramowego, i mam pozwolenie na zrobienie tego, co może zrobić kod strukturalny". Czytanie nieruchomości za pomocą drugiej metody kończy się sukcesem.

Oczywiście należy zachować ostrożność podczas korzystania z doPrivileged, aby nie dopuścić do (niezaufanego) kodu wywołującego.Jeśli, na przykład, kod ramy oferuje następujące metody do wtyczki:

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

byłoby całkowicie unieważnia zasadę, że kod niezaufane nie może odczytać właściwości systemu, ponieważ może po prostu użyć metody.

Używaj tej metody tylko wtedy, gdy wiesz, że jest to bezpieczne i tylko wtedy, kiedy jej potrzebujesz (czyli, kiedy chcesz, aby twój kod był w stanie zrobić więcej niż jakiś inny kod powinien być w stanie zrobić bezpośrednio). Wewnątrz zwykłej aplikacji (która zwykle działa bez Menedżera zabezpieczeń lub tego samego kontekstu bezpieczeństwa dla całego kodu), nie ma różnicy i należy zastosować pierwszą metodę.

-1

Powodem użycia klasy takiej jak sun.security.action.GetPropertyAction jest uniknięcie ładowania kilku, w zasadzie identycznych klas.

Jeśli napisałeś:

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

każdym razem, gdy chcieliśmy dostać się właściwości systemu, należy załadować nową klasę dla każdego wywołania GetProperty. Każda klasa pobiera zasoby systemowe i żyje tak długo, jak zawierająca ClassLoader (na zawsze dla bootclassloadera).

Sprawdź wyjście javap więcej szczegółów:

javap -c -v -p sun.security.action.GetPropertyAction 
Powiązane problemy