🍊
翻译橙
🍊返回主站🤖参与贡献
  • hello,这里是翻译橙
  • spring boot参考文档
    • 1. 法律
    • 2. 寻求帮助
    • 3. 文档概述
    • 4. 入门
    • 5. 升级Spring Boot
    • 6. 使用 Spring Boot 进行开发
      • 6.1. 构建系统
      • 6.2. 构建你的代码
      • 6.3. 配置类
      • 6.4. 自动配置
      • 6.5. Spring Bean 和依赖注入
      • 6.6. 使用@SpringBootApplication注解
      • 6.7. 运行您的应用程序
      • 6.8. 开发者工具
      • 6.9. 打包您的生产应用程序
      • 6.10. 接下来读什么
    • 7.核心特性
      • 7.1. SpringApplication
      • 7.2. 外部化配置
      • 7.3.Profile配置
      • 7.4.日志记录
      • 7.5.国际化
      • 7.6 面向切面的编程
      • 7.7. JSON
      • 7.8. 任务执行与调度
      • 7.9. 单元测试
        • 7.9.1. 测试范围依赖
        • 7.9.2. 测试 Spring 应用程序
        • 7.9.3. 测试 Spring Boot 应用程序
        • 7.9.4. 测试容器
        • 7.9.5. 测试工具
      • 7.10. Docker Compose 支持
      • 7.11. 测试容器支持
      • 7.12. 创建您自己的自动配置
      • 7.13. Kotlin 支持
      • 7.14 SSL
      • 7.15.接下来要读什么
    • 8. 网络
      • 8.1. Servlet Web 应用程序
        • 8.1.1. “Spring Web MVC 框架”
        • 8.1.2. JAX-RS 和Jersey
        • 8.1.3. 嵌入式 Servlet 容器支持
      • 8.2 反应式网络应用程序
        • 8.2.1. “Spring WebFlux 框架”
        • 8.2.2. 嵌入式反应式服务器支持
        • 8.2.3. 反应式服务器资源配置
      • 8.3. 优雅关机
      • 8.4. spring安全
        • 8.4.1. MVC安全
        • 8.4.2. WebFlux 安全
        • 8.4.3. OAuth2
        • 8.4.4. SAML 2.0
      • 8.5. spring 会话
      • 8.6.GraphQL
      • 8.7. Spring HATEOAS
      • 8.8.接下来读什么
    • 9. 数据
      • 9.1. SQL数据库
      • 9.2. 使用 NoSQL 技术
      • 9.3. 接下来读什么
    • 10. 消息
      • 10.1. JMS
      • 10.2. AMQP
      • 10.3. Apache Kafka 支持
      • 10.4. Apache Pulsar 支持
      • 10.5. RSocket
      • 10.6. Spring Integration
      • 10.7. WebSockets
      • 10.8. What to Read Next
    • 11. IO
      • 11.1. 缓存
      • 11.2. Hazelcast
      • 11.3. Quartz 调度程序
      • 11.4. 发送电子邮件
      • 11.5. 验证
      • 11.6. 调用 REST 服务
      • 11.7. web services
      • 11.8. 使用 JTA 进行分布式事务
      • 11.9. 接下来读什么
    • 12. 容器镜像
  • Spring核心功能
    • 1.IOC容器和Bean简介
      • 1.2. 容器概述
      • 1.3. Bean概述
      • 1.4. 依赖项
        • 1.4.1. 依赖注入
        • 1.4.2. 详细的依赖关系和配置
        • 1.4.3. 使用depends-on
        • 1.4.4. 延迟初始化的 Bean
        • 1.4.5. 自动装配协作者
        • 1.4.6. 方法注入
    • 2. Resources
      • 2.1. 介绍
      • 2.2. Resource接口
      • 2.3. 内置Resource实现
      • 2.4. ResourceLoader接口
      • 2.5. ResourcePatternResolver接口
      • 2.6. ResourceLoaderAware接口
      • 2.7. 资源作为依赖
      • 2.8. 应用程序上下文和资源路径
    • 3. 验证、数据绑定和类型转换
      • 3.1. 使用 Spring 的 Validator 接口进行验证
      • 3.2. 将代码解析为错误消息
      • 3.3. Bean 操作和BeanWrapper
      • 3.4. spring类型转换
      • 3.5. spring字段格式
      • 3.6. 配置全局日期和时间格式
      • 3.7. Java Bean 验证
    • 4. SpEL表达式
    • 5. Spring 面向切面编程
      • 5.1. AOP 概念
      • 5.2. Spring AOP 的能力和目标
      • 5.3. AOP 代理
      • 5.4. @AspectJ 支持
        • 5.4.1. 启用@AspectJ 支持
        • 5.4.2. 声明一个切面
        • 5.4.3. 声明切入点
        • 5.4.4. 声明切点
        • 5.4.5. 切面说明
        • 5.4.6. 切面实例化模型
        • 5.4.7. AOP 示例
      • 5.5. 基于模式的 AOP 支持
      • 5.6. 选择要使用的 AOP 声明样式
      • 5.7. 混合切面类型
      • 5.8. 代理机制
      • 5.9. @AspectJ 代理的程序化创建
      • 5.10. 在 Spring 应用程序中使用 AspectJ
      • 5.11.更多资源
    • 6. Spring AOP API
      • 6.1. Spring中的切入点API
      • 6.2. Spring 中的 Advice API
      • 6.3. Spring 中的 Advisor API
      • 6.4. 使用ProxyFactoryBean创建 AOP 代理
      • 6.5. 简洁的代理定义
      • 6.6. 以编程方式创建 AOP 代理ProxyFactory
      • 6.7. 操作切面对象
      • 6.8. 使用“自动代理”工具
      • 6.9. 使用TargetSource实现
      • 6.10. 定义新的切面类型
    • 7. 空指针安全
    • 8. 数据缓冲器和编解码器
    • 9. 日志
    • 10. 附录
      • 10.1. XML 模式
      • 10.2. 自定义XML Schema
        • 10.2.1. 创作 Schema
        • 10.2.2. 编码一个NamespaceHandler
        • 10.2.3. 使用BeanDefinitionParser
        • 10.2.4. 注册处理程序和模式
        • 10.2.5. 在 Spring XML 配置中使用自定义扩展
        • 10.2.6. 更详细的例子
      • 10.3. 应用程序启动步骤
  • 使用redis实现分布式锁
  • Java 安全标准算法名称
  • JDK 9 JEP
  • JDK 10 JEP
  • 人件
    • 《人件》
    • 第一部分 管理人力资源
      • 01 此时此刻,一个项目正在走向失败
      • 02 干酪汉堡,做一个,卖一个
      • 03 维也纳在等你
      • 04 质量——如果时间允许
      • 05 再谈帕金森定律
      • 06 苦杏素
    • 第二部分 办公环境
      • 07 家具警察
      • 08 “朝九晚五在这里啥也完成不了。”
      • 09 在空间上省钱
      • 间奏曲:生产效率度量和不明飞行物
      • 10 大脑时问与身体时间
      • 11 电话
      • 12 门的回归
      • 13 采取保护步骤
    • 第三部分 正确的人
      • 14 霍恩布洛尔因素
      • 15 谈谈领导力
      • 16 雇一名杂耍演员
      • 17 与他人良好合作
      • 18 童年的终结
      • 19 在这儿很开心
      • 20 人力资本
    • 第四部分 高效团队养成
      • 21 整体大于部分之和
      • 22 黑衣团队
      • 23 团队自毁
      • 24 再谈团队自毁
      • 25 竞争
      • 26 一顿意面晚餐
      • 27 敞开和服
      • 28 团队形成的化学反应
    • 第五部分 沃土
      • 29 自我愈复系统
      • 30 与风险共舞
      • 3l 会议、独白和交流
      • 32 终极管理罪恶得主是……
      • 33 “邪恶”电邮
      • 34 让改变成为可能
      • 35 组织型学习
      • 36 构建社区
    • 第六部分 快乐地工作
      • 37 混乱与秩序
      • 38 自由电子
      • 39 霍尔加·丹斯克
