深度理解SpringIOC,面试你根本不须要慌!

文章已托管到GitHub,你们能够去GitHub查看阅读,欢迎老板们前来Star! 搜索关注微信公众号 码出Offer 领取各类学习资料!java

深度理解Spring IOC(控制反转)


1、IOC概述

Inverse Of Controll即为控制反转,简称IOCgit

简单来讲,IOC反转了依赖关系的知足方式,由以前的本身建立依赖对象,变为由工厂推送。(变主动为被动,即反转)它解决了具备依赖关系的组件之间的强耦合,使得项目形态更加稳健github

2、什么是IOC?

2.1 了解IOC思想

大概了解了IOC是控制反转,至于如今咱们并不清楚它的思想和做用。那么问题来了,IOC(控制反转)是什么呢?web

控制反转,简称IOC。顾名思义,它是由“控制”和“反转”两个词语组合而成。那么咱们就顺藤摸瓜,分别分析一下这两个词语!spring

2.2 控制

控制一词,咱们须要想的就不少。好比说,达成控制的条件必须是两个对象 ,控制能够分为谁控制谁控制你作什么 。那咱们一一列举这几种状况:数据库

  1. 在Java中咱们以new的方式建立对象,开发者控制控制着开发工具并间接的控制程序建立所须要的依赖对象,对于程序来讲是直接的控制建立对象;若是使用IOC呢?那就能够是IOC容器直接的控制建立对象
  2. 既然是IOC控制建立对象,那么控制建立对象是怎么控制的呢?使用IOC建立对象是须要标签引入外部对象,这说明了IOC容器控制着建立依赖对象的入口

2.3 反转

反转一词,咱们想的也不少。好比说,达成反转的条件必须是两个对象有反转就有正转 ,而后就是反转了些什么 。那么咱们也一一列举说明:微信

  1. 在Java中咱们是间接的实用程序来建立对象,这能够看做正转。那有了IOC容器,一会儿就变了,咱们不用本身new对象,而是直接反转为由IOC建立生成依赖对象并存入IOC容器中
  2. 使用IOC容器建立对象咱们只须要经过配置来告诉它须要建立的对象是什么,并标识一下之后使用什么来获取IOC容器中建立好的对象便可(配置使用IOC的过程),这时候等你想要IOC容器中对象就直接用这个惟一标识来获取就好,而获取的过程确定是IOC经过这个惟一标识来查找并返回给咱们该对象
  3. 也许有的小伙伴仍是不明白反转。为何要把IOC容器帮咱们建立对象的行为叫反转呢?由于由容器帮咱们查找及注入依赖对象,对象只是被动的接受依赖对象。若是不反转呢?开发者就须要建立对象,并找到、获取、使用该对象,此过程当中的全部都有开发者来控制的

3、IOC的做用

经过控制反转,对象在被建立的时候,由一个调控系统内全部对象的外界实体将其所依赖的对象的引用传递给它。也能够说,依赖被注入到对象中。app

好比:Class A中用到了Class B的对象b,通常状况下,须要在A的代码中显式的new一个B的对象。ide

在使用了IOC以后呢?A的代码只须要定义一个私有的B对象,不须要直接new来得到这个对象,而是经过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(xml)来指定工具

既然由配置文件来指定建立对象关系,就大大下降了各个组件之间的强耦合并有利于维护,是项目变得更加稳健灵活

4、IOC解决Dao层和Service层的强耦合

在原始的Web开发中,Dao层和Service层是密不可分的。Dao层为数据访问层,只与数据库打交道。Servcie层为业务处理层,只处理实现相应的业务。而咱们将Web开发中的Dao层和Service层串在一块儿,就须要在Service层new一个私有的Dao层实现对象(XxxDaoImpl)。有了IOC的思想,再想一想传统的Dao层与Service层的实现就显得很不灵活,一旦修改了Dao层实现类,就必须将项目中的源码都修改掉,显然是一件很是可怕的事情。

5、使用IOC解决Dao层和Service层的强耦合

既然解决Dao层和Service层的强耦合那必须得这两个组件对吧。

Dao层

// Dao层接口
package com.mylifes1110.dao;

import com.mylifes1110.bean.User;

public interface UserDao {
    int insertUser(User user);
}

// Dao层实现类
package com.mylifes1110.dao.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;

public class UserDaoImpl implements UserDao {

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserDao------");
        return 0;
    }
}

注意: 咱们在使用IOC时,必须将Dao层实现类对象注入到IOC容器中,这必有一个注入方式来告知IOC容器建立对象和获取对象,在Service层咱们并不须要new实现类对象,而是建立一个Service层的Setter方法来注入UserDaoImpl依赖到UserServcieImpl中(这里能够把它们想为拼装),此时所用的注入方式叫作Setter方法依赖注入,如今不须要纠结,后续我会将依赖注入的全部方式列举并分析依赖注入思想和依赖注入与IOC的关系。

Service层

// Service层接口
package com.mylifes1110.service;

import com.mylifes1110.bean.User;

public interface UserService {
    int insertUser(User user);
}

// Service层实现类
package com.mylifes1110.service.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
import com.mylifes1110.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

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

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserService------");
        return userDao.insertUser(null);
    }
}

spring-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       http://www.springframework.org/schema/context http://www.springframework.org/schema/beans/spring-context.xsd"
>

    <!--id:惟一标识 class:须要被建立的目标对象全限定名-->
    <bean id
="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>

    <!--id:惟一标识 class:须要被建立的目标对象全限定名-->
    <bean id
="UserService" class="com.mylifes1110.service.impl.UserServiceImpl">
        <!--Setter方法依赖注入 name:Service层定义的userDao属性 ref:Dao层bean标签惟一标识-->
        <property name="userDao" ref="UserDao"/>
    </bean>

</beans>

测试类

/**
@MethodName insertUser1
@Param []
@Description 测试IOC的使用
@Author Ziph
@Date 2020/7/12
*/

@Test
public void insertUser1() {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
    UserService userService = (UserService) context.getBean("UserService");
    userService.insertUser(null);
    // 打印结果
    ------insertUser and UserService------
    ------insertUser and UserDao------
}
在这里插入图片描述
在这里插入图片描述
相关文章
相关标签/搜索