estado tratando de llegar a una buena solución a esto mismo que
- gira en torno a la creación de un XSD para el archivo de configuración - ya que en mi mente todo el beneficio del uso de XML es que puede escribir fuertemente el archivo de configuración, en términos de tipos de datos, y qué campos son obligatorios/opcionales
- Validará el XML contra el XSD, por lo que si falta un valor arrojará un error en lugar de que su bean sea inyectado con un 'nulo '
- No confía en las anotaciones de primavera (como @Value - en mi opinión eso le da conocimiento sobre frijoles ut su contenedor + relación con otros beans, por lo que rompe COI)
- Validará el XML de primavera frente al XSD, por lo que si intenta hacer referencia a un campo XML no presente en el XSD, arrojará también un error
- El bean no tiene conocimiento de que sus valores de propiedad se estén inyectando desde XML (es decir, Quiero inyectar propiedades individuales, y no el objeto XML como un todo)
Lo que se me ocurrió es la siguiente, disculpas, esto es bastante largo, pero me gusta como una solución ya que creo que cubre todo. Espero que esto pueda serle útil a alguien. piezas triviales primeros:
El grano Quiero valores de las propiedades inyectados en:
package com.ndg.xmlpropertyinjectionexample;
public final class MyBean
{
private String firstMessage;
private String secondMessage;
public final String getFirstMessage()
{
return firstMessage;
}
public final void setFirstMessage (String firstMessage)
{
this.firstMessage = firstMessage;
}
public final String getSecondMessage()
{
return secondMessage;
}
public final void setSecondMessage (String secondMessage)
{
this.secondMessage = secondMessage;
}
}
clase de prueba para crear el grano de arriba y volcar los valores de propiedad que ya ha recibido:
package com.ndg.xmlpropertyinjectionexample;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Main
{
public final static void main (String [] args)
{
try
{
final ApplicationContext ctx = new ClassPathXmlApplicationContext ("spring-beans.xml");
final MyBean bean = (MyBean) ctx.getBean ("myBean");
System.out.println (bean.getFirstMessage());
System.out.println (bean.getSecondMessage());
}
catch (final Exception e)
{
e.printStackTrace();
}
}
}
MyConfig.xsd : archivo MyConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:myconfig="http://ndg.com/xmlpropertyinjectionexample/config" targetNamespace="http://ndg.com/xmlpropertyinjectionexample/config">
<xsd:element name="myConfig">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="someConfigValue" type="xsd:normalizedString" />
<xsd:element minOccurs="1" maxOccurs="1" name="someOtherConfigValue" type="xsd:normalizedString" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Muestra basado en el XSD:
<?xml version="1.0" encoding="UTF-8"?>
<config:myConfig xmlns:config="http://ndg.com/xmlpropertyinjectionexample/config">
<someConfigValue>First value from XML file</someConfigValue>
<someOtherConfigValue>Second value from XML file</someOtherConfigValue>
</config:myConfig>
de fragmentos de pom.xml para funcionar xsd2java (no había mucho más aquí además de establecer a Java 1.6, y la dependencia de primavera-contexto):
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<id>main-xjc-generate</id>
<phase>generate-sources</phase>
<goals><goal>generate</goal></goals>
</execution>
</executions>
</plugin>
Ahora el XML propio muelle. Esto crea un esquema/validador, a continuación, utiliza JAXB para crear un unmarshaller para crear un POJO del archivo XML, a continuación, utiliza la primavera # anotación para inyectar valores de propiedad por quering el POJO:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd" >
<!-- Set up schema to validate the XML -->
<bean id="schemaFactory" class="javax.xml.validation.SchemaFactory" factory-method="newInstance">
<constructor-arg value="http://www.w3.org/2001/XMLSchema"/>
</bean>
<bean id="configSchema" class="javax.xml.validation.Schema" factory-bean="schemaFactory" factory-method="newSchema">
<constructor-arg value="MyConfig.xsd"/>
</bean>
<!-- Load config XML -->
<bean id="configJaxbContext" class="javax.xml.bind.JAXBContext" factory-method="newInstance">
<constructor-arg>
<list>
<value>com.ndg.xmlpropertyinjectionexample.config.MyConfig</value>
</list>
</constructor-arg>
</bean>
<bean id="configUnmarshaller" class="javax.xml.bind.Unmarshaller" factory-bean="configJaxbContext" factory-method="createUnmarshaller">
<property name="schema" ref="configSchema" />
</bean>
<bean id="myConfig" class="com.ndg.xmlpropertyinjectionexample.config.MyConfig" factory-bean="configUnmarshaller" factory-method="unmarshal">
<constructor-arg value="MyConfig.xml" />
</bean>
<!-- Example bean that we want config properties injected into -->
<bean id="myBean" class="com.ndg.xmlpropertyinjectionexample.MyBean">
<property name="firstMessage" value="#{myConfig.someConfigValue}" />
<property name="secondMessage" value="#{myConfig.someOtherConfigValue}" />
</bean>
</beans>
Eso es sin duda muy útil para saber, y será una práctica copia de seguridad.Supongo que es bastante fácil anular PropertiesPersister para implementar el análisis del estilo de Apache Digester, en lugar del formato xml de propiedades estándar. – GaryF
¿Qué se necesita para crear algo que cargue archivos xml personalizados (sin propiedades) usando cargadores de recursos? –