首页 > 其他分享 >spring(自动加载xml装载容器)

spring(自动加载xml装载容器)

时间:2023-12-29 21:45:27浏览次数:29  
标签:xml String spring org bean ATTRIBUTE import public 加载

1.实现将DefaultListableBeanFactory类注入到当前AbstractBeanDefinitionReader中

2.取出xml内容,并生成beanfinition实例对象,注入到DefaultListableBeanFactory类中的map中。

package org.springframework.beans.factory.xml;

import cn.hutool.core.util.StrUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.util.StringUtils;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanReference;
import org.springframework.beans.factory.supper.AbstractBeanDefinitionReader;
import org.springframework.beans.factory.supper.BeanDefinitionRegistry;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
    public static final String BEAN_ELEMENT = "bean";
    public static final String PROPERTY_ELEMENT = "property";
    public static final String ID_ATTRIBUTE = "id";
    public static final String NAME_ATTRIBUTE = "name";
    public static final String CLASS_ATTRIBUTE = "class";
    public static final String VALUE_ATTRIBUTE = "value";
    public static final String REF_ATTRIBUTE = "ref";
    public static final String INIT_METHOD_ATTRIBUTE = "init-method";
    public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
    public static final String SCOPE_ATTRIBUTE = "scope";
    public static final String LAZYINIT_ATTRIBUTE = "lazyInit";
    public static final String BASE_PACKAGE_ATTRIBUTE = "base-package";
    public static final String COMPONENT_SCAN_ELEMENT = "component-scan";

    public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
        super(registry);
    }

    public XmlBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) {
        super(registry, resourceLoader);
    }


    @Override
    public void loadBeanDefinitions(Resource resource) throws BeansException {
        try {
            InputStream inputStream = resource.getInputStream();
            doLoadBeanDefinitions(inputStream);
        } catch (IOException | DocumentException ex) {
            throw new BeansException("IOException parsing XML document from " + resource, ex);
        }
    }

    @Override
    public void loadBeanDefinitions(String location) throws BeansException {
        ResourceLoader resourceLoader = getResourceLoader();
        Resource resource = resourceLoader.getResource(location);
        loadBeanDefinitions(resource);
    }

    public void doLoadBeanDefinitions(InputStream inputStream) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        Element root = document.getRootElement();

        //自动扫描组件
        Element scanComponent = root.element(COMPONENT_SCAN_ELEMENT);
        if (scanComponent != null) {
            String backPackage = scanComponent.attributeValue(BASE_PACKAGE_ATTRIBUTE);
            if (StrUtil.isNotEmpty(backPackage)) {
                scanPackage(backPackage);
            }
        }

        //扫描bean
        List<Element> beanList = root.elements(BEAN_ELEMENT);
        for (Element bean : beanList) {
            String beanId = bean.attributeValue(ID_ATTRIBUTE);
            String beanName = bean.attributeValue(NAME_ATTRIBUTE);
            String className = bean.attributeValue(CLASS_ATTRIBUTE);
            String initMethodName = bean.attributeValue(INIT_METHOD_ATTRIBUTE);
            String destroyMethodName = bean.attributeValue(DESTROY_METHOD_ATTRIBUTE);
            String beanScope = bean.attributeValue(SCOPE_ATTRIBUTE);
            String lazyInit = bean.attributeValue(LAZYINIT_ATTRIBUTE);

            Class<?> clazz;
            try {
                //寻找class类
                clazz = Class.forName(className);
            } catch (ClassNotFoundException e) {
                throw new BeansException("Cannot find class [" + className + "]");
            }

            //ID优先name
            beanName = StrUtil.isNotEmpty(beanId) ? beanId : beanName;
            if (StrUtil.isEmpty(beanName)) {
                beanName = StrUtil.lowerFirst(clazz.getSimpleName());
            }

            //生成bean实例
            BeanDefinition beanDefinition = new BeanDefinition(clazz);

            //设置初始化init-methods
            beanDefinition.setInitMethodName(initMethodName);

            //初始化销毁方式
            beanDefinition.setDestroyMethodName(destroyMethodName);

            //设置beanScope
            if (StrUtil.isNotEmpty(beanScope)) {
                beanDefinition.setScope(beanScope);
            }

            //设置类的属性
            List<Element> propertyList = bean.elements(PROPERTY_ELEMENT);
            for (Element propertyItem : propertyList) {
                String propertyNameAttribute = propertyItem.attributeValue(NAME_ATTRIBUTE);
                String propertyValueAttribute = propertyItem.attributeValue(VALUE_ATTRIBUTE);
                String propertyRefAttribute = propertyItem.attributeValue(REF_ATTRIBUTE);

                //类设置的属性值不能为空
                if (StrUtil.isEmpty(propertyNameAttribute)) {
                    throw new BeansException("The name attribute cannot be null or empty");
                }

                //如果是实例引用,则引入对象
                Object value = propertyValueAttribute;
                if (StrUtil.isNotEmpty(propertyRefAttribute)) {
                    //组装参考示例
                    value = new BeanReference(propertyRefAttribute);
                }

                //追加bean属性内容
                PropertyValue propertyValue = new PropertyValue(propertyNameAttribute, value);
                beanDefinition.getPropertyValues().addPropertyValues(propertyValue);
            }

            //类名不能相同
            if (getRegistry().containsBeanDefinition(beanName)) {
                //beanName不能重名
                throw new BeansException("Duplicate beanName[" + beanName + "] is not allowed");
            }

            //向DefaultListableBeanFactory中的Map注册
            getRegistry().registerBeanDefinition(beanName,beanDefinition);
        }

    }

    /**
     * 自动扫描组件目录
     *
     * @param scanPath
     */
    public void scanPackage(String scanPath) {

    }

}