由 GitBook 提供支持
在本页

这有帮助吗?

在GitHub上编辑
  1. Spring核心功能
  2. 3. 验证、数据绑定和类型转换

3.3. Bean 操作和BeanWrapper

上一页3.2. 将代码解析为错误消息下一页3.4. spring类型转换

最后更新于1年前

这有帮助吗?

org.springframework.beans包遵循 JavaBeans 标准。JavaBean 是具有默认无参数构造函数的类,并且遵循命名约定,其中(例如)命名bingoMadness的属性将具有setBingoMadness(..) setter 方法和getBingoMadness() getter 方法。有关 JavaBeans 和规范的更多信息,请参阅 。

bean 包中一个非常重要的类是BeanWrapper接口及其对应的实现(BeanWrapperImpl)。正如从 javadoc 中引用的那样, BeanWrapper提供了设置和获取属性值(单独或批量)、获取属性描述符和查询属性以确定它们是可读还是可写的功能。此外,BeanWrapper还提供对嵌套属性的支持,使子属性上的属性设置可以无限深。BeanWrapper还支持添加标准 JavaBeans 的能力, PropertyChangeListeners 和VetoableChangeListeners无需在目标类中支持代码。最后但并非最不重要的一点是,BeanWrapper提供了对设置索引属性的支持。通常不由应用程序代码直接使用BeanWrapper,而是由 DataBinder和BeanFactory.

