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

  • 相关阅读:
    字符串转换日期,日期转换字符串
    List中的Map
    一维数组
    流程控制的基本语法和应用
    《代码阅读方法与实践》读书笔记1
    专业实训题目需求分析
    2015年秋季个人阅读计划
    《人件集 人性化的软件开发》阅读笔记03
    《人件集 人性化的软件开发》阅读笔记02
    《人件集 人性化的软件开发》阅读笔记01
  • 原文地址:https://www.cnblogs.com/ice-image/p/14506294.html
Copyright © 2011-2022 走看看