Red de conocimiento informático - Problemas con los teléfonos móviles - ¿Cuál es la función del editor de propiedades Spring?

¿Cuál es la función del editor de propiedades Spring?

Después de analizar la definición del bean a través del analizador xml, la definición analizada es una cadena, pero las propiedades del bean pueden ser varios tipos de Java, por lo que al inicializar el bean, debe seleccionar entre estas cadenas y tipos java. Por ejemplo, mi bean tiene un atributo de clase. Al inyectar el atributo de clase, solo puede establecer un valor de cadena = "a.b.C" para el atributo, y el marco debe agregarlo al completar el atributo al final. "a.b.C" se convierte en un objeto de clase. b.C", y cuando el marco finalmente completa la propiedad, necesita convertir "a.b.C" en un objeto Clase.

¿Cómo se realiza este trabajo? Es el editor de propiedades.

El proceso de PropertyEditor es el siguiente:

Llame a setAsText para pasar el texto a procesar a PropertyEditor. PropertyEditor convertirá el texto en un valor del tipo correspondiente y lo guardará en PropertyEditor.

Llame a getValue para convertir el valor en los pasos anteriores

A través del proceso anterior, puede encontrar que PropertyEditor guardará el valor, por lo que no es seguro para subprocesos, por lo que debe sincronizar el proceso de conversión del valor

PropertyEditor incorporado

Spring Framework tiene múltiples PropertyEditors incorporados antes de que estos PropertyEditors se agreguen al BeanWrapper y el Bean complete las propiedades (en el Bean). análisis de fuente de inicialización del contenedor Spring IOC), el código se encuentra en el método createDefaultEditors de la clase PropertyEditorRegistrySupport Medio: private?void?createDefaultEditors()?{

this.defaultEditors?=?new?HashMaplt ;Classlt;?gt;,?PropertyEditorgt;(64);?

/ /?

//?El JDK no contiene un editor predeterminado para ninguno de estos tipos de destino.

this.defaultEditors.put(Charset.class,?new?CharsetEditor());?

this.defaultEditors.put(Class.class,?new?ClassEditor()) ;?

this.defaultEditors.put(Class[].class,?new?ClassArrayEditor());?

this.defaultEditors.put(Currency.class,?new? CurrencyEditor());?

this.defaultEditors.put(File.class,?new?FileEditor());?

this.defaultEditors.put(InputStream.class,? new?InputStreamEditor());?

this.defaultEditors.put(InputSource.class,?new?InputSourceEditor());?

this.defaultEditors.put(Locale.class ,?new?LocaleEditor());?

this.defaultEditors.put(Pattern.class,?new?PatternEditor());?

this.defaultEditors.put(Propiedades .class,?new?PropertiesEditor());?

this.defaultEditors.put(Resource[].class,?new?ResourceArrayPropertyEditor());?

this.defaultEditors .put(TimeZone.class,?new?TimeZoneEditor());?

this.defaultEditors.put(URI.class,?new?URIEditor());?

this .defaultEditors.put(URL.class,?new?URLEditor());?

this.defaultEditors.put(UUID.class,?new?UUIDEditor());?

//?

//?

this.defaultEditors.put(Collection.class,?new?CustomCollectionEditor(Collection.class));?

this.defaultEditors.put(Set.class,?new?CustomCollectionEditor(Set.class));?

this.defaultEditors.put(SortedSet.class,?new?CustomCollectionEditor(SortedSet.class)); ?

this.defaultEditors.put(List.class,?new?CustomCollectionEditor(List.

clase));?

this.defaultEditors.put(SortedMap.class,?new?CustomMapEditor(SortedMap.class));?

//?

this.defaultEditors.put(byte[].class,?new?ByteArrayPropertyEditor());?

this.defaultEditors.put(char[].class,?new?CharArrayPropertyEditor());?

//?JDK ¡Editor predeterminado sin caracteres! ?

this.defaultEditors.put(char.class,?new?CharacterEditor(false));?

this.defaultEditors.put(Character.class,?new?CharacterEditor( true));?

//?El editor booleano personalizado de Spring acepta más valores de bandera que el editor predeterminado del JDK.

this.defaultEditors.put(boolean.class,?new?CustomBooleanEditor(false));?

this.defaultEditors.put(boolean.class,?new?CustomBooleanEditor(true) ) ));?

//?JDK no contiene un editor predeterminado para tipos de paquetes numéricos.

//?Reemplace el editor de números original JDK con nuestro propio editor de números personalizado.

this.defaultEditors.put(byte.class,?new?CustomNumberEditor(Byte.class,?false));?

