Discover Spring's PropertyEditor

Source: Internet
Author: User

Discover Spring's PropertyEditor

Today, a netizen consulting a question let me have a deep understanding of spring's propertyeditor mechanism, although it is probably known before, but all know what it is, but do not know how it is implemented in spring's entire mechanism. Today, take advantage of the noon leisure time to see the spring source of this aspect. So here is mainly through the analysis of spring source to understand PropertyEditor .

In fact, the Java.beans in the JDK is the PropertyEditor following class, which is provided by AWT for rendering purposes. Spring uses this interface to implement a Bean's property converter. The bean properties that we configure in spring XML or other ways are string-type values, but corresponding to each specific property is of various types, spring uses various types to PropertyEditor convert the properties, which is PropertyEditor not directly implemented in spring PropertyEditorinterface is a PropertyEditorSupport class that blocks some of the methods that spring does not need, such as paintValue providing a default implementation for them, so spring PropertyEditor is implemented on a PropertyEditorSupport basis. Let's take a look at PropertyEditor the implementations that spring provides, and the following captures the implementation classes found through the IDE tools:

This basically involves all of the types provided by the JDK, knowing what Spring provides PropertyEditor and PropertyEditor how these are embedded in spring.

Propertyeditorregistry

Here is PropertyEditor An example of how spring will be embedded within the spring framework BeanWrapperImpl . First look at BeanWrapperImpl the class diagram:

You can see BeanWrapperImpl PropertyEditorRegistry the sub-class that is actually. PropertyEditorRegistryis actually an interface, to do the specific thing is PropertyEditorRegistrySupport . PropertyEditorRegistrySupportthere is a method in which createDefaultEditors this method is initialized by default in spring PropertyEditor . Here's a look at which spring defaults PropertyEditor :

private void Createdefaulteditors () {this.defaulteditors = new Hashmap<class<?>, propertyeditor> (64);    Simple editors, without parameterization capabilities.    The JDK does not contain a default editor for any of these target types.    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 (Properties.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 ());    Default instances of collection editors.    Can is overridden by registering custom instances of those as custom editors.    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.class));    This.defaultEditors.put (Sortedmap.class, New Custommapeditor (Sortedmap.class));    Default editors for primitive arrays.    This.defaultEditors.put (Byte[].class, New Bytearraypropertyeditor ());    This.defaultEditors.put (Char[].class, New Chararraypropertyeditor ()); The JDK does not conTain a default editor for char!    This.defaultEditors.put (Char.class, new Charactereditor (false));    This.defaultEditors.put (Character.class, New Charactereditor (true));    Spring ' s custombooleaneditor accepts more flag values than the JDK ' s default editor.    This.defaultEditors.put (Boolean.class, new Custombooleaneditor (false));    This.defaultEditors.put (Boolean.class, New Custombooleaneditor (true));    The JDK does not contain default editors for number wrapper types!    Override JDK Primitive number editors with our own customnumbereditor.    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));    Only register config value editors if explicitly requested.        if (this.configvalueeditorsactive) {Stringarraypropertyeditor SAE = new Stringarraypropertyeditor ();      This.defaultEditors.put (String[].class, SAE);  This.defaultEditors.put (Short[].class, SAE);        This.defaultEditors.put (Int[].class, SAE);    This.defaultEditors.put (Long[].class, SAE); }}

After executing this, then you BeanWrapperImpl have the above type of conversion function, perhaps the above can be converted to the type does not meet our needs, then you can inject propertyeditor into spring in another way.

Propertyeditorregistrar

This interface has only one method void registerCustomEditors(PropertyEditorRegistry registry) , the implementation of this method can be added to the incoming registry custom, in general, the PropertyEditor incoming registry BeanWrapperImpl entity, so it is equivalent to inject the custom PropertyEditor into the BeanWrapperImpl inside. The question now is how PropertyEditorRegistrar to inject into spring, so you can PropertyEditor add custom to spring. Spring provides a class that is designed to inject a third party PropertyEditor into it, and this class is a CustomEditorConfigurer first look at the class diagram of this class:

Find that it implements the BeanFactoryPostProcessor interface, then the method will be BeanDefinition called after construction, postProcessBeanFactory and only the whole method is the only way to embed spring, then look at what this method does:

public void Postprocessbeanfactory (Configurablelistablebeanfactory beanfactory) throws Beansexception {if (this.prope Rtyeditorregistrars! = null) {for (Propertyeditorregistrar PropertyEditorRegistrar:this.propertyEditorRegistrars        ) {Beanfactory.addpropertyeditorregistrar (Propertyeditorregistrar); }} if (this.customeditors! = null) {for (map.entry<string,?> entry:this.customEditors.entrySet ())            {String key = Entry.getkey ();            Object value = Entry.getvalue ();            Class requiredtype = null;                try {requiredtype = Classutils.forname (key, This.beanclassloader); if (value instanceof propertyeditor) {if (logger.iswarnenabled ()) {Logger.warn ("Passing propertyeditor instances into Customeditorconfigurer are deprecated:" + "use Prop Ertyeditorregistrars or PropertyEditor class names instead.        " +                        "Offending key [" + Key + ";                    Offending editor Instance: "+ value"; } beanfactory.addpropertyeditorregistrar (New Sharedpropertyeditorregistrar (                Requiredtype, (propertyeditor) value); } else if (value instanceof Class) {beanfactory.registercustomeditor (Requiredtype, (Cla                SS) value); } else if (value instanceof String) {Class Editorclass = classutils.forname (String) VA                    Lue, This.beanclassloader);                    Assert.isassignable (Propertyeditor.class, Editorclass);                Beanfactory.registercustomeditor (Requiredtype, Editorclass); } else {throw new IllegalArgumentException ("Mapped value [" + Value + "] for custom EDI           Tor key ["+ key +"] is not of required type ["+ PropertyEditor.class.getName () +                 "] or a corresponding Class or String value indicating a propertyeditor implementation");                    }} catch (ClassNotFoundException ex) {if (this.ignoreunresolvableeditors) {                            Logger.info ("Skipping editor [" + value + "] for required type [" + Key + "]:" + (Requiredtype! = null?)                "Editor": "Required type") + "class not found."); } else {throw new Fatalbeanexception ((requiredtype! = null ?                "Editor": "Required Type") + "class not Found", ex); }            }        }    }}

It is found that the methods it calls are beanFactory configured PropertyEditorRegistrar and customEditors injected into the Spring bean factory. We just inject a Bean into the spring container CustomEditorConfigurer , and then the settings propertyEditorRegistrars and customEditors properties can inject the custom PropertyEditor into spring. Of course you can also use CustomEditorConfigurer a class to customize a class to implement an BeanFactoryPostProcessor interface, and then follow CustomEditorConfigurer a similar path, or you can achieve the purpose. Here is a custom PropertyEditor approximate process:

public class CustomPropertyEditor extends PropertyEditorSupport {@Overridepublic void setAsText(String text) throws IllegalArgumentException {    super.setAsText(text);}@Overridepublic Object getValue() {    return super.getValue();}}

The above is a definition of a customization PropertyEditor , which needs to be PropertyEditor injected into spring:

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">    <property name="customEditors">        <map>            <entry key="com.xx.foo.FooPojo" value="com.xx.foo.CustomPropertyEditor"/>        </map>    </property></bean>

Spring invokes methods to set the literal setAsText value of the property, and then it needs to be converted to the corresponding Property object according to the specification you specify.

The following gives an ClassEditor implementation, you can imitate this to achieve:

  public class Classeditor extends PropertyEditorSupport {private final ClassLoader classloader;/** * Create a de Fault classeditor, using the thread context ClassLoader. */public Classeditor () {this (null);} /** * Create A default classeditor, using the given ClassLoader. * @param classLoader the ClassLoader to use * (or {@code null} for the thread context ClassLoader) */public Classeditor (Cl Assloader classLoader) {This.classloader = (ClassLoader! = null? ClassLoader:ClassUtils.getDefaultClassLoader ());} @Overridepublic void Setastext (String text) throws IllegalArgumentException {if (Stringutils.hastext (text)) {s    Etvalue (Classutils.resolveclassname (Text.trim (), This.classloader));    } else {setValue (null);    }} @Overridepublic String Getastext () {Class clazz = (Class) GetValue ();    if (clazz! = null) {return classutils.getqualifiedname (clazz);    } else {return ""; }}}

Exploring Spring's PropertyEditor

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.