BeanWrapper工作方式部分由其名称表示:它包装一个 bean 以对该 bean 执行操作,例如设置和检索属性。

3.3.1. 设置和获取基本和嵌套属性

设置和获取属性是通过 BeanWrapper 的 setPropertyValue 和 getPropertyValue 重载方法变体完成的. 有关详细信息,请参阅他们的 Javadoc。下表显示了这些约定的一些示例:

表达式
备注

name

指示与 getName() 或 isName() 和setName(..)方法对应的属性名称。

account.name

指示对应于(例如) getAccount().setName() 或getAccount().getName()方法的属性帐户的嵌套属性名称。

account[2]

指示索引属性account的第三个元素。索引属性可以是array、list或其他自然排序的集合。

account[COMPANYNAME]

指示由 account Map 属性的 COMPANYNAME 键索引的映射条目的值。

(如果您不打算直接使用 BeanWrapper,那么下一部分对您来说并不重要。如果您只使用DataBinder和 BeanFactory 以及它们的默认实现,您应该跳到关于 的 部分。)

以下两个示例类使用BeanWrapper来获取和设置属性:

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;
    }
}
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;
    }
}

以下代码片段显示了一些示例,说明如何检索和操作实例化的Company s 和Employees 的某些属性:

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");

3.3.2. 内置PropertyEditor实现

在 Spring 中使用属性编辑的几个示例:

  • 在 bean 上设置属性是通过使用PropertyEditor实现来完成的。当您使用String在 XML 文件中声明的某个 bean 的属性值时,Spring(如果相应属性的设置器有Class 参数)ClassEditor会尝试将参数解析为Class对象。

  • 在 Spring 的 MVC 框架中解析 HTTP 请求参数是通过使用各种PropertyEditor实现来完成的,您可以在 CommandController.

Spring 有许多内置的PropertyEditor实现来简化生命周期。它们都位于org.springframework.beans.propertyeditors 包中。大多数(但不是全部,如下表所示)默认情况下由 BeanWrapperImpl注册. 如果可以以某种方式配置属性编辑器,您仍然可以注册自己的变体来覆盖默认变体。下表描述了Spring PropertyEditor提供的各种实现:

类
备注

ByteArrayPropertyEditor

字节数组的编辑器。将字符串转换为其对应的字节表示。默认注册为BeanWrapperImpl。

ClassEditor

将表示类的字符串解析为实际类,反之亦然。当找不到类时,抛出一个IllegalArgumentException。默认情况下,由 BeanWrapperImpl注册 。

CustomBooleanEditor

