计算机系统应用教程网站

网站首页 > 技术文章 正文

《Spring6》第03节:简单介绍Spring创建Bean对象的原理

btikc 2024-09-22 01:09:54 技术文章 20 ℃ 0 评论

《Spring6》第03节:简单介绍Spring创建Bean对象的原理

前面介绍了如何搭建Spring6.x框架的基础开发环境,并且通过几行代码就可以获取到Bean对象,可以看到,我们没有主动通过new关键字创建对象,而是直接调用Spring提供的getBean()方法就获取到了相应的对象。

我猜你可能有疑问,Java里面创建对象不是要使用new关键字吗?为什么在Spring里面没有使用new关键字也可以获取到对象呢?下面我就给你们解答一下这个疑问。

1.1、反射机制

我们在刚学习Java语言的时候,都知道创建对象需要使用new关键字,例如:

  • 创建一个对象,就需要写出下面的代码。
AService aService = new AService();
  • 后面我们又学习了Java中的反射机制,从而又解锁了一种新的创建对象的方式,即:采用反射机制创建对象
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        // 1、加载类对象
        Class<?> clazz = Class.forName("com.spring.study.AService");
        // 2、创建实例对象
        AService aService = (AService) clazz.newInstance();
        // 3、调用类中方法
        aService.demo01();
    }
}

看到这里,你是不是有一点懂了Spring是如何通过XML配置文件创建对象的啦。没错,Spring就是利用的Java反射机制,根据XML配置中的类路径信息,获取到相应的类对象,然后利用无参构造方法实例化对象。这里我们就可以将Spring创建对象的步骤,大致理解成下面三个:

  • 第一步:读取XML配置信息。
  • 第二步:利用Java反射机制和工厂模式,根据读取到的类路径信息,实例化对象。
  • 第三步:通过getBean()方法,获取Bean对象。

下面我们就简单的实现一下Spring创建Bean对象的过程,加深Spring创建Bean的原理的理解,当然,这里只是简单的实现Spring创建并且获取Bean对象的代码,Spring的源码中肯定没有这篇文章写的这么简单的啦。

1.2、读取XML配置

这里采用dom4j来读取XML配置信息,首先引入dom4j的依赖:

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.3</version>
</dependency>

接着编写一个XmlReaderUtil工具类,读取src/main/resources目录下的demo.xml配置文件,将其中配置信息保存到Map容器里面。

package com.spring.study.ioc;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.util.ResourceUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ZhuYouBin
 * @version 1.0.0
 * @date 2024/8/20 11:46
 * @description
 */
public class XmlReaderUtil {
    public static Map<String, String> getBeanDefinitionMap() {
        Map<String, String> beanMap = new HashMap<>();
        try {
            // 创建 SAXReader 对象
            SAXReader reader = new SAXReader();
            // 读取 resources 目录下的 XML 文件
            Document document = reader.read(ResourceUtils.getFile("classpath:demo.xml"));
            // 获取根元素
            Element root = document.getRootElement();
            // 遍历根元素下的子元素
            List<Element> childElements = root.elements();
            for (Element element : childElements) {
                // 获取bean节点的id和class属性
                String id = element.attribute("id").getText();
                String aClass = element.attribute("class").getText();
                beanMap.put(id, aClass);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return beanMap;
    }
}

1.3、创建工厂类

创建一个BeanFactory工厂类,其中定义一个getBean()方法,用于根据指定bean名称获取对象。

package com.spring.study.ioc;

import java.util.HashMap;
import java.util.Map;

/**
 * @author ZhuYouBin
 * @version 1.0.0
 * @date 2024/8/20 11:30
 * @description
 */
public class BeanFactory {
    private static final Map<String, Object> BEAN_MAP = new HashMap<>();

    static {
        Map<String, String> definitionMap = XmlReaderUtil.getBeanDefinitionMap();
        definitionMap.forEach((name, className) -> {
            try {
                // 利用反射机制创建bean
                Class<?> clazz = Class.forName(className);
                Object bean = clazz.newInstance();
                BEAN_MAP.put(name, bean);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public static <T> T getBean(String name) {
        return (T) BEAN_MAP.get(name);
    }
}

1.4、编写测试类

创建TestCode测试类,使用BeanFactory工厂类中的getBean()方法就可以获取到指定的Bean对象了。

package com.spring.study.ioc;

import com.spring.study.AService;

/**
 * @author ZhuYouBin
 * @version 1.0.0
 * @date 2024/8/20 11:50
 * @description 测试代码
 */
public class TestCode {
    public static void main(String[] args) {
        // 1、获取bean
        AService aService = BeanFactory.getBean("aService");
        // 2、使用bean
        aService.demo01();
    }
}

运行结果如下所示:

1.5、源代码获取

源代码地址:

https://gitcode.com/knowledge-base/spring-study/tree/spring6-chapter-03

到此,Spring创建Bean对象以及获取Bean对象的大致过程就简单介绍完了,通过这篇文章是不是对Spring更加熟悉了一点点呢。

今天就到这里,未完待续~~

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表