2009-01-28 23 views
9

Nuestro código utiliza muchas propiedades del sistema, por ejemplo, 'java.io.tmpdir', 'usuario.home', 'user.name', etc. No tenemos constantes definidas para estos en cualquier lugar (y tampoco creo que java) o cualquier otra cosa inteligente para tratar con ellos, por lo que están en texto sin formato en todo el código.Mejor práctica para usar las propiedades del sistema Java

String tempFolderPath = System.getProperty("java.io.tmpdir"); 

¿Cómo están utilizando las propiedades del sistema?

Respuesta

8

Lo trataría como cualquier otra constante de cadena que haya esparcido por su código y definiría una variable constante para él. De acuerdo, en este caso es poco probable que "java.io.tmpdir" cambie, pero nunca se sabe. (No me refiero a que Sun pueda cambiar el significado de "java.io.tmpdir", ni a qué propiedad del sistema apunte, sino que puede cambiar su opinión sobre qué propiedad del sistema necesita leer).

Si solo está utilizando una propiedad en particular dentro de una clase, entonces definiría las constantes en esa clase.

private final String TEMPDIR = "java.io.tmpdir"; 

Si estás usando las mismas propiedades en diferentes clases, es posible que desee definir una clase estática de su propia para mantener las constantes que utiliza más a menudo.

public final Class Prop { 
    public static final String TEMPDIR = "java.io.tmpdir"; 
    ... 
} 

Entonces, en todas partes es necesario utilizar esa constante llamarlo simplemente usando

System.getProperty(Prop.TEMPDIR); 
+0

Pero, ¿dónde harías eso? ¿Hace algún tipo de interfaz solo constantes en alguna parte solo para las propiedades del sistema? Nunca he sido un gran fan de ellos realmente. ¿Alguna sugerencia? – willcodejavaforfood

+0

Agregué un par de sugerencias diferentes, pero creo que para cadenas constantes en muchas clases diferentes, la interfaz que describes es la mejor. –

+0

Bastante justo. Pregunta Daft realmente :) – willcodejavaforfood

1

me gustaría tratar a estos como cualquier otra constante, probablemente con un prefijo o P_PROP_, y ponerlos en una clase de constantes apropiadas.

Si utiliza un montón de ellos, incluso me gustaría considerar dividir a cabo a una clase PropertyNames constantes:

public final class PropertyNames 
{ 
    private PropertyNames() 
    { 
    // no instantiation 
    } 

    public static final String P_VAR_DIRECTORY = "org.acme.app.varDir"; 

    public static final String P_TMP_DIRECTORY = "java.io.tmpDir"; 
} 

Por último, me gustaría considerar seriamente namespacing los nombres de propiedad a sí mismos, con el nombre de dominio inversa estándar utilizado para paquetes. Esto es solo para evitar chocar con los consumidores de propiedades de terceros.

+1

Estas propiedades no están definidas por mí, son propiedades del sistema y no puedo nombrarlos. – willcodejavaforfood

4

si lo está utilizando en varios lugares, puede ser una buena idea escribir una clase para encapsular la lectura de la propiedad y tal vez otras propiedades.

así que tal vez algo como: Configuration.getTemporaryDirectory()

3

Dado que el título de la pregunta es muy amplia, voy a tirar en otra buena práctica debe tener en cuenta cuando se utilizan las propiedades del sistema. El acceso a las propiedades del sistema puede por negada por el SecurityManager, por lo que puede necesitar para acceder a ellos a través de un PrivilegedAction, así:

String tmpdir = AccessController.doPrivileged(new PrivilegedAction<String>() { 
    public String run() { 
    return System.getProperty("java.io.tmpdir"); 
    } 
}); 

utilizar una acción privilegiada cuando el código restringe una acción sensible, por lo que será seguro, incluso si código malicioso lo invoca.

Por ejemplo, no sería seguro utilizar una acción privilegiada en un método como OutputStream open(File file). El código no confiable podría invocarlo, y usar los privilegios de su código para escribir cualquier cosa, en cualquier lugar.

Sin embargo, si tiene un método que guarda las preferencias del usuario para su aplicación en un archivo que elija, probablemente sea seguro. Un llamador malicioso no puede elegir la ubicación del archivo o su contenido; ésos son especificados por tu código.Por lo tanto, su método puede usar una acción privilegiada para permitir que sea invocado por un código sin privilegios.

4

Creo que en un software orientado a objetos, probablemente tiene un objeto (o un método) que tiene una dependencia en un directorio donde se debe realizar un trabajo. Entonces, puedes poner en evidencia esta dependencia en el constructor o el método. Después de eso, si necesita un valor predeterminado para ese directorio y el defecto proviene de una propiedad del sistema, sólo tiene que crear un método de fábrica o de un constructor/método con menos parámetros que pasa al otro costrunctor/Método A:

new File(System.getProperty("java.io.tmpdir"); 

No necesita crear un "imán de dependencia" solo para contener un parámetro de configuración.

0

En Java, las cadenas son inmutables, lo que significa que no se sobrescribe el mismo objeto en el espacio de la memoria; una nueva Cadena se crea todo el tiempo. La sugerencia actualmente más votada es utilizar una constante:

System.getProperty(Prop.TEMPDIR); 

Lamentablemente, la constante que se utiliza es para la clave de propiedad real. Eso significa que cada vez que realiza esta llamada, va a crear un nuevo objeto String para mantener el valor. En mi opinión, usted debe hacer la constante el resultado de la propia llamada:

public static final String SYS_PROP_TEMP_DIR = System.getProperty("java.io.tmpdir"); 
+1

Eso es incorrecto: no estás creando una Cadena, más bien, la JRE está devolviendo una referencia a una Cadena y es muy probable que te dé la misma en las siguientes, en lugar de crearla de nuevo. Sin embargo, todavía vale la pena hacer lo que sugieres porque la llamada 'System.getProperty()' es aparentemente bastante lenta: http://stackoverflow.com/a/18045622/587365 –

+1

y no hace daño encapsular el hecho de que eres obtener esta información de una propiedad del sistema. –

4

SystemUtils proporcionado por el paquete de Apache Commons Lang, resuelve este problema.

SystemUtils ha definido constante para la mayoría de las propiedades del sistema, que se pueden obtener mediante una búsqueda, por ejemplo:

import org.apache.commons.lang3.SystemUtils; 

class Something 
{ 
    public static void main(String[] args){  
     System.out.println(SystemUtils.JAVA_IO_TMPDIR); 
    } 
} 

Probablemente, esto es una forma más limpia de hacerlo.

Cuestiones relacionadas