可自定义的Boolean属性编辑器。默认情况下,注册者为BeanWrapperImpl, 但可以通过将其自定义实例注册为自定义编辑器来覆盖。

CustomCollectionEditor

集合的属性编辑器,将任何Collection源转换为给定的目标 Collection类型。

CustomDateEditor

可定制的java.util.Date属性编辑器,支持自定义DateFormat。默认未注册。必须根据需要使用适当的格式进行用户注册。

CustomNumberEditor

任何子类的可定制Number属性编辑器,例如Integer、Long、Float或 Double. 默认情况下,注册者为BeanWrapperImpl,但可以通过将其自定义实例注册为自定义编辑器来覆盖。

FileEditor

将字符串解析为java.io.File对象。默认情况下,由BeanWrapperImpl注册 。

InputStreamEditor

单向属性编辑器,可以接受一个字符串并产生(通过一个中间ResourceEditor和Resource)InputStream,以便InputStream 可以将属性直接设置为字符串。请注意,默认用法不会为您关闭InputStream。默认情况下,由 BeanWrapperImpl注册。

LocaleEditor

可以将字符串解析为Locale对象,反之亦然(字符串格式为 [language]_[country]_[variant],与Locale 的方法toString() 相同)。也接受空格作为分隔符,作为下划线的替代。默认情况下,由 BeanWrapperImpl注册。

PatternEditor

可以将字符串解析为java.util.regex.Pattern对象,反之亦然。

PropertiesEditor

可以将java.util.Properties字符串(使用类的 javadoc 中定义的格式格式化 )转换为Properties对象。默认情况下,由BeanWrapperImpl 注册。

StringTrimmerEditor

修剪字符串的属性编辑器。可选地允许将空字符串转换为null值。默认情况下未注册 - 必须是用户注册的。

URLEditor

可以将 URL 的字符串表示解析为实际URL对象。默认情况下,由BeanWrapperImpl 注册。

Spring 使用java.beans.PropertyEditorManager为可能需要的属性编辑器设置搜索路径。搜索路径还包括sun.bean.editors,其中包括诸如Font、Color和大多数基本类型的PropertyEditor实现。另请注意,标准 JavaBeans 基础结构会自动发现PropertyEditor类(无需显式注册它们),前提是它们与它们处理的类在同一个包中并且与该类具有相同的名称,并带有Editor后缀。例如,可以具有以下类和包结构,这足以使SomethingEditor该类被识别并用作Something类型的属性的PropertyEditor。

com
  chank
    pop
      Something
      SomethingEditor // the PropertyEditor for the Something class
com
  chank
    pop
      Something
      SomethingBeanInfo // the BeanInfo for the Something class

被SomethingBeanInfo引用类的以下 Java 源代码将CustomNumberEditor与Something类的age属性相关联:

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());
        }
    }
}

注册其他自定义PropertyEditor实现

当将 bean 属性设置为字符串值时,Spring IoC 容器最终使用标准 JavaBeansPropertyEditor实现将这些字符串转换为属性的复杂类型。Spring 预先注册了许多自定义PropertyEditor实现(例如,将表示为字符串的类名转换为Class对象)。此外,Java 的标准 JavaBeansPropertyEditor查找机制允许PropertyEditor 对类进行适当命名,并将其放置在与其提供支持的类相同的包中,以便可以自动找到它。

如果需要注册其他自定义PropertyEditors,可以使用多种机制。最手动的方法,通常不方便或不推荐,是使用 ConfigurableBeanFactory接口的registerCustomEditor()方法,假设您有参考BeanFactory。另一种(稍微方便一点)机制是使用一个特殊的 bean factory 后处理器,称为CustomEditorConfigurer. 尽管您可以将 bean factory 后处理器与BeanFactory实现一起使用,但CustomEditorConfigurer具有嵌套属性设置,因此我们强烈建议您将其与 ApplicationContext应用。

标准 JavaBeansPropertyEditor实例用于将表示为字符串的属性值转换为属性的实际复杂类型。您可以使用 bean 工厂后处理器CustomEditorConfigurer,方便地将对其他PropertyEditor实例的支持添加到ApplicationContext.

