自始至终,SpringBoot框架都是为了能够帮助使用Spring框架的开发 快速高效地构建 一个个基于Spring框架以及Spring生态体系的应用解决方案。要深刻理解SpringBoot框架,首先我们需要深刻理解Spring框架。
一、Spring 中的 IoC、DI 和 DL
部分Java开发者对 IoC 和 DI 的概念有些混淆,认为二者是对等的,实际IoC(Inversion Of Control——控制反转)有两种方式:
- 一种就是DI(Dependency Injection——依赖注入)是当前软件实体被动接受其依赖的其他组件被IoC容器注入;
- 而另一种是DL(Dependency Lookup——依赖査找)是当前软件实体主动去某个服务注册地査找其依赖的那些服务。
概念之间的关系如图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MRnrEDuD-1614673450451)(…/…/Study notes/SpringBoot/notes/image/图2-1 IOC相关概念示意图.png)]
以一下Spring IoC容器的一个典型代码片段为例
代码语言:javascript复制public class App (
public static void main(String[] args) (
Applicationcontext context = new FileSystemXmlApplication-Context("...");
// ...
MockService service = context.getBean(MockService.class);
service.doSomething();
)
)
任何一个使用Spring框架构建的独立的Java应用,通常都会存在一行类似于context.getBean(..);
的代码,实际上,这行代码做的就是DL的工作,而构建的任何一种IoC容器背后(比如 BeanFactory或者ApplicationContext)发生的事情,则更多是DI的过程(也可能有部分DL的逻辑用于对接遗留系统)。
此外,Spring IoC容器的依赖注入工作可以分为两个阶段:
阶段一:收集和注册
第一个阶段可以认为是构建和收集bean定义的阶段,在这个阶段中,我 们可以通过XML或者Java代码的方式定义一些bean,然后通过手动组装或者让容器基于某些机制自动扫描的形式,将这些bean定义收集到IoC容器中。
阶段二:分析和组装
第二阶段要干的事情就是分析这些已经在IoC容器之中的bean, 然后根据它们之间的依赖关系先后组装它们。如果IoC容器发现某个bean依赖另一个bean,它就会将这另一个bean注入给依赖它的那个bean,直到所有 bean的依赖都注入完成,所有bean都“整装待发”,整个IoC容器的工作即算完成。
二、JavaConfig 与 @Configuration
Java 5的推出,加上当年基于纯Java Annotation的依赖注入框架Guice的 出现,使得Spring框架及其社区也“顺应民意”,推出并持续完善了基于Java 代码和Annotation元信息的依赖关系绑定描述方式,即JavaConfig项目
基于JavaConfig方式的依赖关系绑定描述基本上映射了最早的基于XML的配置方式,比如
表达形式层面
基于XML的配置方式是这样的:
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi= nhttp://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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/context/spring-context.xsd">
<!-- bean 定义-->
</beans>
基于JavaConfig的配置方式是这样的:
代码语言:javascript复制©Configuration
public class MockConfiguration{
// bean定义
}
任何一个标注了 ©Configuration的Java类定义都是一个JavaConfig配 置类。
注册bean定义层面
基于XML的配置形式是这样的:
代码语言:javascript复制<bean id= "mockService" class="..MockServicelmpl">
...
</bean>
而基于JavaConfig的配置形式是这样的:
代码语言:javascript复制©Configuration
public class MockConfiguration {
@Bean
public MockService mockService() {
return new MockServiceJmpl();
}
}
任何一个标注了 @Bean的方法,其返回值将作为一个bean定义注册到 Spring的IoC容器,方法名将默认成为该bean定义的id。
表达依赖注入关系层面
为了表达bean与bean之间的依赖关系,在XML形式中一般是这样的:
代码语言:javascript复制<bean id= "mockService" class="..MockServicelmpl">
<property name="dependencyService" ref="dependencyservice"/>
</bean>
<bean id="dependencyservice" class="DependencyServicelmpl"/>
而在JavaConhg中则是这样的:
代码语言:javascript复制@Configuration
public class MockConfiguration {
@Bean
public MockService mockService() {
return new MockServiceImpl(dependencyservice());
}
@Bean
public Dependencyservice dependencyservice() {
return new DependencyServicelmpl();
}
}
如果一个bean的定义依赖其他bean,则直接调用对应JavaConfig类中依赖bean的创建方法就可以了。
三、其他高曝光率的Annotation
©Configuration在前面已经提及过了,这里不再赘述,下面看几个其他比较常见的Annotation,便于为后面更好地理解SpringBoot框架
1、@ComponentScan
@ComponentScan
: 对应 XML 配置形式中的 context:component-scan
元 素
注解作用:@ComponentScan用于类或接口上主要是指定扫描路径,spring会把指定路径下带有指定注解的类自动装配到bean容器里。会被自动装配的注解包括@Bean、@Controller、@Service、@Component、@Repository等等。
2、@lmport 与 @lmportResource
在XML形式的配置中,我们通过<import resource=,'XXX.xml"/>
的形式 将多个分开的容器配置合到一个配置中,在JavaConfig形式的配置中,我们则 使用@Import这个Annotation完成同样目的:
@Configuration
©Import (MockConfiguration.class)
public class XConfiguration {
...
}
@Import只负责引入JavaConfig形式定义的loC容器配置,如果有一些遗 留的配置或者遗留系统需要以XML形式来配置(比如dubbo框架),我们依然 可以通过@ImportResource将它们一起合并到当前JavaConfig配置的容器中:
代码语言:javascript复制@Configuration
@ImportResource("...")
public class XConfiguration {
...
}
参考:
- 《SpringBoot揭秘 快速构建微服务体系》 第二章
- 浅析Spring IOC、依赖注入(DI)和依赖查找(DL)