关于后端:Spring-源码解析五Bean-的配置定义注册

1次阅读

共计 33106 个字符,预计需要花费 83 分钟才能阅读完成。

Spring 源码解析五:Bean 的配置、定义、注册

在 Spring 源码解析二:上下文组件(WebApplicationContext) 中,留有一些点待解析:

  • ConfigurableListableBeanFactory如何加载、实例化 bean
  • ResourceEditorRegistrar如何注册属性编辑器、属性编辑器如何解析为对象
  • PathMatchingResourcePatternResolver如何解析、加载 locationPattern 指定的资源
  • PropertySourcesPropertyResolver如何是解析门路的
  • XmlBeanDefinitionReader如何是解析 bean 定义的
  • AnnotatedBeanDefinitionReader是如何注册 bean 的
  • ClassPathBeanDefinitionScanner是如何扫描包的

其中第一条已在 Spring 源码解析三:Bean 的注册、解析、实例化机制 中解析了,这一节来看看前面几条

1. ResourceEditorRegistrar

ResourceEditorRegistrar
的次要性能是在 bean 实例化的时候,在 beanDefinition 转换为 BeanWrapper 后用于对属性的填充

比如说,xml 中这样定义了一个 bean

<bean id="demoBean" class="com.example.DemoBean">
  <property name="date" value="2021-10-15" />
</bean>

com.example.DemoBean 类中定义了一个属性 dateDate类型的,但 Spring 从 xml 中读出来的是字符串,这就须要给 Spring 配置属性编辑器,把字符串转化成对象。

public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
    // 注册自定义编辑器
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        // 注册实体,临时省略,前面再解析
        // 这里先解析 PropertyEditorRegistry
    }
}

先来看看 PropertyEditorRegistrySupport
是如何解决各种类型的属性编辑器的(PropertyEditorRegistry只是接口,PropertyEditorRegistrySupport是其默认实现)

1.1. PropertyEditorRegistrySupport

public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
    // 默认编辑器
    private Map<Class<?>, PropertyEditor> defaultEditors;
    // 笼罩默认编辑器
    private Map<Class<?>, PropertyEditor> overriddenDefaultEditors;
    // 自定义编辑器
    private Map<Class<?>, PropertyEditor> customEditors;
    // Path 自定义编辑器
    private Map<String, CustomEditorHolder> customEditorsForPath;
    // 自定义编辑器缓存
    private Map<Class<?>, PropertyEditor> customEditorCache;
}

1.1.1. PropertyEditorRegistrySupport.getDefaultEditor

public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
    // 获取针对 requiredType 的默认编辑器
    public PropertyEditor getDefaultEditor(Class<?> requiredType) {
        // ... 代码省略

        if (this.overriddenDefaultEditors != null) {
            // 如果有自定义笼罩默认编辑器的,返回自定义默认编辑器
            PropertyEditor editor = this.overriddenDefaultEditors.get(requiredType);
            if (editor != null) {return editor;}
        }
        // 如果 defaultEditors 还没创立过,则创立
        if (this.defaultEditors == null) {createDefaultEditors();
        }
        return this.defaultEditors.get(requiredType);
    }

    // 创立默认编辑器,所有的根本、罕用类型都囊括了
    private void createDefaultEditors() {this.defaultEditors = new HashMap<>(64);

        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(Path.class, new PathEditor());
        this.defaultEditors.put(Pattern.class, new PatternEditor());
        this.defaultEditors.put(Properties.class, new PropertiesEditor());
        this.defaultEditors.put(Reader.class, new ReaderEditor());
        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());
        this.defaultEditors.put(ZoneId.class, new ZoneIdEditor());

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

        this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
        this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());

        this.defaultEditors.put(char.class, new CharacterEditor(false));
        this.defaultEditors.put(Character.class, new CharacterEditor(true));

        this.defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
        this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));

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

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