this.defaultEditors.put(Byte.class,? new?CustomNumberEditor(Byte.class,?true));?

this.defaultEditors.put(short.class,?new?CustomNumberEditor(Short.class,?false));?

this.defaultEditors.put(Short.class,?new?CustomNumberEditor(Short.class,?true));?

this.defaultEditors.put(int.class,?new?CustomNumberEditor( Integer.class,?false));?

this.defaultEditors.put(Integer.class,?new?CustomNumberEditor(Integer.class,?true));?

this .defaultEditors.put(long.class,?new?CustomNumberEditor(Long.class,?false));?

this.defaultEditors.put(Long.class,?new?CustomNumberEditor(Long.class, ?true));?

this.defaultEditors.put(float.class, ?new?CustomNumberEditor(Float.class, ?false));?

this.defaultEditors.put (Float.class,?new?CustomNumberEditor(Float.class,?true));?

this.defaultEditors.put(double.class,?new?CustomNumberEditor(Double.class,?false)) ;?

this.defaultEditors.put(double.class,?new?CustomNumberEditor(double.class,?true));?

this.defaultEditors.put(BigDecimal.class ,?new?CustomNumberEditor(BigDecimal.class,?true));?

this.defaultEditors.put(BigInteger.class,?new?CustomNumberEditor(BigInteger.class,?true));? p>

//?

if(this.configValueEditorsActive)?{

¿Si?(this.configValueEditorsActive)?

StringArrayPropertyEditor?sae ?= ?nuevo?Stri

ngArrayPropertyEditor();?

this.defaultEditors.put(String[].class,?sae);?

this.defaultEditors.put(short[].class,?sae ) );?

this.defaultEditors.put(int[].class,?sae);?

this.defaultEditors.put(long[].class,?sae) ?

}?

}

Además, algunos PropertyEditors relacionados con recursos están integrados. El código se encuentra en el método RegisterCustomEditors de la clase ResourceEditorRegistrar. :

public?void?registerCustomEditors(PropertyEditorRegistry?registry)?{

ResourceEditor?baseEditor?=?new?ResourceEditor(this.resourceLoader,?this.propertyResolver);?

doRegisterEditor(registro,?Resource.class,?baseEditor);?

doRegisterEditor(registro,?ContextResource.class,?baseEditor);?

doRegisterEditor(registro) ,?InputStream.class ,?new?InputStreamEditor(baseEditor));?

doRegisterEditor(registro,?InputSource.class,?new?InputSourceEditor(baseEditor));?

doRegisterEditor (registro,?Archivo .clase,?nuevo?FileEditor(baseEditor));?

doRegisterEditor(registro,?URL.clase,?nuevo?URLEditor(baseEditor));?

ClassLoader?classLoader? =?this.resourceLoader.getClassLoader();?

doRegisterEditor(registro,?URI.class,?new?URIEditor(classLoader));?

doRegisterEditor (registro,?Clase .clase,?nuevo?ClassEditor(classLoader));?

doRegisterEditor(registro,?Clase[].clase,?nuevo?ClassArrayEditor(classLoader));?

if( this.resourceLoader instancia de?ResourcePatternResolver)?{

doRegisterEditor(registro,?Resource[]

.class,?

new?ResourceArrayPropertyEditor((ResourcePatternResolver)?this.resourceLoader,?this.propertyResolver));?

}?

}

ResourceEditorRegistrar es el registro PropertyEditor integrado del marco. Es un BFPP agregado al contenedor cuando se inicia ClasspathXmlApplicationContext. El código específico se analiza en el archivo de configuración de inicio del contenedor Spring IOC.

Editor de propiedades personalizado

Cuando el PropertyEditor integrado de Spring no puede cumplir con nuestros requisitos, podemos personalizar el PropertyEditor según el mecanismo de extensión proporcionado por Spring. Como ejemplo de cómo implementar un PropertyEditor personalizado, mi PropertyEditor es un editor relacionado con el tiempo que puede convertir cadenas que se ajustan a un formato de tiempo específico en objetos de fecha.

Primero, defina PropertyEditor. El marco proporciona la clase base PropertyEditor PropertyEditorSupport. Heredar directamente esta clase puede guardar algo de código.

public?class?DateEditor? extiende?PropertyEditorSupport?{ ?

privado?DateFormat?dateFormat;?

público?void?setDateFormat(String?dateFormat)?{?dateFormat(String?dateFormat)?

este .dateFormat?=?new?SimpleDateFormat(dateFormat);?

}?

@Override?

public?void?setAsText( String?text)? throws?IllegalArgumentException?{?

intenta?{?

Object?value?=?dateFormat.parse(texto);?

setValue(valor); ?

}?{

e.printStackTrace();?

}?

}

@Override?{

if(getValue()?instanciade?Fecha)?{

¿Fecha?(Fecha)?getValue();?

return.dateFormat.format(d);?

}?

return.super.getAsText();?

}? >

}

