zoukankan      html  css  js  c++  java
  • 04-Spring自定义标签解析

    自定义标签的解析

    这一篇主要说明自定义标签的解析流程,除了 bean、alias、import、beans之外的标签,都属于自定义标签的范围,自定义标签的解析需要命名空间配合,

    1. 获取对应的命名空间
    2. 根据命名空间获取对应的命名空间处理器 handler
    3. 通过对应的 handler 去找到对应的解析器
    4. 通过对应的解析器去对自定义标签进行解析。
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        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;
                    if (delegate.isDefaultNamespace(ele)) {
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }
    

    parseCustomElement(ele, null)

    获取对应的命名空间,根据命名空间找到对应的命名空间处理器 handler,通过对应的 handler 去找到对应的解析器,最后使用解析器对标签进行对应的解析

    public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
        // 获取对应的命名空间
        String namespaceUri = getNamespaceURI(ele);
        if (namespaceUri == null) {
            return null;
        }
        // 根据命名空间找到对应的NamespaceHandlerspring
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
        if (handler == null) {
            error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
            return null;
        }
        // 调用自定义的NamespaceHandler进行解析
        return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    }
    

    resolve

    从命名空间中解析出对应的Handler,然后拿到对应的解析器对其进行解析。

    getHandlerMappings() 中的数据来源于在 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)) 中 createReaderContext 配置的默认值,会去对应的位置直接加载对应的文件,在此时进行解析。

    public NamespaceHandler resolve(String namespaceUri) {
        // 获取所有已经配置好的handler映射
        Map<String, Object> handlerMappings = getHandlerMappings();
        // 根据命名空间找到对应的信息
        Object handlerOrClassName = handlerMappings.get(namespaceUri);
        if (handlerOrClassName == null) {
            return null;
        }
        else if (handlerOrClassName instanceof NamespaceHandler) {
            // 如果已经做过解析,直接从缓存中读取
            return (NamespaceHandler) handlerOrClassName;
        }
        else {
            // 没有做过解析,则返回的是类路径
            String className = (String) handlerOrClassName;
            try {
                // 通过反射将类路径转化为类
                Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
                if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
                    throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
                                                 "] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
                }
                // 实例化类
                NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
                // 调用自定义的namespaceHandler的初始化方法
                namespaceHandler.init();
                // 讲结果记录在缓存中
                handlerMappings.put(namespaceUri, namespaceHandler);
                return namespaceHandler;
            }
            catch (ClassNotFoundException ex) {
                throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
                                             "] for namespace [" + namespaceUri + "]", ex);
            }
            catch (LinkageError err) {
                throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
                                             className + "] for namespace [" + namespaceUri + "]", err);
            }
        }
    }
    
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        // 获取元素的解析器
        BeanDefinitionParser parser = findParserForElement(element, parserContext);
        return (parser != null ? parser.parse(element, parserContext) : null);
    }
    

    BeanDefinitionParser#parse

    不同的标签有不同的处理类,具体的处理逻辑不尽相同,最终都会将其解析为 BeanDefinition 子类对象,将其注入到 beandefinitionMap 和 beanDefinitionNames 集合中去。

    AnnotationConfigUtils.registerAnnotationConfigProcessors

    在某些步骤会注入一些实现 BeanFactoryPostProcessor 接口的子类,后续在解析一些注解的时候会使用到。

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
        BeanDefinitionRegistry registry, @Nullable Object source) {
    
        // 获取beanFactory
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                // //设置依赖比较器
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                // //设置自动装配解析器
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }
    
        // 创建BeanDefinitionHolder集合
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    
        // 注册内部管理的用于处理@configuration注解的后置处理器的bean
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 注册BeanDefinition到注册表中
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        // 注册内部管理的用于处理@Autowired,@Value,@Inject以及@Lookup注解的后置处理器bean
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        // 注册内部管理的用于处理JSR-250注解,例如@Resource,@PostConstruct,@PreDestroy的后置处理器bean
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        // 注册内部管理的用于处理JPA注解的后置处理器bean
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                                                    AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                    "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        // 注册内部管理的用于处理@EventListener注解的后置处理器的bean
        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }
    
        // 注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }
    
        return beanDefs;
    }
    

  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/ice-image/p/14506294.html
Copyright © 2011-2022 走看看