这些默认的编辑器都比较简单,都在 beans/propertyeditors
这个包下,只有一个不在这个包下,也须要解析下:ResourceArrayPropertyEditor

ResourceArrayPropertyEditor 解析的是多个资源,如通配符 * 代表的多个资源

public class ResourceArrayPropertyEditor extends PropertyEditorSupport {
    // 转换 String 值为目标值
    @Override
    public void setAsText(String text) {// 解析 path 中的占位符 ${}
        String pattern = resolvePath(text).trim();
        try {
            // 应用 ResourcePatternResolver.getResources 解析
            setValue(this.resourcePatternResolver.getResources(pattern));
        }
        catch (IOException ex) {// ... 代码省略}
    }

    // 设置转换的值
    @Override
    public void setValue(Object value) throws IllegalArgumentException {
        // 如果是 Collection,持续解决
        // 如果是数组,但还没有转化为 Resource,持续解决
        if (value instanceof Collection || (value instanceof Object[] && !(value instanceof Resource[]))) {Collection<?> input = (value instanceof Collection ? (Collection<?>) value : Arrays.asList((Object[]) value));
            Set<Resource> merged = new LinkedHashSet<>();
            for (Object element : input) {if (element instanceof String) {// 解析 path 中的占位符 ${}
                    String pattern = resolvePath((String) element).trim();
                    try {
                        // 转化为 Resource,并增加
                        Resource[] resources = this.resourcePatternResolver.getResources(pattern);
                        Collections.addAll(merged, resources);
                    }
                    catch (IOException ex) {// ... 代码省略}
                }
                else if (element instanceof Resource) {
                    // 如果原本就是 Resource,则增加
                    merged.add((Resource) element);
                }
                else {// ... 代码省略}
            }
            super.setValue(merged.toArray(new Resource[0]));
        }
        else {super.setValue(value);
        }
    }
}

1.1.2. PropertyEditorRegistrySupport.registerCustomEditor

public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
    // 注册自定义编辑器
    @Override
    public void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor) {
        // ... 代码省略

        // 如果有 propertyPath,注册到 customEditorsForPath 中
        if (propertyPath != null) {if (this.customEditorsForPath == null) {this.customEditorsForPath = new LinkedHashMap<>(16);
            }
            this.customEditorsForPath.put(propertyPath, new CustomEditorHolder(propertyEditor, requiredType));
        }
        // 不然,注册到 customEditors 中
        else {if (this.customEditors == null) {this.customEditors = new LinkedHashMap<>(16);
            }
            this.customEditors.put(requiredType, propertyEditor);
            this.customEditorCache = null;
        }
    }

    // 增加针对 requiredType 的笼罩默认编辑器
    public void overrideDefaultEditor(Class<?> requiredType, PropertyEditor propertyEditor) {if (this.overriddenDefaultEditors == null) {this.overriddenDefaultEditors = new HashMap<>();
        }
        this.overriddenDefaultEditors.put(requiredType, propertyEditor);
    }
}

1.2. ResourceEditorRegistrar.registerCustomEditors

public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
    // 注册自定义编辑器
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        // 应用以后的 resourceLoader,笼罩 Resource、InputStream、File、Path 等的默认资源加载器
        // 其余的解决形式不变
        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));
        }
    }

    // 如果能够,笼罩默认编辑器,不然注册自定义编辑器
    private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {if (registry instanceof PropertyEditorRegistrySupport) {((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
        }
        else {registry.registerCustomEditor(requiredType, editor);
        }
    }
}

2. PathMatchingResourcePatternResolver

PathMatchingResourcePatternResolver
是一个 Ant 模式通配符的 Resource 查找器,能够用来查找类门路下或者文件系统中的资源

Ant 模式匹配规定如下

  1. ? 匹配一个字符
  2. * 匹配 0 个或多个字符
  3. ** 匹配 0 个或多个目录

例如

  • /trip/api/*x 匹配 /trip/api/x/trip/api/ax/trip/api/abx,但不匹配 /trip/abc/x
  • /trip/a/a?x 匹配 /trip/a/abx,但不匹配 /trip/a/ax/trip/a/abcx
  • /**/api/alie 匹配 /trip/api/alie/trip/dax/api/alie,但不匹配 /trip/a/api
  • /**/*.htmlm 匹配所有以 .htmlm 结尾的门路
public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
    // 默认应用 Ant 模式通配符
    private PathMatcher pathMatcher = new AntPathMatcher();

    // 解析 locationPattern 指定的资源
    @Override
    public Resource[] getResources(String locationPattern) throws IOException {
        // 以 "classpath*:" 结尾
        if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {// 有 *?{}符号的通配符
            if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {// 找出含有 *?{}符号门路涵盖的资源
                return findPathMatchingResources(locationPattern);
            }
            else {
                // 无通配符,当做纯字符看待
                return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
            }
        }
        else {
            // 以 "war:" 结尾或其余有: 的门路
            int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
                    locationPattern.indexOf(':') + 1);
            if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {// 找出含有 *?{}符号门路涵盖的资源
                return findPathMatchingResources(locationPattern);
            }
            else {
                // 不然,当做单个名字资源
                return new Resource[] {getResourceLoader().getResource(locationPattern)};
            }
        }
    }

}

