03.spring-ioc实现原理

167 阅读2分钟

前言

继续学习IOC这部分内容,只不过这次我们用spring实现IOC。

image-20230130134132555

这里核心容器中的每个模块,都对应了单独依赖。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
</dependency>

四个依赖:

  • spring-context 上下文,容器
  • spring-beans 创建对象
  • spring-core 核心jar
  • spring-expression【SpEL】 表达式jar

四个依赖的关系:

image-20230131142600228

通过这个依赖关系图,可以看到,只要是依赖spring-context,就相当于把所有spring的核心模块都依赖进来了。

spring框架中使用IOC

1. 引入依赖

<properties>
    <spring.version>5.3.25</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

2. 配置文件

在src/main/resources目录下创建spring.xml配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userDao" class="com.mayuanfei.springioc.dao.impl.UserDaoImpl" />
</beans>

3. UserDao接口及实现

public interface UserDao {
    /**
     * 添加数据
     */
    public void append();
}
public class UserDaoImpl implements UserDao {
    /**
     * 添加数据
     */
    @Override
    public void append() {
        System.out.println("UserDaoImpl 插入数据库");
    }
}
public class UserDaoImpl2 implements UserDao {
    /**
     * 添加数据
     */
    @Override
    public void append() {
        System.out.println("UserDaoImpl2 插入数据库");
    }
}

4.测试类

@Test
public void testIoc() {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    UserDao userDao = context.getBean("userDao", UserDao.class);
    userDao.append();
}

5. 代码地址

gitee.com/mayuanfei/S… 下的SpringIoc02

spring-ioc实现原理

image-20230131152135365

1. XML解析技术读取配置文件

这里通过Dom4j把配置文件中<bean id="userDao" class="com.mayuanfei.springioc.dao.impl.UserDaoImpl" />读取到spring中。这里最关键的两个属性为:bean的id和bean的全路径名

2. 实例化对象

//获得类的字节码 	
Class clazz =Class.forName("com.mayuanfei.springioc.dao.impl.UserDaoImpl") 	

//通过字节码实例化对象 	
Object obj  = clazz.newInstance(); 	

//将对象放到一个map集合中 	
map.put("userDao",obj)

3.获得对象

public Object getBean(String name){
    Object obj =map.get(name);
    return obj;
}   

4. spring IOC接口

  • BeanFactory接口: IOC容器基本功能接口,是spring内部使用的接口,我们在处理业务时一般不直接使用该接口

  • ApplicationContext 接口: BeanFactory的子接口,提供更多更强大的功能,研发人员一般使用的接口,继承关系如下图:

    image-20230201151058848

​ 其中FileSystemXmlApplicationContext和ClassPathXmlApplicationContext区别在于前者要给出文件系统的全路径;而后者仅仅给出类路径即可。

记忆印记

  • 依赖spring-context,相当于依赖所有spring的核心模块。
  • springioc相当于把配置文件中的bean转换到内存中一个map中进行维护。
  • ApplicationContext中可以获得实例对象