3.AbstractBeanDefinitionReader:实现调用注册接口去操作bean相关操作

package org.springframework.beans.factory.supper;

import org.springframework.beans.factory.BeansException;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;

public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader {
    private final BeanDefinitionRegistry registry;

    private ResourceLoader resourceLoader;

    public AbstractBeanDefinitionReader(BeanDefinitionRegistry definitionRegistry, ResourceLoader resourceLoader) {
        this.registry = definitionRegistry;
        this.resourceLoader = resourceLoader;
    }

    public AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, new DefaultResourceLoader());
    }

    @Override
    public BeanDefinitionRegistry getRegistry() {
        return registry;
    }

    @Override
    public void loadBeanDefinitions(String[] locations) throws BeansException {
        for (String location : locations) {
            loadBeanDefinitions(location);
        }
    }

    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public ResourceLoader getResourceLoader() {
        return resourceLoader;
    }
}

4.测试

标签:xml,String,spring,org,bean,ATTRIBUTE,import,public,加载
From: https://www.cnblogs.com/jichenghui/p/17935730.html

相关文章

  • 使用Commons JXPath简化XML/JSON处理
    第1章:引言咱们都知道,在现代软件开发中,处理XML和JSON数据几乎是家常便饭。这两种格式广泛应用于配置文件、数据交换、API响应等领域。不过,要手动解析和操作它们,有时候真是让人头大。当你面对一堆复杂的XML或JSON文件时,如果有一个工具能直接帮你找到想要的数据,那该多好。JXPath正......
  • 使用Commons JXPath简化XML/JSON处理
    第1章:引言咱们都知道,在现代软件开发中,处理XML和JSON数据几乎是家常便饭。这两种格式广泛应用于配置文件、数据交换、API响应等领域。不过,要手动解析和操作它们,有时候真是让人头大。当你面对一堆复杂的XML或JSON文件时,如果有一个工具能直接帮你找到想要的数据,那该多好。JXPath正......
  • 使用Commons JXPath简化XML/JSON处理
    第1章:引言咱们都知道,在现代软件开发中,处理XML和JSON数据几乎是家常便饭。这两种格式广泛应用于配置文件、数据交换、API响应等领域。不过,要手动解析和操作它们,有时候真是让人头大。当你面对一堆复杂的XML或JSON文件时,如果有一个工具能直接帮你找到想要的数据,那该多好。JXPath正......
  • Java+SpringBoot+Maven+TestNG+httpclient+Allure+Jenkins实现接口自动化
    一、方案需求目标:测试左移,测试介入研发过程,验证单接口正常及异常逻辑选用工具:Java、SpringBoot、Maven、TestNG、httpclient、Allure、Jenkins方案:创建测试接口测试工程,参照研发设计文档和设计思路,编写正常及异常用例,直接调用服务端接口,覆盖接口逻辑和验证异常处理,提升接口健壮......
  • 网络安全——SpringBoot配置文件明文加密
    信铁寒胜:这边文章真的说得挺好的。XTHS:第一步、XTHS:第二步、XTHS:第三步、XTHS:第四步!就可以实现了。(但是前提,你要先对你的文本进行加密,然后按照ENC(加密文本),放到配置文件中) 一、前言在日常开发中,项目中会有很多配置文件。比如SpringBoot项目核心的数据库配置、Redis账号密码......
  • Springboot集成Nacos
    1.添加依赖com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discovery2.2.9.RELEASEcom.alibaba.cloudspring-cloud-starter-alibaba-nacos-config2.2.9.RELEASE2.注册中心1、把Nacos的Ip和端口配置配置文件中2、在启动类上加上@EnableDiscoveryClient注解3、同一类的服务可......
  • Springboot集成Nacos
    1.添加依赖com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discovery2.2.9.RELEASEcom.alibaba.cloudspring-cloud-starter-alibaba-nacos-config2.2.9.RELEASE2.注册中心1、把Nacos的Ip和端口配置配置文件中2、在启动类上加上@EnableDiscoveryClient注解3、同一类的服务可......
  • 在SpringBoot中自定义指标并使用Prometheus监控报警
    公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享在10分钟教你使用Prometheus监控SpringBoot工程中介绍了如何使用Prometheus监控SpringBoot提供的默认指标,这篇介绍如何自定义业务指标,并使用Prometheus进行监控并报警,同时在Grafana进行展现示例......
  • Spring Boot 正式弃用 Java 8。。
    大家好,我是R哥。关注Spring框架的都知道,因为Spring6.0要求最低JDK17+,所以SpringBoot3.0也必须JDK17+了,但是3.0出来的时候,一站式生成项目还是可以选Java8的,如下图所示:这是Spring提供的一站式生成Spring应用的网站,这个网站可以帮助开发人员一键生成符合S......
  • SpringBoot+modbus4j实现ModebusTCP通讯读取数据
    场景Windows上ModbusTCP模拟Master与Slave工具的使用:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/135290463ModebusTCPModbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP。Modbus协......