2.1. PathMatchingResourcePatternResolver.findPathMatchingResources

public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {// 找出含有 *?{}符号门路涵盖的资源
    protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
        // 返回根门路,如 "/WEB-INF/*.xml" 的根门路是 "/WEB-INF/"
        String rootDirPath = determineRootDir(locationPattern);
        // 去除根门路的子门路
        String subPattern = locationPattern.substring(rootDirPath.length());
        // 获取根门路下的所有资源
        Resource[] rootDirResources = getResources(rootDirPath);
        // 后果集
        Set<Resource> result = new LinkedHashSet<>(16);
        for (Resource rootDirResource : rootDirResources) {
            // 解析有: 的协定
            URL rootDirUrl = rootDirResource.getURL();
            // bundle 协定
            if (rootDirUrl.getProtocol().startsWith("bundle")) {
                // 当做 UrlResource
                rootDirResource = new UrlResource(rootDirUrl);
            }
            // vfs 协定
            if (rootDirUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirUrl, subPattern, getPathMatcher()));
            }
            // jar,war,zip,wsjar,vfszip 协定
            else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) {
                // 从 jar 文件中载入资源
                result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPattern));
            }
            else {
                // 从系统文件中载入资源
                result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
            }
        }
        return result.toArray(new Resource[0]);
    }
}

2.2. PathMatchingResourcePatternResolver.findAllClassPathResources

public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
    // 找出无通配符门路涵盖的资源
    protected Resource[] findAllClassPathResources(String location) throws IOException {
        // 去掉结尾的 /
        String path = location;
        if (path.startsWith("/")) {path = path.substring(1);
        }
        Set<Resource> result = doFindAllClassPathResources(path);
        return result.toArray(new Resource[0]);
    }

    protected Set<Resource> doFindAllClassPathResources(String path) throws IOException {Set<Resource> result = new LinkedHashSet<>(16);
        ClassLoader cl = getClassLoader();
        // 通过 classloader 加载资源
        Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
        while (resourceUrls.hasMoreElements()) {URL url = resourceUrls.nextElement();
            // url 转换为 UrlResource,再增加
            result.add(convertClassLoaderURL(url));
        }
        if (!StringUtils.hasLength(path)) {
            // 解决 jar 资源,系统文件资源
            addAllClassLoaderJarRoots(cl, result);
        }
        return result;
    }
}

3. PropertySourcesPropertyResolver

PropertySourcesPropertyResolver
的次要性能是通过 @PropertySource 注解将属性起源注入到有如 @Configuration, @Component, ... 注解的类中

