Spring IoC容器(控制反转和依赖注入)+值注入

Spring IoC容器(控制反转和依赖注入)+值注入

IoC容器(控制反转和依赖注入)

为什么需要控制反转

为什么需要控制反转,new 是强依赖,new 是写死了
导致UserService 依赖于 UserDaoImpl 这个底层模块,违反了依赖倒置原则,同时如果更换实现类就违反了开闭原则

案例
class UserService{
    public void getUser(){
        // 直接依赖(强依赖)
        UserDao userDao = new UserDaoImpl();
    }
}

控制反转介绍

IoC全称Inversion of Control,直译为控制反转
IoC又称为依赖注入(DI:Dependency Injection)
依赖倒置是需求(原则),控制反转是接口,依赖注入是实现类
控制反转就是一种实现依赖倒置的一种有效手段(方法)
而依赖注入是对控制反转的具体实现
IoC容器是在容器(Bean容器)的扩展

IoC容器的核心职责是负责对象的管理以及对象之间的依赖

IoC容器 = IOC + 容器(Bean容器/容器工厂)
file
如果没有IoC只有容器,就不能实现 IoC
容器:人物 IoC:外挂

找到依赖的方式

主动(依赖查找)

从容器中拿,如果修改实现类只需要修改xml(配置文件)
不是控制反转,只是把创建放到容器中解决并没有把管理交给容器解决

UserService userService = context.getBean(UserDao.class);

被动(控制反转/依赖注入)

容器主动给
控制反转是完整把控制权(创建和管理[查找])交给Ioc容器解决
简单来说,我只管使用不管他是怎么来的(比喻:你只管下单,IoC容器管杀管埋)
专业来说,就是让容器自动将需要的 Bean 注入到相关的类中完成装配的过程

依赖的顺序

根据配置文件找到依赖,同时会根据依赖所依赖的去查找

<bean id="userDao" class="org.example.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="org.example.service.impl.UserServiceImpl">
    <constructor-arg name="userDao" ref="userDao"/>
</bean>
<bean id="userController" class="org.example.controller.UserController">
    <constructor-arg name="userService" ref="userService"/>
</bean>

file

实现IoC的两种方式

set方法

这样容器就会自动将bean通过set方法注入到UserService中

<bean id="userService" class="org.example.service.impl.UserServiceImpl">
    <property name="对应的set方法去除set然后将下一个首字母改成小写的名称" ref="需要注入的bean的id"/>
</bean>
构造方法

这样容器就会自动将bean通过构造方法注入到UserService中

<bean id="userService" class="org.example.service.impl.UserServiceImpl">
    <constructor-arg name="构造方法的参数名" ref="需要注入的bean的id"/>
</bean>

值注入

IoC容器可以注入Bean,那也可以注入值
如下是使用 set 方法注入,也可以使用构造方法

<bean id="userDao" class="org.example.dao.impl.UserDaoImpl">
    <property name="string" value="值"/>
    <property name="integer" value="123"/>
    <property name="list">
        <list>
            <value>list1</value>
            <value>list2</value>
        </list>
    </property>
    <property name="set">
        <set>
            <value>set1</value>
            <value>set2</value>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="key" value="value"/>
        </map>
    </property>
</bean>
<bean id="userService" class="org.example.service.impl.UserServiceImpl">
<bean id="userDao" class="org.example.dao.impl.UserDaoImpl">
    <constructor-arg name="string" value="值"/>
    <constructor-arg name="integer" value="123"/>
    <constructor-arg name="list">
        <list>
            <value>list1</value>
            <value>list2</value>
        </list>
    </constructor-arg>
    <constructor-arg name="set">
        <set>
            <value>set1</value>
            <value>set2</value>
        </set>
    </constructor-arg>
    <constructor-arg name="map">
        <map>
            <entry key="key" value="value"/>
        </map>
    </constructor-arg>
</bean>