|
对于最新稳定版本,请使用Spring Framework 7.0.1! |
豆子控与豆包装机
这org.springframework.beans该软件包遵循 JavaBeans 标准。
JavaBean 是一个默认无参数构造子的类,其后果
命名规范,其中(例如)一个属性宾果疯狂愿意
采用二传方法set宾果疯狂(..)以及一个getter方法getBingo疯狂().为
关于 JavaBeans 及其规范的更多信息,请参见 javabeans。
豆子包里有一个相当重要的类别是豆包装机接口及其
对应的实现(BeanWrapperImpl(豆包装师)).正如javadoc引用的,豆包装机提供设置和获取属性值的功能(单独或单独获取)
bulk),获取属性描述符,并查询属性以确定它们是否属于
可读或可书写。另外,还有豆包装机支持嵌套属性,
使得子属性的属性设置可以无限深度。这豆包装机同时支持添加标准 JavaBeans 的能力PropertyChangeListeners和可否决变更听众,无需在目标类中支持代码。
最后但同样重要的是豆包装机支持设置索引属性。
这豆包装机通常应用代码不直接使用,但被DataBinder以及豆子工厂.
方式豆包装机作品部分名称可指:它将豆子包裹到
对该豆子执行作,比如设置和检索属性。
设置和获取基本属性和嵌套属性
设置和获取属性是通过setPropertyValue和getPropertyValue过载方法的变体豆包装机.请参见他们的Javadoc
详。下表展示了这些惯例的一些例子:
| 表达 | 解释 |
|---|---|
|
表示该物业 |
|
表示嵌套属性 |
|
表示索引性质的第三个元素 |
|
表示由 |
(如果你不打算与你合作,接下来的部分对你来说并不重要
这豆包装机径直。如果你只使用那个DataBinder以及豆子工厂以及它们的默认实现,你应该跳到以下内容章节物业编辑.)
以下两个示例类使用了豆包装机去拿并设置
性能:
-
Java
-
Kotlin
public class Company {
private String name;
private Employee managingDirector;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Employee getManagingDirector() {
return this.managingDirector;
}
public void setManagingDirector(Employee managingDirector) {
this.managingDirector = managingDirector;
}
}
class Company {
var name: String? = null
var managingDirector: Employee? = null
}
-
Java
-
Kotlin
public class Employee {
private String name;
private float salary;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
}
class Employee {
var name: String? = null
var salary: Float? = null
}
以下代码片段展示了一些如何检索和作某些
实例化的性质公司s 和员工s:
-
Java
-
Kotlin
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 company
Float salary = (Float) company.getPropertyValue("managingDirector.salary");
val company = BeanWrapperImpl(Company())
// setting the company name..
company.setPropertyValue("name", "Some Company Inc.")
// ... can also be done like this:
val value = PropertyValue("name", "Some Company Inc.")
company.setPropertyValue(value)
// ok, let's create the director and tie it to the company:
val jim = BeanWrapperImpl(Employee())
jim.setPropertyValue("name", "Jim Stravinsky")
company.setPropertyValue("managingDirector", jim.wrappedInstance)
// retrieving the salary of the managingDirector through the company
val salary = company.getPropertyValue("managingDirector.salary") as Float?
内置属性编辑实现
Spring 使用了一个概念属性编辑实现对象以及一个字符串.这很方便
以不同于对象本身的方式表示属性。例如,一个日期可以用人类易读的方式表示(作为字符串:'2007-14-09'),而
我们仍然可以将人类可读的形式转换回原始日期(甚至,甚至
更好的是将任何输入的日期以人类可读的形式转换回日期物体)。这
行为可以通过注册 类型为 的自定义编辑器来实现java.beans.PropertyEditor.在 a 上注册自定义编辑器豆包装机或
或者,在特定的IoC容器中(如上一章所述),给出
了解如何将属性转换为所需类型。更多相关信息属性编辑看Java doc 的java.beansOracle 提供的软件包.
以下是几个在 Spring 中使用属性编辑的例子:
-
在豆子上设置属性的方法是
属性编辑实现。 当你使用字符串作为你声明的某个豆子属性的价值 在XML文件中,Spring(如果对应属性的设定符具有类参数)用途ClassEditor尝试将参数解析为类对象。 -
在Spring的MVC框架中解析HTTP请求参数,是通过使用各种方式完成的 之
属性编辑你可以在所有子类中手动绑定的实现指挥控制器.
Spring有许多内置功能属性编辑实现让生活更轻松。
它们都位于org.springframework.beans.propertyeditors包。大多数(但非全部,如下表所示)默认注册于BeanWrapperImpl(豆包装师).如果属性编辑器可以以某种方式配置,你可以
仍然注册你自己的变体以覆盖默认版本。下表描述了
各种属性编辑Spring提供的实现:
| 类 | 解释 |
|---|---|
|
字节数组编辑器。将字符串转换为对应的字节
交涉。默认注册 |
|
解析表示类与实际类的字符串,反之亦然。当
找不到类,一个 |
|
可定制属性编辑器 |
|
用于收藏的属性编辑器,可以转换任何来源 |
|
可定制属性编辑器 |
|
可自定义属性编辑器,适用于任何 |
|
将字符串解析为 |
|
单向属性编辑器,可以对字符串进行生成(通过
中间 |
|
可以将字符串解析为 |
|
可以将字符串解析为 |
|
可以转换字符串(格式化为 javadoc 中定义的格式) |
|
属性编辑器,可以裁剪字符串。可选地允许变换空字符串
变成了 |
|
可以将URL的字符串表示解析为实际的 |
Spring使用java.beans.PropertyEditorManager设定属性的搜索路径
可能需要编辑。搜索路径还包括Sun.Bean.编辑哪
包括属性编辑以下类型的实现字体,颜色,以及大多数
原始类型。还要注意,标准的 JavaBeans 基础设施
自动发现属性编辑课程(无需注册
明确地说,如果它们与所处理的类处于同一包中,并且具有相同的条件
名称为该类别,且编辑 器附加。例如,可以有以下
类和包结构,这就足够满足某样编辑器未来班级
被认可并用作属性编辑为东西-类型属性。
com
chank
pop
Something
SomethingEditor // the PropertyEditor for the Something class
注意你也可以使用标准Beans信息这里也有JavaBeans的机制
(这里有部分描述)。这
以下示例使用了Beans信息显式注册一个或多个的机制属性编辑具有相关类性质的实例:
com
chank
pop
Something
SomethingBeanInfo // the BeanInfo for the Something class
以下为所引用的 Java 源代码某物豆信息类
助理自定义数字编辑器其中年龄的属性东西类:
-
Java
-
Kotlin
public class SomethingBeanInfo extends SimpleBeanInfo {
public PropertyDescriptor[] getPropertyDescriptors() {
try {
final PropertyEditor numberPE = new CustomNumberEditor(Integer.class, true);
PropertyDescriptor ageDescriptor = new PropertyDescriptor("age", Something.class) {
@Override
public PropertyEditor createPropertyEditor(Object bean) {
return numberPE;
}
};
return new PropertyDescriptor[] { ageDescriptor };
}
catch (IntrospectionException ex) {
throw new Error(ex.toString());
}
}
}
class SomethingBeanInfo : SimpleBeanInfo() {
override fun getPropertyDescriptors(): Array<PropertyDescriptor> {
try {
val numberPE = CustomNumberEditor(Int::class.java, true)
val ageDescriptor = object : PropertyDescriptor("age", Something::class.java) {
override fun createPropertyEditor(bean: Any): PropertyEditor {
return numberPE
}
}
return arrayOf(ageDescriptor)
} catch (ex: IntrospectionException) {
throw Error(ex.toString())
}
}
}
注册额外自定义属性编辑实现
当将 bean 属性设置为字符串值时,Spring IoC 容器最终会使用
标准JavaBeans属性编辑将这些字符串转换为复类型
财产。Spring 预注册了许多自定义属性编辑实现(例如,到
将一个用字符串表示的类名转换为类目的)。此外
Java 标准 JavaBeans属性编辑查找机制允许属性编辑对于一个类,应适当命名并置于与该类相同的包中
它为其提供支持,以便自动找到。
如果需要注册其他自定义物业编辑,有几个机制包括
可用。最手动的方法,通常并不方便
推荐的做法是registerCustomEditor()方法ConfigurableBeanFactory接口,假设你有豆子工厂参考。
另一种(稍微方便一点)的机制是使用特殊的豆子工厂
后处理器称为CustomEditorConfigurer.不过你也可以用豆子工厂的后处理器
跟豆子工厂实现,CustomEditorConfigurer有
嵌套属性设置,因此我们强烈建议你将其与应用上下文,你可以像其他豆子一样部署,且
该系统可自动检测并应用。
注意,所有豆子工厂和应用场景都会自动使用若干
内置属性编辑器,通过使用豆包装机自
处理房产转换。标准属性编辑器豆包装机登记册已列于上一节。
此外应用上下文s 还会覆盖或添加额外的编辑器来处理
资源查找以符合特定应用上下文类型的方式进行。
标准 JavaBeans属性编辑实例用于转换属性价值
用字符串表示为该属性的实际复类型。你可以使用CustomEditorConfigurer方便地补充,是豆子工厂的后处理器。
支持更多属性编辑实例到应用上下文.
考虑以下示例,定义了一个名为异域类型和
另一类DependsOnExoticType,需要异域类型作为一个属性集合:
-
Java
-
Kotlin
package example;
public class ExoticType {
private String name;
public ExoticType(String name) {
this.name = name;
}
}
public class DependsOnExoticType {
private ExoticType type;
public void setType(ExoticType type) {
this.type = type;
}
}
package example
class ExoticType(val name: String)
class DependsOnExoticType {
var type: ExoticType? = null
}
当设置正确后,我们希望能够将类型属性分配为
字符串,其中属性编辑转换为实际异域类型实例。以下豆子定义展示了如何建立这种关系:
<bean id="sample" class="example.DependsOnExoticType">
<property name="type" value="aNameForExoticType"/>
</bean>
这属性编辑实现方式可能类似于以下内容:
-
Java
-
Kotlin
package example;
import java.beans.PropertyEditorSupport;
// converts string representation to ExoticType object
public class ExoticTypeEditor extends PropertyEditorSupport {
public void setAsText(String text) {
setValue(new ExoticType(text.toUpperCase()));
}
}
package example
import java.beans.PropertyEditorSupport
// converts string representation to ExoticType object
class ExoticTypeEditor : PropertyEditorSupport() {
override fun setAsText(text: String) {
value = ExoticType(text.toUpperCase())
}
}
最后,以下示例展示了如何使用CustomEditorConfigurer注册新属性编辑其中应用上下文,然后可以根据需要使用它:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="example.ExoticType" value="example.ExoticTypeEditor"/>
</map>
</property>
</bean>
用PropertyEditor注册商
另一种用 Spring 容器注册属性编辑器的机制是
创建并使用PropertyEditor注册商.该接口在
你需要在多个不同情况下使用同一套属性编辑器。
你可以写对应的注册商,并在每种情况下重复使用。PropertyEditor注册商实例与一个名为PropertyEditorRegistry,一个由Spring实现的接口豆包装机(和DataBinder).PropertyEditor注册商实例特别方便
当与CustomEditorConfigurer(此处描述),该性质揭示了
叫setPropertyEditorRegistrars(..).PropertyEditor注册商新增实例
转给CustomEditorConfigurer这样可以很容易地与DataBinder和
Spring MVC 控制器。此外,它避免了自定义时的同步需求
编辑:APropertyEditor注册商预计将创造新鲜的属性编辑每次豆子创建尝试的实例。
以下示例展示了如何创建自己的PropertyEditor注册商实现:
-
Java
-
Kotlin
package com.foo.editors.spring;
public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {
public void registerCustomEditors(PropertyEditorRegistry registry) {
// it is expected that new PropertyEditor instances are created
registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
// you could register as many custom property editors as are required here...
}
}
package com.foo.editors.spring
import org.springframework.beans.PropertyEditorRegistrar
import org.springframework.beans.PropertyEditorRegistry
class CustomPropertyEditorRegistrar : PropertyEditorRegistrar {
override fun registerCustomEditors(registry: PropertyEditorRegistry) {
// it is expected that new PropertyEditor instances are created
registry.registerCustomEditor(ExoticType::class.java, ExoticTypeEditor())
// you could register as many custom property editors as are required here...
}
}
另见org.springframework.beans.support.ResourceEditorRegistrar举个例子PropertyEditor注册商实现。注意其实现中registerCustomEditors(..)方法,它创建每个属性编辑器的新实例。
下一个示例展示了如何配置CustomEditorConfigurer并注入一个实例
我们的CustomPropertyEditorRegistrar进入其中:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<ref bean="customPropertyEditorRegistrar"/>
</list>
</property>
</bean>
<bean id="customPropertyEditorRegistrar"
class="com.foo.editors.spring.CustomPropertyEditorRegistrar"/>
最后(稍微偏离本章主题)给你们
使用 Spring 的 MVC Web 框架,使用PropertyEditor注册商在
与数据绑定的网页控制器结合使用非常方便。如下
示例使用PropertyEditor注册商在实现@InitBinder方法:
-
Java
-
Kotlin
@Controller
public class RegisterUserController {
private final PropertyEditorRegistrar customPropertyEditorRegistrar;
RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
this.customPropertyEditorRegistrar = propertyEditorRegistrar;
}
@InitBinder
void initBinder(WebDataBinder binder) {
this.customPropertyEditorRegistrar.registerCustomEditors(binder);
}
// other methods related to registering a User
}
@Controller
class RegisterUserController(
private val customPropertyEditorRegistrar: PropertyEditorRegistrar) {
@InitBinder
fun initBinder(binder: WebDataBinder) {
this.customPropertyEditorRegistrar.registerCustomEditors(binder)
}
// other methods related to registering a User
}
这种风格属性编辑注册可以促成简洁的代码(实现
关于@InitBinder方法只有一行长,且共识属性编辑注册码应封装在一个类中,然后在尽可能多的控制器之间共享
按需。