public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
    // 字符值到对象的转换器,默认应用 DefaultConversionService
    private volatile ConfigurableConversionService conversionService;
    // 占位符的前缀,默认是 ${
    private String placeholderPrefix = SystemPropertyUtils.PLACEHOLDER_PREFIX;
    // 占位符的后缀,默认是 }
    private String placeholderSuffix = SystemPropertyUtils.PLACEHOLDER_SUFFIX;
    // 多个值的分隔符,默认 :
    private String valueSeparator = SystemPropertyUtils.VALUE_SEPARATOR;
}
public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
    // 获取一个属性值
    protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {if (this.propertySources != null) {
            // 从起源中遍历
            for (PropertySource<?> propertySource : this.propertySources) {
                // 起源中获取值
                Object value = propertySource.getProperty(key);
                if (value != null) {if (resolveNestedPlaceholders && value instanceof String) {
                        // 解析占位符
                        value = resolveNestedPlaceholders((String) value);
                    }

                    // 转换以后值到其余类型对象,如果需要的话
                    return convertValueIfNecessary(value, targetValueType);
                }
            }
        }
        // 没有就返回 null
        return null;
    }

    // 解析占位符
    protected String resolveNestedPlaceholders(String value) {
        // ... 代码省略

        return resolvePlaceholders(value);
    }

    // 解析占位符
    public String resolvePlaceholders(String text) {if (this.nonStrictHelper == null) {this.nonStrictHelper = createPlaceholderHelper(true);
        }
        // 替换占位符
        return doResolvePlaceholders(text, this.nonStrictHelper);
    }

    // 转换以后值到其余类型对象,如果需要的话
    protected <T> T convertValueIfNecessary(Object value, Class<T> targetType) {
        // ... 代码省略

        ConversionService conversionServiceToUse = this.conversionService;
        if (conversionServiceToUse == null) {
            // ... 代码省略

            // 获取默认的转换器 DefaultConversionService
            conversionServiceToUse = DefaultConversionService.getSharedInstance();}
        // 转换值
        return conversionServiceToUse.convert(value, targetType);
    }
}

来看看 DefaultConversionService
是如何转换对象的

public class DefaultConversionService extends GenericConversionService {public DefaultConversionService() {
        // 初始化的时候就增加默认转换器
        addDefaultConverters(this);
    }

    // 增加默认转换器
    public static void addDefaultConverters(ConverterRegistry converterRegistry) {
        // 增加标量类转换器
        addScalarConverters(converterRegistry);
        // 增加汇合类转换器
        addCollectionConverters(converterRegistry);

        // 转换 ByteBuffer 或字节数组到其余任意类型
        converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
        converterRegistry.addConverter(new StringToTimeZoneConverter());
        converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
        converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());

