itjavashuai 2019-12-15
IoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度。其基本思想是:借助于“第三方”实现具有依赖关系的对象之间的解耦。
DI(Dependence Injection 依赖注入):将实例变量传入到一个对象中去(Dependency injection means giving an object its instance variables)。
在没有IoC之前,我们要在A
类中使用B
类,就要在A
类中new
出B
类的实例,这样A
类和B
类之间就出现了耦合。
public class A { private B b = new B(); }
使用了IoC之后,我们就把实例化这样操作交给框架去帮我们做了。
容器是Spring的核心,Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。
Spring容器并不是只有一个,Spring自带多个容器的实现,可以归纳为两种不同的类型:
BeanFactory
),最简单的容器,提供基本的DI支持。ApplicationContext
),继承了BeanFactory
,并提供应用框架级别的服务。作为开发人员,我们需要告诉Spring哪些对象要作为bean装配到容器中,bean和bean之间的依赖关系。Spring提供了三种主要的装配机制:
下面我们逐一介绍这三种机制。
@Component
注解表明该类会作为组件类,并告知Spring要为这个类创建bean。
@Component public class Dog { }
@ComponentScan
注解启用了组件扫描。
@Configuration @ComponentScan public class DemoApplication { }
@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; } }
@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:
get
方法,获取到对应的组件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,但在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的配置更加强大、类型安全并且易于重构。
原文首发在我的简书 https://www.jianshu.com/p/7f7e089f4909