概述

  • IOC (Inversion of Control) 控制反转

    • 使用对象时,由主动new产生对象,转换为由外部提供对象,这里的外部是指 Spring 容器,此过程中,对象的创建控制权由程序转移到了外部,此思想称为控制反转
    • Spring 技术 对 IOC 思想进行了实现
      • Spring提供了一个容器,称为 IOC 容器,用来充当 IOC 思想中的外部
      • IOC容器负责对象的创建,初始化等一系列的工作,对创建或者被管理的对象在IOC容器中,统称为Bean
  • DI (Dependency Injection)依赖注入

    • 在容器中建立beanbean的依赖关系的整个过程,称为依赖注入

IOC(控制反转)案例

BookService

public interface BookService {
    void addBook();
}

BookServiceImpl

public class BookServiceImpl implements BookService {
    @Override
    public void addBook() {
        System.out.println("BookServiceImpl add a book......");
    }
}

applicationContext.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,由Spring为我们创建对象-->
    <bean id="bookServiceBeanid" class="com.origin.service.impl.BookServiceImpl"/>
</beans>

BookTest

public class BookTest {
    public static void main(String[] args) {
        //容器加载配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //根据id去拿到容器为我们创建好的对象
        BookService bookService = (BookService) context.getBean("bookServiceBeanid");
        //使用对象,调用方法
        bookService.addBook();
    }
}

运行结果

image-1652192175058

DI(依赖注入)案例

UserDao

public interface UserDao {
    void addUser();
}

UserDaoImpl

public class UserDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("UserDaoImpl add a user......");
    }
}

UserService

public interface UserService {
    void addUser();
}

UserServiceImpl

public class UserServiceImpl implements UserService {

    // UserServiceImpl中存在UserDao,两者存在关系,故UserServiceImpl依赖UserDao;
    // 所以在UserServiceImpl创建时,要将UserDao进行注入,称为依赖注入。
    private UserDao userDao;

    @Override
    public void addUser() {
        userDao.addUser();
    }

    public void setUserDao(UserDaoImpl userDao) {
        this.userDao = userDao;
    }
}

applicationContext.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">

    <!--配置UserDao的bean-->
    <bean id="UserDaoBeanid" class="com.origin.dao.impl.UserDaoImpl"/>

    <bean id="userServiceBeanid" class="com.origin.service.impl.UserServiceImpl">
        <!--UserDao作为UserServiceImpl的一个属性,在此处进行注入-->
        <property name="userDao" ref="UserDaoBeanid"/>
    </bean>
</beans>

UserTest

public class UserTest {
    public static void main(String[] args) {
        //容器加载配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //根据id去拿到容器为我们创建好的对象
        UserService userService = (UserService) context.getBean("userServiceBeanid");
        //使用对象,调用方法
        userService.addUser();
    }
}

运行结果

image-1652192086174

哪些对象适合被Spring管理

项目中并不是所有的对象都要交给Spring来管理:

  • 适合交给Spring容器管理的对象
    • 表现层对象:servlet
    • 业务层对象:service
    • 数据层对象:dao
    • 工具对象:util
    • 配置对象:configuration
  • 不适合交给Spring容器管理的对象
    • 封装实体的域对象:domain,pojo,entity

结语

为什么不在调用方法的时候,直接new对象出来,然后通过调用方法即可?

首先,这样功能上肯定是可以实现的,但是对于开发来讲,这种方式不仅会写很多重复的代码,而且会创建很多基于相同类型的对象,当项目得体量很大的时候,使用一次方法,就要创建一个对象,无异于给内存造成压力。

这也正是为什么Spring创建的bean默认是一个单例实例。