java - leer - propertysourcesplaceholderconfigurer
Archivos Java.properties como clases fuertemente tipadas (8)
Hay innumerables marcos que logran eso para XML con varios grados de configuración necesarios. El estándar incluido con Java es JaxB, pero no es exactamente un framework de persistencia xml de liner ...
El problema es que usar el archivo de propiedades solo funcionará mejor que XML (o JSON, ...) en las clases más triviales. Cuando la clase se vuelva un poco más compleja, el archivo de propiedades se convertirá en una pesadilla. Otro problema es que con las clases triviales, no hay mucha diferencia entre Xml y las propiedades.
Eso significa que el alcance del proyecto será bastante limitado. Principalmente útil para proyectos que tienen un montón de archivos de propiedades simples.
En la gran aplicación con la que trabajé, la lectura de propiedades de tipo fuerte se realiza con bastante frecuencia utilizando un método de fábrica simple.
Foo foo = Foo.loadFrom("foo.properties");
class Foo {
static Foo loadFrom(String fileName) {
Properties props = new Properties();
props.load(...);
Foo foo = new Foo();
foo.setKeyFoo(props.get("KeyFoo"));
...
return foo;
}
...
}
¿Hay alguna forma de obtener archivos de propiedades como clases fuertemente tipadas? Supongo que hay generadores de código pero hacerlo con anotaciones sería mucho más genial.
Lo que quiero decir es;
foo.properties file
keyFoo = valuefoo
keyBar = valuebar
tal vez con
@properties(file="foo.properties")
class foo { }
se convierte
class foo {
String getKeyFoo() { }
String getKeyBar() { }
}
si no, ¿debo comenzar un proyecto de código abierto para eso?
ADICIÓN A LA PREGUNTA;
Creo que tenemos un archivo foo.properties con, por ejemplo, más de 10 entradas; y creo que se usa como un archivo de configuración simple. Lo que creo es que estas entradas de configuración se deben proporcionar como una clase de configuración con métodos getXXX relacionados a otras partes del diseño. Luego, el resto del sistema accede a la configuración a través de la clase proporcionada en lugar de tratar con los nombres de las claves y no necesita preocuparse de dónde viene la configuración. Luego puede reemplazar esta clase con un simulacro cuando está probando llamadas y la dependencia al sistema de archivos desaparece. Por otro lado, es realmente agradable obtener todas las entradas de una manera fuertemente tipada.
Entonces, este problema es un problema de generación de código entre bastidores, no está relacionado con el tiempo de ejecución. Pero la generación de código con algo externo en lugar de anotaciones no me pareció agradable. Aunque no estoy muy familiarizado con las anotaciones, creo que esto podría lograrse (pero tendré en cuenta que las anotaciones no pueden generar clases como señala McDowell).
Hay un proyecto similar para hacer la configuración como archivos estáticos. Requiere declarar una interfaz, pero completa la implementación en sí misma:
public interface AppConfig extends Config {
long getTimeout ();
URL getURL ();
Class getHandlerClass ();
}
La Herramienta de procesamiento de anotaciones ( apt ) no puede modificar clases (aunque puede crear nuevas). Para modificar la clase en tiempo de compilación, probablemente necesite editar AST (como hace el Proyecto Lombok ). El enfoque más simple probablemente sería generar las clases y luego usar la biblioteca generada como una dependencia para otro código.
Si desea hacerlo estáticamente, es un problema de generación de código que puede resolverse con bastante facilidad (para cada elemento del archivo, getXXX
un nuevo método getXXX
).
Pero si desea esto en tiempo de ejecución, entonces tiene el problema de tener su método de referencia de código que no existía en el momento de la compilación; No creo que se pueda hacer.
(Tenga en cuenta que si está buscando una idead de proyecto, se puede hacer lo contrario, tener una interfaz con el método y la anotación de acceso, y una implementación generada en tiempo de ejecución, que se basa en los métodos anotados).
El OP desea asignar un archivo de propiedades a una API de Java de modo que cada propiedad con nombre en el archivo corresponda a un método getter con un nombre similar en la API. Supongo que una aplicación usaría esta API para obtener valores de propiedad sin tener que usar cadenas de nombre de propiedad.
El problema conceptual es que un archivo de propiedades no es fundamentalmente una entidad estáticamente estática. Cada vez que alguien edita un archivo de propiedades, puede agregar nuevas propiedades y, por lo tanto, cambiar el "tipo" del archivo de propiedades ... y, por implicación, la firma de la API correspondiente. Si verificamos que no hubo propiedades inesperadas cuando la aplicación Java cargó el archivo de propiedades, entonces tenemos una verificación de tipo dinámica explícita. Si no buscamos propiedades inesperadas (por ejemplo, mal nombradas), tenemos una fuente de errores. Las cosas se vuelven aún más complicadas si desea que los tipos de valores de las propiedades sean algo más que una Cadena.
La única forma en que podría hacerlo correctamente sería inventar el concepto de un esquema para un archivo de propiedades que especifica los nombres de las propiedades y los tipos de los valores de las propiedades. Luego, implemente un editor de archivos de propiedades que garantice que el usuario no pueda agregar propiedades que entren en conflicto con el esquema.
Y en este punto debemos reconocer que una mejor solución sería usar XML como la representación del archivo de propiedades, un editor de esquemas XML para editar archivos de propiedades, y JAXP o algo similar para mapear el archivo de propiedades a las API de Java.
Otra forma más es utilizar un marco de enlace de datos que hace esto. Incluso uno que no parece respaldar directamente eso podría funcionar: por ejemplo, el procesador Jackson JSON permitiría que esto se hiciera de la siguiente manera:
ObjectMapper m = new ObjectMapper (); MyBean bean = m.convertValue (properties, MyBean.class); // (nota: requiere el código más reciente del tronco; de lo contrario, es necesario escribir primero, leer de nuevo)
que funciona siempre que las entradas en el mapa de propiedades coincidan con las propiedades lógicas de los beans, y los valores de cadena se pueden convertir a valores subyacentes coincidentes.
¿Algo como JFig (feo IMO), Commons Configuration o EasyConf ?
Creo que esto resolverá su problema que he escrito en este marco de propiedad durante el último año. Proporcionará múltiples formas de cargar propiedades, y las tendrá fuertemente tipadas también.
Eche un vistazo a http://sourceforge.net/projects/jhpropertiestyp/
Es de fuente abierta y completamente documentado
Aquí está mi breve descripción de SourceForge:
JHPropertiesTyped will give the developer strongly typed properties. Easy to integrate in existing projects. Handled by a large series for property types. Gives the ability to one-line initialize properties via property IO implementations. Gives the developer the ability to create own property types and property io''s. Web demo is also available, screenshots shown above. Also have a standard implementation for a web front end to manage properties, if you choose to use it.
Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage.