理解Spring中的IoC和DI

什么是IoC和DI

IoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度。其基本思想是:借助于“第三方”实现具备依赖关系的对象之间的解耦。php

DI(Dependence Injection 依赖注入):将实例变量传入到一个对象中去(Dependency injection means giving an object its instance variables)。java

  • 控制反转是一种思想
  • 依赖注入是一种设计模式
  • IoC框架使用依赖注入做为实现控制反转的方式

为何须要

在没有IoC以前,咱们要在A类中使用B类,就要在A类中newB类的实例,这样A类和B类之间就出现了耦合。spring

public class A {
    private B b = new B();
}
复制代码

使用了IoC以后,咱们就把实例化这样操做交给框架去帮咱们作了。编程

Spring 中的IoC

容器是Spring的核心,Spring容器负责建立应用程序中的bean并经过DI来协调这些对象之间的关系。设计模式

Spring容器并非只有一个,Spring自带多个容器的实现,能够概括为两种不一样的类型:安全

  1. bean工厂(BeanFactory),最简单的容器,提供基本的DI支持。
  2. 应用上下文(ApplicationContext),继承了BeanFactory,并提供应用框架级别的服务。

做为开发人员,咱们须要告诉Spring哪些对象要做为bean装配到容器中,bean和bean之间的依赖关系。Spring提供了三种主要的装配机制:框架

  • 隐式的bean发现机制和自动装配
  • 在Java中进行显示配置
  • 在XML中进行显示配置

下面咱们逐一介绍这三种机制。函数

自动装配bean

组件扫描:spring会自动发现应用上下文中所建立的bean

@Component 注解代表该类会做为组件类,并告知Spring要为这个类建立bean。学习

@Component
public class Dog {

}
复制代码

@ComponentScan 注解启用了组件扫描。this

@Configuration
@ComponentScan
public class DemoApplication {

}
复制代码

自动装配:Spring自动知足bean之间的依赖

@Autowired 注解能够做用在构造器、方法、属性上。

@Component
public class Dog {
  	// 属性
    @Autowired
    private Cat cat;

  	// 构造器
    // 从Spring 4.3开始,具备单个构造函数的类能够省略@Autowired注释
    @Autowired
    public Dog(Cat cat) {
        this.cat = cat;
    }

  	// 方法
    @Autowired
    public void setCat(Cat cat) {
        this.cat = cat;
    }
}
复制代码

在Java中装配bean

组价配置:声明一个配置类,并在配置类中配置bean

@Configuration 注解代表这个类是配置类,咱们能够在配置类下建立bean。

@bean 注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring上下文中的bean。

/** * 普通类 */
public class BaseBean {

    public void p() {
        System.out.println("Hello bean");
    }
}



/** * 配置类 */
@Configuration
public class BeanConfig {

  	// 这个方法返回一个对象,Spring会把这个对象注册为bean
    @Bean
    public BaseBean getBaseBean() {
        return new BaseBean();
    }

}
复制代码

组件注入:在配置类中把被依赖的组件注入另外一个组件中

两种方式注入bean:

  1. 咱们能够直接调用get方法,获取到对应的组件
  2. get方法中把被依赖的组件做为参数传入,Spring在调用这个方法时,会自动为你注入。
/** * 普通类 */
public class BaseBean {

    public void p() {
        System.out.println("Hello bean");
    }
}

/** * 普通类 */
public class UserBean {
    private BaseBean baseBean;

    public UserBean(BaseBean baseBean) {
        this.baseBean = baseBean;
    }
}



/** * 配置类 */
@Configuration
public class BeanConfig {

    // 这个方法返回一个对象,Spring会把这个对象注册为bean
    @Bean
    public BaseBean getBaseBean() {
        return new BaseBean();
    }

    /** * 如下为两种注入bean的方法 */
  	// 方法一:直接调用get方法
    @Bean
    public UseBean getUseBean() {
        return new UseBean(getBaseBean());
    }

  	// 方法二:当作参数传入,Spring将自动为你注入
    @Bean
    public UseBean getUseBean(BaseBean baseBean) {
        return new UseBean(baseBean);
    }

}
复制代码

一般状况下咱们都会使用方法二。

经过XML装配bean

尽管如今咱们已经再也不怎么使用XML装配bean,但在Spring刚刚出现的时候,XML是描述配置的主要方式,咱们仍是有必要了解一下的。

在使用JavaConfig的时候,咱们建立了一个配置类来装配bean,而在XML配置中,咱们须要建立一个XML文件,而且要以<beans>元素为根。

最为简单的Spring 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 -->

</beans>
复制代码

组件配置

以上文的BaseBean为例,咱们在XML文件中把它声明为bean。

<bean id="baseBean" class="com.example.demo.BaseBean" />
复制代码

组件注入

<bean id="useBean" class="com.example.demo.UseBean" c:_="baseBean" />
复制代码

XML的语法我就再也不这里详述了,有兴趣的同窗能够自行学习。

总结

本文咱们简单介绍了Spring中的IoC,介绍了Spring中装配bean的三种方式:自动化配置,基于Java的显式配置以及基于XML的显式配置。这些技术都是为了描述Spring应用中的组件以及组件之间的关系。

通常来讲咱们都会使用自动化配置,尽可能避免显式配置带来的维护成本。若是不得不使用显式配置的话,咱们优先选择基于Java的配置,它比基于XML的配置更增强大、类型安全而且易于重构。

参考资料

控制反转(IoC)与依赖注入(DI)

Spring 实战

Spring 揭秘

原文首发在个人简书 www.jianshu.com/p/7f7e089f4…

相关文章
相关标签/搜索