Spring IoC容器与Bean管理19:Bean对象的作用域及生命周期四:实现一个简单的IoC容器;(本篇博客仅做参考用)

本文旨在通过一个简单的例子,帮助读者深入理解Spring IoC容器的工作原理。创建一个名为s07的Maven工程,定义了一个Apple类,并在applicationContext.xml中配置了一个Apple实例。接着,模拟实现ApplicationContext接口和ClassPathXmlApplicationContext类,使用反射机制解析XML配置文件,创建并初始化IoC容器。最后,通过SpringApplication测试类获取并打印配置的Apple对象。整个过程展示了IoC容器如何利用Map存储bean并进行数据注入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明:

(1)这篇博客的目的是,帮助加深对Spring IoC容器的理解;主要是理解,Spring IoC容器背后是如何利用反射机制完成对象的创建和数据的注入的;
(2)这篇博客中的内容不需要记忆,仅作提升理解Spring IoC容器用;

(3)通过本篇博客的介绍,能够感受到IoC容器的原理并不复杂;IoC容器本质的是一个Map键值对对象;

(4)本篇博客仅仅是IoC容器的基础实现;Spring框架中的IoC容器远比本篇博客中的内容复杂的多;

目录

0.为了演示,创建一maven工程:s07

1.创建Apple类: 

2.创建applicationContext.xml配置文件

3.创建ApplicationContext接口和ClassPathXmlApplicationContext实现类

4.创建SpringApplication类,去测试


0.为了演示,创建一maven工程:s07

1.创建Apple类: 

Apple类:

package com.imooc.spring.ioc.entity;

import javax.print.attribute.standard.RequestingUserName;

public class Apple {
    private String title;
    private String color;
    private String origin;

    public Apple() {
    }

    public Apple(String title, String color, String origin) {
        this.title = title;
        this.color = color;
        this.origin = origin;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getOrigin() {
        return origin;
    }

    public void setOrigin(String origin) {
        this.origin = origin;
    }
}

说明:

(1)这个Apple类没什么好说的,一个普通的javaBean;

然后,我们去创建一个配置文件,然后在配置文件中,按照Spring IoC的规则和样式,写一个Apple对象的信息;

2.创建applicationContext.xml配置文件

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="红富士"/>
        <property name="color" value="红色"/>
        <property name="origin" value="欧洲"/>
    </bean>
</beans>

 说明:

(1)这个配置文件名字可以随便起,那就干脆和Spring IoC一样,也叫做applicationContext.xml吧;

(2)这个applicationContext.xml中,按照Spring IoC配置文件的规则和样式,写了一个Apple对象的信息;

配置文件写好了之后,对于这个配置文件,是如何在运行时,创建对象嘞?我们需要自己去实现IoC容器;下面按照Spring IoC的规则和样式,去加载xml配置文件,完成IoC容器的初始化工作;

3.创建ApplicationContext接口和ClassPathXmlApplicationContext实现类

ApplicationContext接口:

package com.imooc.spring.ioc.context;

/**
 * 这个接口,就来模拟Spring中的ApplicationContext接口;
 */
public interface ApplicationContext {
    public Object getBean(String beanId);
}

说明:

(1)模拟Spring IoC容器,在ApplicationContext接口中,创建一个getBean()方法;

……………………………………………………

ClassPathXmlApplicationContext实现类:

package com.imooc.spring.ioc.context;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 这个类模拟Spring中的ClassPathXmlApplicationContext类;
 * 这个类的作用:(1)实现ApplicationContext接口;(2)完成IoC容器的创建过程;
 */
public class ClassPathXmlApplicationContext implements ApplicationContext{
    private Map iocContainer = new HashMap();
    public ClassPathXmlApplicationContext(){
        try{
            String filePath = this.getClass().getResource("/applicationContext.xml").getPath();
            filePath = new URLDecoder().decode(filePath, "UTF-8");
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File(filePath));
            List<Node> beans = document.getRootElement().selectNodes("bean");
            for (Node node : beans) {
                Element element = (Element) node;
                String id = element.attributeValue("id");
                String className = element.attributeValue("class");
                Class c = Class.forName(className);
                Object obj = c.newInstance();
                List<Node> properties = element.selectNodes("property");
                for (Node p : properties) {
                    Element property = (Element) p;
                    String propName = property.attributeValue("name");
                    String propValue = property.attributeValue("value");
                    String setMethodName = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
                    Method setMethod = c.getMethod(setMethodName, String.class);
                    setMethod.invoke(obj, propValue);//通过setter方法注入数据
                }
                iocContainer.put(id, obj);
            }
            System.out.println("IoC容器初始化完毕。");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public Object getBean(String beanId) {
        return iocContainer.get(beanId);
    }
}

说明:

(1)这个类的职责就是实现ApplicationContext接口,并且完成IoC容器的创建过程;可以这样理解:每一个ClassPathXmlApplicationContext对象,都对应一个IoC容器,这个容器本身是用来存储对象的;

(2)在Java中,IoC容器使用Map去保存对象,key对应了beanId,value对应了相应的对象;

(3)在实例化ClassPathXmlApplicationContext对象的过程中,去加载处理applicationContext.xml配置文件,所以主要代码都写在了ClassPathXmlApplicationContext的默认构造方法中了。同时,因为在这个过程中可能会产生异常,所以写在了try块中;

(4)获取applicationContext.xml这个配置文件的地址;

这儿的内容,前面遇到过N次,比如第一次遇到是在【前台系统二:需求分析与数据建模:创建数据工具类、分页工具类;Dao数据对象访问类;(分页模块的Model的Dao部分)】,如有需要可以快速参考下这篇博客;

(5)获得了applicationContext.xml文件的地址后,就是解析这个文件了;由于这个文件是xml文件,所以可以利用现有的轮子,以提高程序的效率;引入dom4j和jaxen;

dom4j:是java的xml解析组件,其可以把xml文件转成一个document对象,帮助我们读取和操作xml的内容;jaxen:在使用Dom4j,利用XPath查询时候,必须要先下载Jaxen的jar包;在快速查询xml文件的时候,需要引入这个dom4j底层依赖的Jaxen;这部分如有需要可以快速参考【XML三:如何使用Java操作XML?DOM;Dom4j简介;项目导入Dom4j这个jar包】及附近相关文章;

(6)解析xml文件:这部分如有需要可以快速参考【XML三:如何使用Java操作XML?DOM;Dom4j简介;项目导入Dom4j这个jar包】及附近相关文章;

有关反射技术,如有需要可以快速参考下【Java反射一:反射引入(一个案例,感性认识什么是反射);(.class,Class.forName()和.getClass()的区别)】及附近相关文章;

至此,这个IoC容器的初始化的代码就写好了;

4.创建SpringApplication类,去测试

SpringApplication类:

package com.imooc.spring.ioc;

import com.imooc.spring.ioc.context.ApplicationContext;
import com.imooc.spring.ioc.context.ClassPathXmlApplicationContext;
import com.imooc.spring.ioc.entity.Apple;

public class SpringApplication {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext();
        Apple sweetApple = (Apple) context.getBean("sweetApple");
        System.out.println(sweetApple);
    }
}

运行结果:

……………………………………………………

这儿打一个断点,进一步观察:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值