java多线程    Java入门    vsftp    ftp    linux配置    centos    FRP教程    HBase    Html5缓存    webp    zabbix    分布式    neo4j图数据库    

Spring IOC的理解

IOC 的定义:

Spring提供的容器又称为IoC容器。

IOC 全称为 Inversion of Control ,翻译为控制反转。IOC不是一种技术,而是一种思想。

应用本身不依赖对象的创建和维护,而是交给外部去的容器去维护(这里是Spring), 所以IOC也叫依赖注入DI(DI:Dependency Injection),就对象的创建和维护依赖于外部容器,而不是自己。

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。这个就叫控制反转

下面的例子在线书店,用户服务,书籍服务,购物车服务都依赖一个数据源DataSource。我们看IOC的情况和非IOC的情况

1.读取一个用户信息(非IOC的状态)

这个情况下,必须自己new一个数据源对象

public class UserService {
    private HikariConfig config = new HikariConfig();
    private DataSource dataSource = new HikariDataSource(config);

    public User getUser(long userId) {
        try (Connection conn = dataSource.getConnection()) {
            ...
            return user;
        }
    }
}

2.读取一本书的信息(非IOC的状态)

public class BookService {
    private HikariConfig config = new HikariConfig();
    private DataSource dataSource = new HikariDataSource(config);

    public Book getBook(long bookId) {
        try (Connection conn = dataSource.getConnection()) {
            ...
            return book;
        }
    }
}

3.用户要买书(非IOC的状态)

public class CartServlet extends HttpServlet {
    private BookService bookService = new BookService();
    private UserService userService = new UserService();

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        long currentUserId = getFromCookie(req);
        User currentUser = userService.getUser(currentUserId);
        Book book = bookService.getBook(req.getParameter("bookId"));
        cartService.addToCart(currentUser, book);
        ...
    }
}

传统的应用程序中,控制权在程序本身,程序的控制流程完全由开发者控制,例如:

CartServlet创建了BookService,在创建BookService的过程中,又创建了DataSource组件。这种模式的缺点是,一个组件如果要使用另一个组件,必须先知道如何正确地创建它。

这里的依赖关系为Cart依赖Book和User,Book和User依赖DataSource

开发应用程序的人,要知道如何装配BookService 如何装配DataSource,

改动下代码(IOC的状态 setter属性注入模式)

public class BookService {
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
}

这改动的好处,Book服务的开发者不用关心数据源如何装配的。只关心自己的业务代码即可

因此,IoC又称为依赖注入(DI:Dependency Injection),它解决了一个最主要的问题:将组件的创建+配置与组件的使用相分离,并且,由IoC容器负责管理组件的生命周期。

第二种改动方式 (IOC的状态 构造器模式)

public class BookService {
    private DataSource dataSource;

    public BookService(DataSource dataSource) {
        this.dataSource = dataSource;
    }
}

通过构造器传入数据源

Spring的IoC容器同时支持属性注入和构造方法注入,并允许混合使用。

在设计上,Spring的IoC容器是一个高度可扩展的无侵入容器。所谓无侵入,是指应用程序的组件无需实现Spring的特定接口,或者说,组件根本不知道自己在Spring的容器中运行。

这种无侵入的设计有以下好处:

  1. 应用程序组件既可以在Spring的IoC容器中运行,也可以自己编写代码自行组装配置;
  2. 测试的时候并不依赖Spring容器,可单独进行测试,大大提高了开发效率。

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

  ●谁依赖于谁:当然是应用程序依赖于IoC容器(spring框架)

  ●为什么需要依赖:**应用程序需要IoC容器来提供对象需要的外部资源**;

  ●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象

  ●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

https://www.liaoxuefeng.com/wiki/1252599548343744/1282381977747489#0

https://blog.51cto.com/u_12826294/3085812

https://www.cnblogs.com/xdp-gacl/p/4249939.html

IOC官方文档 https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/beans.html


This entry was posted in JAVA. Bookmark the permalink.
月小升QQ 2651044202, 技术交流QQ群 178491360
首发地址:月小升博客https://java-er.com/blog/spring-ioc/
无特殊说明,文章均为月小升原创,欢迎转载,转载请注明本文地址,谢谢
您的评论是我写作的动力.

Leave a Reply