javascript
Spring5参考指南: BeanWrapper和PropertyEditor
文章目錄
- BeanWrapper
- PropertyEditor
BeanWrapper
通常來說一個Bean包含一個默認的無參構造函數,和屬性的get,set方法。
org.springframework.beans 包里面有個很重要的類叫做BeanWrapper接口和他的實現BeanWrapperImpl,BeanWrapper提供了設置和獲取屬性值(單個或批量)、獲取屬性描述符和查詢屬性的功能,以確定它們是可讀的還是可寫的。
此外,BeanWrapper還支持嵌套屬性,允許將子屬性的屬性設置為無限深度。BeanWrapper還支持添加標準JavaBeans屬性PropertyChangeListeners和VetoableChangeListeners,而不需要在目標類中支持代碼。最后,BeanWrapper提供了對設置索引屬性的支持。BeanWrapper通常不直接由應用程序代碼使用,而是由DataBinder和BeanFactory使用。
BeanWrapper提供了setPropertyValue,setPropertyValues,getPropertyValue和getPropertyValues方法,和一系列的可覆蓋的方法來實現對Bean的操作。
下面是使用BeanWrapper的例子,我們先定義兩個bean:
@Data public class Company {private String name;private Employee managingDirector; } @Data public class Employee {private String name;private float salary;}下面是使用的例子:
public class BeanWrapperUsage {public static void main(String[] args) {BeanWrapper company = new BeanWrapperImpl(new Company());// setting the company name..company.setPropertyValue("name", "Some Company Inc.");// ... can also be done like this:PropertyValue value = new PropertyValue("name", "Some Company Inc.");company.setPropertyValue(value);// ok, let's create the director and tie it to the company:BeanWrapper jim = new BeanWrapperImpl(new Employee());jim.setPropertyValue("name", "Jim Stravinsky");company.setPropertyValue("managingDirector", jim.getWrappedInstance());// retrieving the salary of the managingDirector through the companyFloat salary = (Float) company.getPropertyValue("managingDirector.salary");} }注意setPropertyValue和getPropertyValue的使用。
其中propertyName屬性可以有如下幾種形式:
| name | 指示屬性name相對于的getName() , isName() 和 setName(…)方法 |
| account.name | 指示account內部的name屬性,對應getAccount().setName() 和getAccount().getName()方法。 |
| account[2] | 指示account的第三個元素,索引屬性可以是array, list或者其他的自然排序的集合。 |
| account[COMPANYNAME] | 一個map,key是COMPANYNAMEs |
PropertyEditor
Spring使用PropertyEditor的概念來實現Object和String之間的轉換。
比如你配置了一個時間對象,但是在配置上,你可能需要傳入一個String,然后可以通過PropertyEditor來將其自動轉換為時間類型。
在Spring中使用PropertyEditor的情況有如下幾種:
-
通過使用PropertyEditor實現來設置bean的屬性。當使用String作為在XML文件中聲明的某個bean的屬性值時,Spring(如果相應屬性的setter有類參數)則使用ClassEditor嘗試將參數解析為Class對象。
-
在Spring的MVC框架中解析HTTP請求參數是通過使用各種屬性編輯器實現來完成的,這些實現可以手動綁定到CommandController的所有子類中。
Spring有內置的方便使用的PropertyEditor實現,他們都在org.springframework.beans.propertyeditors包里面,大多數都是通過BeanWrapperImpl來注冊的。下表列出了Spring提供的多種PropertyEditor:
| ByteArrayPropertyEditor | 字節數組編輯器。將字符串轉換為相應的字節表示形式。默認情況下由BeanWrapperImpl注冊。 |
| ClassEditor | 將表示類的字符串解析為實際類,反之亦然。當找不到類時,將引發IllegalArgumentException。默認情況下,由BeanWrapperImpl注冊。 |
| CustomBooleanEditor | 布爾屬性的可自定義屬性編輯器。默認情況下,由BeanWrapperImpl注冊,但可以通過將其自定義實例注冊為自定義編輯器來重寫。 |
| CustomCollectionEditor | 集合的屬性編輯器,將任何源集合轉換為給定的目標集合類型。 |
| CustomDateEditor | java.util.date的可自定義屬性編輯器,支持自定義日期格式。默認情況下未注冊。必須根據需要使用適當的格式進行用戶注冊。 |
| CustomNumberEditor | 任何數字子類(如integer、long、float或double)的可自定義屬性編輯器。默認情況下,由BeanWrapperImpl注冊,但可以通過將其自定義實例注冊為自定義編輯器來重寫。 |
| FileEditor | 將String解析成為java.io.File對象。默認由BeanWrapperImpl來注冊。 |
| InputStreamEditor | 單向屬性編輯器,它可以獲取一個字符串并(通過中間的ResourceEditor和Resource)生成一個InputStream,以便InputStream屬性可以直接設置為字符串。請注意,默認用法不會為您關閉inputstream。默認情況下,由BeanWrapperImpl注冊。 |
| LocaleEditor | 可以將字符串解析為區域設置對象,反之亦然(字符串格式為[country][variant],與區域設置的toString()方法相同)。默認情況下,由BeanWrapperImpl注冊。 |
| PatternEditor | 可以將字符串解析為java.util.regex.Pattern對象,反之亦然。 |
| PropertiesEditor | 可以將字符串(使用java.util.Properties類的javadoc中定義的格式格式化)轉換為屬性對象。默認情況下,由BeanWrapperImpl注冊。 |
| StringTrimmerEditor | 修剪字符串的屬性編輯器。(可選)允許將空字符串轉換為空值。默認情況下未注冊-必須是用戶注冊的。 |
| URLEditor | 可以將URL的字符串表示形式解析為實際的URL對象。默認情況下,由BeanWrapperImpl注冊。 |
Spring使用java.beans.PropertyEditorManager為可能需要的屬性編輯器設置搜索路徑,如果標準JavaBeans基礎結構與它們處理的類位于同一個包中,并且與該類具有相同的名稱,并且附加了Editor,那么標準JavaBeans基礎結構會自動發現PropertyEditor類(無需顯式注冊)。例如,可以具有以下類和包結構,這足以使SomethingEditor類被識別并用作某個類型化屬性的屬性編輯器。
如下面的目錄結構:
comflydeanbeansExoticTypeExoticTypeEditor下面是ExoticType和ExoticTypeEditor的定義:
@Data public class ExoticType {private String name;public ExoticType(String name) {this.name = name;} } public class ExoticTypeEditor extends PropertyEditorSupport {public void setAsText(String text) {setValue(new ExoticType(text.toUpperCase()));} }除了自動注冊之外,也可以使用CustomEditorConfigurer將新創建的PropertyEditor注冊到ApplicationContext:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="customEditors"><map><entry key="com.flydean.beans.ExoticType" value="com.flydean.beans.ExoticTypeEditor"/></map></property></bean>你也可以使用標準的BeanInfo JavaBeans機制。下面的示例使用BeanInfo機制顯式地用關聯類的屬性注冊一個或多個PropertyEditor實例:
comflydeanbeansExoticTypeExoticTypeBeanInfo以下引用的ExoticTypeBeanInfo類的Java源代碼將CustomNumberEditor與ExoticType類的age屬性關聯起來:
public class ExoticTypeBeanInfo extends SimpleBeanInfo {public PropertyDescriptor[] getPropertyDescriptors() {try {final PropertyEditor numberPE = new CustomNumberEditor(Integer.class, true);PropertyDescriptor ageDescriptor = new PropertyDescriptor("age", ExoticType.class) {public PropertyEditor createPropertyEditor(Object bean) {return numberPE;};};return new PropertyDescriptor[] { ageDescriptor };}catch (IntrospectionException ex) {throw new Error(ex.toString());}} }PropertyEditorRegistrar
另一種機制來注冊屬性編輯器到Spring容器的方法就是使用PropertyEditorRegistrar。
下面是使用的例子:
public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {public void registerCustomEditors(PropertyEditorRegistry registry) {// it is expected that new PropertyEditor instances are createdregistry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());// you could register as many custom property editors as are required here...} }下面是使用CustomEditorConfigurer的配置例子:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="propertyEditorRegistrars"><list><ref bean="customPropertyEditorRegistrar"/></list></property></bean><bean id="customPropertyEditorRegistrar"class="com.flydean.beans.CustomPropertyEditorRegistrar"/>本節的例子可參考beanWrapper-propertyEditor
更多精彩內容且看:
- 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
- java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程
更多教程請參考flydean的博客
總結
以上是生活随笔為你收集整理的Spring5参考指南: BeanWrapper和PropertyEditor的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5参考指南: Resourc
- 下一篇: Spring5参考指南: SpEL