初探Spring之IOC容器

初探Spring之IoC容器

本博客适合已经会用spring的读者,而不是初学者,这里博主也是会用以后再想想为什么能用的一步,想说深入底层,但显然目前还不能叫深入hhh。

IoC的概念

IoC(Inverse of Control)的字面意思是控制反转,它负责把对象的创建和对象间的调用通过Spring去管理,目的是降低程序耦合度。那这里有两个词,控制和反转,让我们带着两个词进入IoC容器的学习。

对象间调用

在这里插入图片描述

我们在一个对象中使用另一个对象,就必须要显示的去创建另一个对象的实例,不管是构造方法还是工厂方法(工厂方法其实也是new)来获得对象。

这里有三种对象间的调用方式

1、传统java对象的调用方式

class UserSerivce{
    
    
    addUser(){
    
    
        UserDao dao = new UserDao();
        dao.add();
    }
}
class UserDao{
    
    
    add(){
    
    
        System.out.println("add");
    }
}

这里如果我们的UserDao里方法发生了变化,那UserService里的代码显然也要改变。

2、工厂模式

class UserService{
    
    
    void add(){
    
    
        UserDao dao = UserFactory.getUserDao();
    }
}
class UserDao{
    
    
    add(){
    
    
        //*****
    }
}
class UserFactory{
    
    
    public static UserDao getUserDao(){
    
    
        return new UserDao();
    }
}

3、就是我们今天要看的IoC

利用IoC来创建

IoC底层利用的三个技术

  • xml解析
  • 工厂模式
  • 反射

IoC的过程

1#创建xml配置类,配置创建的对象

<bean id="userDao" class="com.feng.UserDao">
</bean>

2#创建工厂类,利用反射机制创建对象

class UserFactory{
    
    
    public static UserDao getUserDao(){
    
    
        String classValue = class属性值;
        //利用xml解析xml文件中的class属性来获取class值com.feng.UserDao
        Class clazz = Class.forName(classValue);
        return (userDao)clazz.newInstance();
    }
}

这里可以发现Spring的IoC方式最大限度降低了程序间的耦合度,对象的创建和对象间的调度都可以丢给Spring来管理。

SpringIoC容器

IoC思想基于容器,IoC容器底层其实就是对象工厂,把容器实例化,Spring给我们提供了两种方式(两个接口)。

扫描二维码关注公众号,回复: 11735233 查看本文章

BeanFactory:

BeanFactory为IOC容器提供了基础功能,Spring文档中提到,当前该类仅仅是为了向后兼容老的版本,除非你不得不用,否则就应该使用第二种容器。

etc:

	BeanFactory beanFactory = new ClassPathXmlApplicationContext("bean1.xml");
//加载配置文件不创建对象
	User user = beanFactory.getBean("user",user.class);
//此时才创建对象

ApplicationContext:

通过API文档可以知道,ApplicationContext是BeanFactory的子接口,并且从文档中也可以看到ApplicaionContext除了包含有BeanFactory的所有功能还支持了更多的功能。

etc:

ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");//加载配置文件时,创建对象 
User user = context.getBean("user",User.class);

在这里插入图片描述

可以看到ApplicationContext的的实现有很多种,常用的两种相信大家并不陌生

FileSystemXmlApplicationContext:默认是从系统的盘符下获取文件 
ClassPathXmlApplicationContext:默认是指项目的classpath路径下面的配置文件

IoC的别名,依赖注入

依赖注入(DI,Dependency Injection)

所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。为什么说IoC又称为DI,其实他们只是从不同的角度去描述一件事情,就是通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦。

这里举一个很容易理解的例子就懂了,比如现在有两个对象,对象A和对象B,现在A要调用B,是不是需要一个IoC容器?我们把A当成一台电脑,B可能是一个鼠标、一个键盘、一个硬盘、一个U盘,反正就是可以插在电脑上,给电脑用的任何东西,电脑(对象A)现在需要U盘(对象B),谁是IoC容器?你就是IoC容器,你做了什么?电脑想用什么你就给他插什么,插上以后,他就有了对象B的控制权,(读取U盘也好,连接鼠标也好)。你(IoC容器只负责满足他),要什么给什么,他也不需要操心怎么创建鼠标、键盘(创建对象),也不需要操心最后怎么摧毁,反正你(IoC)一切包办,是不是很好理解。

现在需要U盘(对象B),谁是IoC容器?你就是IoC容器,你做了什么?电脑想用什么你就给他插什么,插上以后,他就有了对象B的控制权,(读取U盘也好,连接鼠标也好)。你(IoC容器只负责满足他),要什么给什么,他也不需要操心怎么创建鼠标、键盘(创建对象),也不需要操心最后怎么摧毁,反正你(IoC)一切包办,是不是很好理解。

传统实现里,对象A要什么都要自己去new,各个组件间的耦合度十分严重。有了IoC容器后,它把组件之间的关系从程序内部提到外部容器,也就是说由容器在运行期将组件间的某种依赖关系动态注入组件中。

SpringIoC例子

实体类

public class Hello {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Hello{" +
                "name='" + name + '\'' +
                '}';
    }
}

beans.xml

<?xml version="1.0" encoding="GBK"?>
<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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用Spring来创建对象,在Spring这些都成为Bean

        类型  变量名 = new 类型();
        Hello hello = new Hello();

        id = 变量名
        class = new 的对象
        property 相当于给对象的属性设置一个值
        
        ref:引用Spring容器中创建好的对象
        value:具体的值,基本数据类型
    -->
    <bean id="hello" class="com.feng.pojo.Hello">
        <property name="name" value="Spring"/>
    </bean>

</beans>

测试类

public class MyTest {
    
    
    public static void main(String[] args) {
    
    
        //获取Spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext( "beans.xml");
        //我们的对象现在都在Spring中管理,我们要使用直接去里面取出来即可
        Hello hello = (Hello)context.getBean("hello");
        System.out.println(hello.toString());
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43876186/article/details/108600153