        converterRegistry.addConverter(new ObjectToObjectConverter());
        converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
        converterRegistry.addConverter(new FallbackObjectToStringConverter());
        converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
    }

    // 增加汇合类转换器
    public static void addCollectionConverters(ConverterRegistry converterRegistry) {ConversionService conversionService = (ConversionService) converterRegistry;

        // 数组转汇合
        converterRegistry.addConverter(new ArrayToCollectionConverter(conversionService));
        // 汇合转数组
        converterRegistry.addConverter(new CollectionToArrayConverter(conversionService));

        // 数组转另一种数组
        converterRegistry.addConverter(new ArrayToArrayConverter(conversionService));
        // 汇合转另一种汇合
        converterRegistry.addConverter(new CollectionToCollectionConverter(conversionService));
        // Map 转另一种 Map
        converterRegistry.addConverter(new MapToMapConverter(conversionService));

        converterRegistry.addConverter(new ArrayToStringConverter(conversionService));
        converterRegistry.addConverter(new StringToArrayConverter(conversionService));

        converterRegistry.addConverter(new ArrayToObjectConverter(conversionService));
        converterRegistry.addConverter(new ObjectToArrayConverter(conversionService));

        converterRegistry.addConverter(new CollectionToStringConverter(conversionService));
        converterRegistry.addConverter(new StringToCollectionConverter(conversionService));

        converterRegistry.addConverter(new CollectionToObjectConverter(conversionService));
        converterRegistry.addConverter(new ObjectToCollectionConverter(conversionService));

        // 转换 Stream 到数组或汇合
        converterRegistry.addConverter(new StreamConverter(conversionService));
    }

    // 增加标量类转换器
    private static void addScalarConverters(ConverterRegistry converterRegistry) {
        // 一个 jdk 版本的数字转换到其余 jdk 版本的数字
        converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());

        converterRegistry.addConverterFactory(new StringToNumberConverterFactory());
        converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter());

        converterRegistry.addConverter(new StringToCharacterConverter());
        converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter());

        converterRegistry.addConverter(new NumberToCharacterConverter());
        converterRegistry.addConverterFactory(new CharacterToNumberFactory());

        converterRegistry.addConverter(new StringToBooleanConverter());
        converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());

        converterRegistry.addConverterFactory(new StringToEnumConverterFactory());
        converterRegistry.addConverter(new EnumToStringConverter((ConversionService) converterRegistry));

        converterRegistry.addConverterFactory(new IntegerToEnumConverterFactory());
        converterRegistry.addConverter(new EnumToIntegerConverter((ConversionService) converterRegistry));

        converterRegistry.addConverter(new StringToLocaleConverter());
        converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());

        converterRegistry.addConverter(new StringToCharsetConverter());
        converterRegistry.addConverter(Charset.class, String.class, new ObjectToStringConverter());

        converterRegistry.addConverter(new StringToCurrencyConverter());
        converterRegistry.addConverter(Currency.class, String.class, new ObjectToStringConverter());

        // String 转 Properties 对象
        converterRegistry.addConverter(new StringToPropertiesConverter());
        // Properties 对象转 String
        converterRegistry.addConverter(new PropertiesToStringConverter());

        converterRegistry.addConverter(new StringToUUIDConverter());
        converterRegistry.addConverter(UUID.class, String.class, new ObjectToStringConverter());
    }
}

这些默认的编辑器都在 convert/support
包下,都不难,举个较简单一点的例子 ArrayToCollectionConverter

final class ArrayToCollectionConverter implements ConditionalGenericConverter {public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        // ... 代码省略

        // 先获取数组长度
        int length = Array.getLength(source);
        TypeDescriptor elementDesc = targetType.getElementTypeDescriptor();
        // 创立汇合
        Collection<Object> target = CollectionFactory.createCollection(targetType.getType(),
                (elementDesc != null ? elementDesc.getType() : null), length);

        // 元素不须要转换
        if (elementDesc == null) {for (int i = 0; i < length; i++) {Object sourceElement = Array.get(source, i);
                target.add(sourceElement);
            }
        }
        // 元素须要转换
        else {for (int i = 0; i < length; i++) {Object sourceElement = Array.get(source, i);
                // 调用注入的 conversionService 转换元素后,再增加
                Object targetElement = this.conversionService.convert(sourceElement,
                        sourceType.elementTypeDescriptor(sourceElement), elementDesc);
                target.add(targetElement);
            }
        }
        return target;
    }
}

4. XmlBeanDefinitionReader

