PropertyEditorRegistrar

这里说的是 org.springframework.beans.PropertyEditorRegistrar 而不是 org.springframework.beans.PropertyEditorRegistry 接口。

这个接口就是注册器,用来注册一组属性编辑器的,可以将一些属性编辑器进行分组,在不同情况下重用这些编辑器。

下图就是将一些属性编辑器分成了两个组:

ResourceEditorRegistrar 类是这个接口的唯一实现:

public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
        doRegisterEditor(registry, Resource.class, baseEditor);
        doRegisterEditor(registry, ContextResource.class, baseEditor);
        doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
        doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
        doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
        doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
        doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
        doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));

        ClassLoader classLoader = this.resourceLoader.getClassLoader();
        doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
        doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
        doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));

        if (this.resourceLoader instanceof ResourcePatternResolver) {
            doRegisterEditor(registry, Resource[].class,
                new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
        }
    }
    // ...
}

当 registerCustomEditors 方法被调用时,就会将类型和编辑器的映射关系注册到 Bean 中;而上面是 Spring 中自带的类型和属性编辑器的映射。

注册位置

在使用 ApplicationContext 容器并调用 refresh() 方法时,会自动向容器中注册 ResourceEditorRegistrar 实例,但是还没有调用 registerCustomEditors 方法。

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// 该方法是在 AbstractBeanFactory 类中实现的;propertyEditorRegistrars 就是一个 LinkedHashSet。
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
    this.propertyEditorRegistrars.add(registrar);
}

这里只是向基础容器中添加属性编辑注册器。

registerCustomEditors 方法调用

Bean 实例化后,在填充属性时会迭代所有的属性编辑注册器,并调用 registerCustomEditors 方法来注册属性编辑器。

protected void registerCustomEditors(PropertyEditorRegistry registry) {
    if (!this.propertyEditorRegistrars.isEmpty()) {
        for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
            try {
                registrar.registerCustomEditors(registry);
            }

每一个 Bean 实例都会关联多个属性编辑器,所以要保证每个属性编辑器的安全性。

自定义属性注册器

PropertyEditor 文章中,创建了一个自定义属性编辑器 UserPropertyEditor;而这里要创建一个注册器,向 Spring 中注册这个属性编辑器。

public class UserEditorRegistrar implements PropertyEditorRegistrar {
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(User.class, new UserPropertyEditor());
    }
}

由于这个属性编辑器是自定义类型的,所以我们调用 registerCustomEditor 方法注册;但是如果你要替换 Spring 中原有的属性编辑器,可以调用 overrideDefaultEditor 方法。

关于这两个方法,可以查看 PropertyEditorRegistry

posted @ 2022-06-07 13:32  不是很聪明  阅读(115)  评论(0)    收藏  举报