SpringBoot-探索回顾Spring框架本质

2022-12-01 21:25:55 浏览数 (1)

自始至终,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完成同样目的:

代码语言:javascript复制
@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)

0 人点赞