考虑以下示例,它定义了一个名为ExoticType的用户类和另一个名为DependsOnExoticType的类,需要将其ExoticType设置为属性:

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;
    }
}

正确设置后,我们希望能够将 type 属性分配为字符串,然后将其PropertyEditor转换为实际 ExoticType实例。以下 bean 定义显示了如何设置这种关系:

<bean id="sample" class="example.DependsOnExoticType">
    <property name="type" value="aNameForExoticType"/>
</bean>

PropertyEditor实现可能类似于以下内容:

// converts string representation to ExoticType object
package example;

public class ExoticTypeEditor extends PropertyEditorSupport {

    public void setAsText(String text) {
        setValue(new ExoticType(text.toUpperCase()));
    }
}

最后,以下示例显示了如何使用CustomEditorConfigurer向 ApplicationContext注册新的 PropertyEditor,然后可以根据需要使用它:

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
            <entry key="example.ExoticType" value="example.ExoticTypeEditor"/>
        </map>
    </property>
</bean>

使用PropertyEditorRegistrar

以下示例显示了如何创建自己的PropertyEditorRegistrar实现:

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...
    }
}

另请参阅org.springframework.beans.support.ResourceEditorRegistrar示例 PropertyEditorRegistrar实现。请注意在 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"/>
@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
}

这种注册PropertyEditor风格可以带来简洁的代码(@InitBinder方法的实现只有一行长),并且可以将通用的PropertyEditor 注册代码封装在一个类中,然后根据需要在尽可能多的控制器之间共享。

Spring 使用PropertyEditor的概念来实现 Object和String之间的转换。以与对象本身不同的方式表示属性可能很方便。例如,Date 可以以人类可读的方式表示(如String: '2007-14-09'),而我们仍然可以将人类可读的形式转换回原始日期(或者,更好的是,将以人类可读的形式输入的任何日期转换回Date对象)。这种行为可以通过注册自定义类型的编辑器java.beans.PropertyEditor来实现 。在一个特定的 IoC 容器中注册自定义编辑器BeanWrapper(如前一章所述),使其了解如何将属性转换为所需的类型。有关PropertyEditor更多信息 ,请。

请注意,您也可以在此处使用标准BeanInfo JavaBeans 机制(在进行了一定程度的描述 )。以下示例使用BeanInfo机制显式注册一个或多个 具有关联类属性的PropertyEditor实例:

请注意,所有 bean 工厂和应用程序上下文都会自动使用许多内置属性编辑器,通过它们使用 BeanWrapper来处理属性转换。列出了BeanWrapper 寄存器的标准属性编辑器。此外,ApplicationContext还覆盖或添加额外的编辑器,以便以适合特定应用程序上下文类型的方式处理资源查找。

向 Spring 容器注册属性编辑器的另一种机制是创建和使用PropertyEditorRegistrar. 当您需要在几种不同的情况下使用同一组属性编辑器时,此接口特别有用。您可以编写相应的注册器并在每种情况下重复使用它。 PropertyEditorRegistrar实例与名为 PropertyEditorRegistry的接口一起工作,该接口由 Spring BeanWrapper (and DataBinder) 实现。PropertyEditorRegistrar实例与CustomEditorConfigurer( 描述)结合使用时特别方便,它公开了一个名为setPropertyEditorRegistrars(..)的方法. 以这种方式添加到PropertyEditorRegistrar的CustomEditorConfigurer 实例可以很容易地与DataBinder和 Spring MVC 控制器共享。此外,它避免了在自定义编辑器上进行同步的需要:PropertyEditorRegistrar预计会 为每个 bean 创建尝试创建新PropertyEditor实例。

最后(有点偏离本章的重点)对于那些使用人来说,将 PropertyEditorRegistrar与数据绑定 Web 控制器结合使用会非常方便。以下示例在@InitBinder 方法的实现中使用 PropertyEditorRegistrar:

javabeans
PropertyEditors
参阅java.beans来自 Oracle 的软件包
此处
上一节
在此处
Spring 的 MVC Web 框架的