dateFormat es el formato de fecha que el usuario necesita inyectar

El siguiente paso es inyectar DateEditor en el contenedor. El marco proporciona una clase BFPP llamada CustomEditorConfigurer. para completar este trabajo.

Simplemente inyecte el DateEditor en este Bean BFPP, existen varios métodos de inyección:

Inyección a través de la propiedad customEditors, que es una propiedad Map en CustomEditorConfigurer donde la clave es una cadena de tipo y el valor es una instancia de En la instancia de PropertyEditor, el fragmento de configuración xml es el siguiente:lt;bean?class="org.springframework.beans.factory.config.CustomEditorConfigurer"gt;?

lt;property?name="customEditors" gt;?

lt;mapgt;?

lt;entry?key="java.util.Date"?value-ref="dateEditor"gt;/entrygt; ?

lt;/mapgt;?

lt;/propertygt;?

lt;/beangt;?

lt;bean ?id="dateEditor" ?class="spring.beans.propertyeditor.DateEditor"gt;?

lt;property?name="dateFormat"?value="aaaa-MM-dd?HH:mm :ss"?

p>

lt;property?name="dateFormat"?

lt;/beangt;

Utilice un frijol de prueba y un trozo de código de prueba para probar:lt;bean?id= "dateBean"?class="spring.beans.propertyeditor.DateBean"gt;?

lt;constructor-arg?value="2014-06-01 ?09:21:20"gt;lt; /constructor-arggt;?

lt;/beangt;@Test?

public?void?test()?{

Contexto BeanFactory = new.ClassPathXmlApplicationContext (?

"spring/beans/propertyeditor/propertyeditor1.xml");?

DateBean?(DateBean)?context.getBean ("dateBean");?

System.out.println(dateBean.getDate());?

}

Imprimir el resultado

Se mencionó Sun? PropertyEditor al principio de este blog. No es seguro para subprocesos y, por lo tanto, requiere sincronización durante el procesamiento, lo que significa que en situaciones de alta concurrencia, la sincronización tendrá un gran impacto en el rendimiento de la aplicación. Por lo tanto, este método no se recomienda; de hecho, Spring lo ha marcado como obsoleto.

Para solucionar los problemas de rendimiento anteriores, podemos modificar la configuración:

lt;bean?class="org.springframework.beans.factory.config.CustomEditorConfigurer"gt; ?

lt;property?name="customEditors"gt;?

lt;mapgt;?

lt;entry?key="java.util. Fecha"?valor ="spring.beans.propertyeditor.DateEditor"gt;lt;/entrygt;?

lt;/mapgt;?

lt;/propertygt;?

lt;/beangt;?

La configuración anterior inyecta la clase DateEditor en la propiedad customEditors. En este caso, se creará un nuevo objeto PropertyEditor y se registrará con BeanWrapper cuando el Bean esté activo. inicializado (consulte "Análisis del código fuente de inicialización de Spring IOC Container Bean" (puede consultar "Análisis del código fuente de inicialización de Spring IOC Container Bean"), de modo que PropertyEditor sea un estado de objeto independiente y diferente, y los problemas de sincronización anteriores no ocurrirán. Pero todavía hay un problema: este DateEditor es necesario inyectar propiedades, y la instanciación de PropertyEditor no puede ser interferida por la capa de aplicación, por lo que no puede inyectar la propiedad dateFormat en el objeto DateEditor, por lo que este método no puede satisfacer nuestras necesidades. , solo se puede aplicar cuando no es necesario inyectar. En el caso de PropertyEditor, para nuestras necesidades, solo se puede lograr inyectando propertyEditorRegistrars, que es la matriz de registro de propertyEditor de CustomEditorConfigurer. Su responsabilidad es registrar PropertyEditors. se puede registrar cualquier número. Para utilizar un PropertyEditor, primero debe definir un registro:

public?class?CustomPropertyEditorRegistrar?implementations?PropertyEditorRegistrar?{?

¿público?{

¿regresar?

}

¿público?{

this.dateFormat = dateFormat;?

}?

@Override

public?void?registerCustomEditors(PropertyEditorRegistry?registry)?{

DateEditor?

dateEditor .setDateFormat(dateFormat);?

registry.registerCustomEditor(Date.class,?dateEditor);?

}

}

}?