XmlBeanDefinitionReader
的次要性能是从 xml 中解析 bean 定义

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
    // 从一个起源处加载 bean 定义
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        // 获取线程池来装载起源
        Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();

        if (!currentResources.add(encodedResource)) {// 如果增加失败,报错}

        try (InputStream inputStream = encodedResource.getResource().getInputStream()) {InputSource inputSource = new InputSource(inputStream);
            if (encodedResource.getEncoding() != null) {inputSource.setEncoding(encodedResource.getEncoding());
            }
            // 通过资源流来加载 bean 定义
            return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
        }
        catch (IOException ex) {// ... 代码省略}
        finally {// ... 代码省略}
    }

    // 通过资源流来加载 bean 定义
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {

        try {
            // 获取 xml 文件的 Document 对象
            Document doc = doLoadDocument(inputSource, resource);
            int count = registerBeanDefinitions(doc, resource);

            // ... 代码省略

            return count;
        }
        catch (BeanDefinitionStoreException ex) {// ... 代码省略}
        // ... 代码省略
    }

    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        // 实例化一个 BeanDefinitionDocumentReader 对象,默认应用 DefaultBeanDefinitionDocumentReader
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();

        // ... 代码省略

        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));

        // ... 代码省略
    }
}

实质上还是调用的 DefaultBeanDefinitionDocumentReader.registerBeanDefinitions

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
    // 注册 bean 定义
    @Override
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        doRegisterBeanDefinitions(doc.getDocumentElement());
    }

    // 从 doc 根元素开始寻找并注册 bean 定义
    protected void doRegisterBeanDefinitions(Element root) {
        BeanDefinitionParserDelegate parent = this.delegate;
        // 实例化一个新的 bean 定义解析器
        this.delegate = createDelegate(getReaderContext(), root, parent);

        // ... 代码省略

        // 解析 bean 定义
        parseBeanDefinitions(root, this.delegate);

        // ... 代码省略
    }

    // 解析 bean 定义
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        // 如果 bean 定义的 xmlns 命名空间为空,或者为 http://www.springframework.org/schema/beans
        if (delegate.isDefaultNamespace(root)) {NodeList nl = root.getChildNodes();
            // 遍历子节点
            for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);
                if (node instanceof Element) {Element ele = (Element) node;
                    // 如果 bean 定义的 xmlns 命名空间为空,或者为 http://www.springframework.org/schema/beans
                    // 做默认解析
                    if (delegate.isDefaultNamespace(ele)) {parseDefaultElement(ele, delegate);
                    }
                    // 不然做自定义解析
                    else {delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            // 解析自定义的元素
            delegate.parseCustomElement(root);
        }
    }
}
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
    // 做默认解析
    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        // 如果是 <import> 元素,导入其余资源
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {importBeanDefinitionResource(ele);
        }
        // 如果是 <alias> 元素,注册别名
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {processAliasRegistration(ele);
        }
        // 如果是 <bean> 元素,注册 bean 定义
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {processBeanDefinition(ele, delegate);
        }
        // 如果是 <beans> 元素,解析子元素
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {doRegisterBeanDefinitions(ele);
        }
    }

    // 如果是 <bean> 元素,注册 bean 定义
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        // 解析 bean 的名字、别名、定义,包裹为 BeanDefinitionHolder
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {

            // ... 代码省略

            try {// 调用 getReaderContext().getRegistry()注册 bean 定义
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {// ... 代码省略}
            // ... 代码省略
        }
    }
}

再进一层,还是调用的 BeanDefinitionParserDelegate

public class BeanDefinitionParserDelegate {
    // 解析自定义的元素
    public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
        // 获取 xmlns 命名空间
        String namespaceUri = getNamespaceURI(ele);
        // 没有 xmlns 命名空间,返回 null
        if (namespaceUri == null) {return null;}
        // 获取命名空间处理器,默认应用 DefaultNamespaceHandlerResolver
        // DefaultNamespaceHandlerResolver 中,默认加载 META-INF/spring.handlers 指定的处理器
        // 外围的处理器是上面这些
        // http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
        // http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
        // http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
        // http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
        // http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
        // http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
        // http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
        // http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
        // http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler
        // http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
        // http\://www.springframework.org/schema/jdbc=org.springframework.jdbc.config.JdbcNamespaceHandler
        // http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);

        // ... 代码省略

        // 调用处理器解析
        return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    }
}

列举一下这些处理器,前面再解析:

  • SimpleConstructorNamespaceHandler
  • SimplePropertyNamespaceHandler
  • UtilNamespaceHandler
  • ContextNamespaceHandler
  • JeeNamespaceHandler
  • LangNamespaceHandler
  • TaskNamespaceHandler
  • CacheNamespaceHandler
  • MvcNamespaceHandler
  • AopNamespaceHandler
  • JdbcNamespaceHandler
  • TxNamespaceHandler
public class BeanDefinitionParserDelegate {
    // 解析有 bean 定义的元素
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
        // 获取 id 属性
        String id = ele.getAttribute(ID_ATTRIBUTE);
        // 获取 name 属性
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

        List<String> aliases = new ArrayList<>();
        if (StringUtils.hasLength(nameAttr)) {
            // 用,; 分隔为多个别名
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            aliases.addAll(Arrays.asList(nameArr));
        }

        // 默认以 id 属性作为 beanName
        String beanName = id;
        // 如果没有 id 属性,但有 name 属性,取第一个 name 作为 beanName
        if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {beanName = aliases.remove(0);
        }

        // ... 代码省略

        // 真正解析 bean 定义
        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
        if (beanDefinition != null) {if (!StringUtils.hasText(beanName)) {
                // 如果没有 beanName,生成默认的 beanName
                try {if (containingBean != null) {
                        beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
                    }
                    else {beanName = this.readerContext.generateBeanName(beanDefinition);

                        // ... 代码省略
                    }

                }
                catch (Exception ex) {
                    // ... 代码省略

                    return null;
                }
            }
            String[] aliasesArray = StringUtils.toStringArray(aliases);
            return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
        }

        return null;
    }

    // 深层解析 bean 定义
    public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {

        // class 属性
        String className = null;
        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {className = ele.getAttribute(CLASS_ATTRIBUTE).trim();}

        // parent 属性
        String parent = null;
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }

        try {
            // 以 class、parent 创立一个根底的定义对象
            AbstractBeanDefinition bd = createBeanDefinition(className, parent);
            // 把其余属性利用到定义对象上,如 singleton、abstract、lazy-init、autowire、depends-on 等
            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            // 设置 description 属性
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

            // 解析 meta 元素
            parseMetaElements(ele, bd);
            // 解析 lookup-method 元素
            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            // 解析 replaced-method 元素
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

            // 解析 constructor-arg 元素
            parseConstructorArgElements(ele, bd);
            // 解析 property 元素
            parsePropertyElements(ele, bd);
            // 解析 qualifier 元素
            parseQualifierElements(ele, bd);

            // ... 代码省略

            return bd;
        }
        catch (ClassNotFoundException ex) {// ... 代码省略}
        // ... 代码省略

        return null;
    }
}

5. AnnotatedBeanDefinitionReader

AnnotatedBeanDefinitionReader
的次要性能是通过注解注册 bean

public class AnnotatedBeanDefinitionReader {public void registerBean(Class<?> beanClass) {doRegisterBean(beanClass, null, null, null, null);
    }

    public void registerBean(Class<?> beanClass, @Nullable String name) {doRegisterBean(beanClass, name, null, null, null);
    }

    public void registerBean(Class<?> beanClass, Class<? extends Annotation>... qualifiers) {doRegisterBean(beanClass, null, qualifiers, null, null);
    }

    public void registerBean(Class<?> beanClass, @Nullable String name,
            Class<? extends Annotation>... qualifiers) {doRegisterBean(beanClass, name, qualifiers, null, null);
    }

    public <T> void registerBean(Class<T> beanClass, @Nullable Supplier<T> supplier) {doRegisterBean(beanClass, null, null, supplier, null);
    }

    public <T> void registerBean(Class<T> beanClass, @Nullable String name, @Nullable Supplier<T> supplier) {doRegisterBean(beanClass, name, null, supplier, null);
    }

    public <T> void registerBean(Class<T> beanClass, @Nullable String name, @Nullable Supplier<T> supplier,
            BeanDefinitionCustomizer... customizers) {doRegisterBean(beanClass, name, null, supplier, customizers);
    }

    // 注册 bean
    private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
            @Nullable BeanDefinitionCustomizer[] customizers) {

        // 创立一个根底的注解 bean 定义
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

        // ... 代码省略

        // 确保 beanName
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        // 解决元信息通用的注解,如 Lazy、Primary、DependsOn、Role、Description
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        // qualifier 注解的解决
        if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);
                }
                else if (Lazy.class == qualifier) {abd.setLazyInit(true);
                }
                else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }

        // 自定义处理器
        if (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);
            }
        }

        // 封装为 Holder
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

        // ... 代码省略

        // 注册到 registry 中
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
}

6. ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner
的次要性能是扫描指定包来获取 bean

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
    // 扫描包
    public int scan(String... basePackages) {
        // ... 代码省略

        // 扫描
        doScan(basePackages);

        // 注册注解解析处理器
        if (this.includeAnnotationConfig) {
            // 次要是上面的 bean
            // org.springframework.context.annotation.internalConfigurationAnnotationProcessor => ConfigurationClassPostProcessor
            // org.springframework.context.annotation.internalAutowiredAnnotationProcessor => AutowiredAnnotationBeanPostProcessor
            // org.springframework.context.annotation.internalCommonAnnotationProcessor => CommonAnnotationBeanPostProcessor
            // org.springframework.context.annotation.internalPersistenceAnnotationProcessor => PersistenceAnnotationBeanPostProcessor
            // org.springframework.context.event.internalEventListenerProcessor => EventListenerMethodProcessor
            // org.springframework.context.event.internalEventListenerFactory => DefaultEventListenerFactory
            AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }

        // ... 代码省略
    }

    // 扫描
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        // 初始化容器
        Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();

        // 遍历包
        for (String basePackage : basePackages) {
            // 获取包中能够解决的组件
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

            // 遍历组件
            for (BeanDefinition candidate : candidates) {
                // 生成 bean 名字
                String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                if (candidate instanceof AbstractBeanDefinition) {
                    // 注入一些默认值,并确定是否须要主动拆卸其余的 bean
                    postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                }
                if (candidate instanceof AnnotatedBeanDefinition) {
                    // 解决元信息通用的注解,如 Lazy、Primary、DependsOn、Role、Description
                    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                }
                // 如果不存在,可增加
                if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);

                    // ... 代码省略

                    beanDefinitions.add(definitionHolder);
                    // 注册到 registry 中
                    registerBeanDefinition(definitionHolder, this.registry);
                }
            }
        }
        return beanDefinitions;
    }

    // 获取包中能够解决的组件
    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
        // ... 代码省略

        return scanCandidateComponents(basePackage);
    }

    // 获取包中能够解决的组件
    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();
        try {
            // 加上 "classpath*:" 前缀,"**/*.class" 后缀
            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    basePackage + '/' + this.resourcePattern;
            // 获取包下的全副类
            Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
            // 遍历资源
            for (Resource resource : resources) {
                // 如果资源可读,持续进行
                if (resource.isReadable()) {
                    try {
                        // 获取元信息读取器
                        MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                        // 初始化一个根底的 bean 定义
                        ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                        sbd.setSource(resource);

                        // 增加
                        candidates.add(sbd);
                    }
                    catch (Throwable ex) {// ... 代码省略}
                }
                else {// ... 代码省略}
            }
        }
        catch (IOException ex) {// ... 代码省略}
        return candidates;
    }
}

列举一下这些处理器,前面再解析:

  • ConfigurationClassPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • PersistenceAnnotationBeanPostProcessor
  • EventListenerMethodProcessor
  • DefaultEventListenerFactory

后续

更多博客,查看 https://github.com/senntyou/blogs

作者:深予之 (@senntyou)

版权申明:自在转载 - 非商用 - 非衍生 - 放弃署名(创意共享 3.0 许可证)

正文完
 0