Spring框架—基础介绍
原文地址:https://www.cnblogs.com/lagou/p/10552815.html
目录
一、spring基本概念
二、spring框架
三、spring中机制和实现
三、spring应用相关
四、Spring的Context的初始化流程
六:Spring扩展
七、springboot相关的知识点
一、spring基本概念
本文涉及的流程与实现默认都是基于最新的5.x版本。spring中的几个重要概念如下:
▌1.IOC
IOC,就是控制反转,如最左边,拿公司招聘岗位来举例:假设一个公司有产品、研发、测试等岗位。如果是公司根据岗位要求,逐个安排人选,如图中向下的箭头,这是正向流程。如果反过来,不用公司来安排候选人,而是由第三方猎头来匹配岗位和候选人,然后进行推荐,如图中向上的箭头,这就是控制反转。在spring中,对象的属性是由对象自己创建的,就是正向流程;如果属性不是对象创建,而是由spring来自动进行装配,就是控制反转。这里的DI也就是依赖注入,就是实现控制反转的方式。正向流程导致了对象于对象之间的高耦合,IOC可以解决对象耦合的问题,有利于功能的复用,能够使程序的结构变得非常灵活。
▌2.context上下文和bean
spring进行IOC实现时使用的有两个概念:context上下文和bean。如中间图所示,所有被spring管理的、由spring创建的、用于依赖注入的对象,就叫做一个bean。Spring创建并完成依赖注入后,所有bean统一放在一个叫做context的上下文中进行管理。
▌3.AOP
AOP就是面向切面编程。如右面的图,一般程序执行流程是从controller层调用service层、然后service层调用DAO层访问数据,最后在逐层返回结果。这个是图中向下箭头所示的按程序执行顺序的纵向处理。但是,一个系统中会有多个不同的服务,例如用户服务、商品信息服务等等,每个服务的controller层都需要验证参数,都需要处理异常,如果按照图中红色的部分,对不同服务的纵向处理流程进行横切,在每个切面上完成通用的功能,例如身份认证、验证参数、处理异常等等、这样就不用在每个服务中都写相同的逻辑了,这就是AOP思想解决的问题AOP以功能进行划分,对服务顺序执行流程中的不同位置进行横切,完成各服务共同需要实现的功能。
二、spring框架
上图列出了spring框架主要包含的组件。这张图来自spring4.x的文档。目前最新的5.x版本中右面的portlet组件已经被废弃掉,同时增加了用于异步响应式处理的WebFlux组件。并不需要对所有的组件都详细了解,只需重点了解最常用的几个组件实现,以及知道每个组件用来实现哪一类功能。图中红框是比较重要的组件,core组件是spring所有组件的核心;bean组件和context组件我刚才提到了,是实现IOC和依赖注入的基础;AOP组件用来实现面向切面编程;web组件包括springmvc是web服务的控制层实现。
三、spring中机制和实现
▌1.AOP
AOP的实现是通过代理模式,在调用对象的某个方法时,执行插入的切面逻辑。实现的方式有动态代理也叫运行时增强,比如jdk代理、CGLIB;静态代理是在编译时进行织入或类加载时进行织入,比如AspectJ。关于AOP还需要了解一下对应的Aspect、pointcut、advice等注解和具体使用方式。
▌2.placeHolder动态替换
主要需要了解替换发生的时间,是在bean definition创建完成后,bean初始化之前,是通过实现BeanFactoryPostProcessor接口实现的。主要实现方式有PropertyPlaceholderConfigurer和PropertySourcesPlaceholderConfigurer。这两个类实现逻辑不一样,spring boot使用PropertySourcesPlaceholderConfigurer实现。
▌3.事务
需要了解spring 中对事务规定的隔离类型和事务传播类型。要知道事务的隔离级别是由具体的数据库来实现的,在数据库部分我会详细介绍。事务的传播类型,可以重点了解最常用的REQUIRED和SUPPORTS类型。
▌4.核心接口类
- ApplicationContext保存了ioc的整个应用上下文,可以通过其中的beanfactory获取到任意到bean;
- BeanFactory主要的作用是根据bean definition来创建具体的bean;
- BeanWrapper是对Bean的包装,一般情况下是在spring ioc内部使用,提供了访问bean的属性值、属性编辑器注册、类型转换等功能,方便ioc容器用统一的方式来访问bean的属性;
- FactoryBean通过getObject方法返回实际的bean对象,例如motan框架中referer对service的动态代理就是通过FactoryBean来实现的。
▌5.Scope
- bean的scope是指bean的作用域,默认情况下是单例模式,这也是使用最多的一种方式;多例模式,即每次从beanFactory中获取bean都会创建一个新的bean。
- request、session、global-session是在web服务中使用的scope,request每次请求都创建一个实例,session是在一个会话周期内保证只有一个实例。
- global-session在5.x版本中已经不在使用,同时增加了Application和Websocket两种scope,分别保证在一个ServletContext与一个WebSocket中只创建一个实例。
▌6.事件机制
spring的事件机制需要知道spring定义的五种标准事件,具体事件可见上图,了解如何自定义事件和实现对应的applicationListener来处理自定义事件。
三、spring应用相关
▌1.常用注释
a.类型类注释::类型类注释包括controller、service等,需要重点了解.其中component和bean注解的区别如下:
- @Component注解在类上使用表明这个类是个组件类,需要Spring为这个类创建bean。
- @Bean注解使用在方法上,告诉Spring这个方法将会返回一个Bean对象,需要把返回的对象注册到Spring的应用上下文中。
b.设置类注解:重点了解@Autowire和@Qualifier以及bytype、byname等不同的自动装配机制。
c.web类注解:主要以了解为主,关注@RequestMapping、@GetMapping、@PostMapping等路径匹配注解,以及@PathVariable、@RequestParam 等参数获取注解。
d.功能类注解:包括@ImportResource引用配置、@ComponentScan注解自动扫描、@Transactional事务注解等等,这里不一一介绍了。
▌2.配置方式
需要了解配置spring的几种方式,xml文件配置、注解配置和使用api进行配置。自动装配机制需要了解按类型匹配进行自动装配,按bean名称进行自动装配,构造器中的自动装配和自动检测等主要的四种方式。还需要了解一下list、set、map等集合类属性的配置方式以及内部bean的使用。
四、Spring的Context的初始化流程
图中左上角是三种类型的context,xml配置方式的context、springboot的context和web服务的context。不论哪种context,创建后都会调用到AbstractApplicationContext类的refresh方法,这个方法是我们要重点分析的。refresh方法中,操作共分13步:
- 第1步:对刷新进行准备,包括设置开始时间、设置激活状态、初始化context环境中的占位符,这个动作根据子类的需求由子类来执行,然后验证是否缺失必要的properties;
- 第2步:刷新并获得内部的bean factory;
- 第3步:对bean factory进行准备工作,比如设置类加载器和后置处理器、配置不进行自动装配的类型、注册默认的环境bean;
- 第4步:为context的子类提供后置处理bean factory的扩展能力。如果子类想在bean定义加载完成后,开始初始化上下文之前做一些特殊逻辑,可以复写这个方法;
- 第5步,执行context中注册的bean factory后缀处理器;
注:这里有两种后置处理器,一种是可以注册bean的后缀处理器,另一种是针对bean factory进行处理的后置处理器。执行的顺序是,先按优先级执行可注册bean的处理器,在按优先级执行针对beanfactory的处理器。对springboot来说,这一步会进行注解bean definition的解析。流程如右面小框中所示,由ConfigurationClassPostProcessor触发、由ClassPathBeanDefinitionScanner解析并注册到bean factory。
- 第6步:按优先级顺序在beanfactory中注册bean的后缀处理器,bean后置处理器可以在bean初始化前、后执行处理;
- 第7步:初始化消息源,消息源用来支持消息的国际化;
- 第8步:初始化应用事件广播器。事件广播器用来向applicationListener通知各种应用产生的事件,是一个标准的观察者模式;
- 第9步,是留给子类的扩展步骤,用来让特定的context子类初始化其他的bean;
- 第10步,把实现了ApplicationListener的bean注册到事件广播器,并对广播器中的早期未广播事件进行通知;
- 第11步,冻结所有bean描述信息的修改,实例化非延迟加载的单例bean;
- 第12步,完成上下文的刷新工作,调用LifecycleProcessor的onFresh()方法以及发布ContextRefreshedEvent事件;
- 第13步:在finally中,执行第十三步,重置公共的缓存,比如ReflectionUtils中的缓存、AnnotationUtils中的缓存等等;
至此,spring的context初始化完成。这里仅介绍了最主要的主流程,建议课后阅读源码来复习这个知识点,补全细节。
五:Spring中bean的生命周期
面试中经常问到的bean的生命周期,先看绿色的部分,bean的创建过程:
- 第1步:调用bean的构造方法创建bean;
- 第2步:通过反射调用setter方法进行属性的依赖注入;
- 第3步:如果实现BeanNameAware接口的话,会设置bean的name;
- 第4步:如果实现了BeanFactoryAware,会把bean factory设置给bean;
- 第5步:如果实现了ApplicationContextAware,会给bean设置ApplictionContext;
- 第6步:如果实现了BeanPostProcessor接口,则执行前置处理方法;
- 第7步:实现了InitializingBean接口的话,执行afterPropertiesSet方法;
- 第8步:执行自定义的init方法;
- 第9步:执行BeanPostProcessor接口的后置处理方法。
这时,就完成了bean的创建过程。在使用完bean需要销毁时,会先执行DisposableBean接口的destroy方法,然后在执行自定义的destroy方法。这部分也建议阅读源码加深理解。
六:Spring扩展
对spring进行定制化功能扩展时,可以选择如下一些扩展点:
▌1.BeanFactoryPostProcessor
是beanFactory后置处理器,支持在bean factory标准初始化完成后,对bean factory进行一些额外处理。在讲context初始化流程时介绍过,这时所有的bean的描述信息已经加载完毕,但是还没有进行bean初始化。例如前面提到的PropertyPlaceholderConfigurer,就是在这个扩展点上对bean属性中的占位符进行替换。
▌2.BeanDefinitionRegistryPostProcessor
它扩展自BeanFactoryPostProcessor,在执行BeanFactoryPostProcessor的功能前,提供了可以添加bean definition的能力,允许在初始化一般bean前,注册额外的bean。例如可以在这里根据bean的scope创建一个新的代理bean。
▌3.BeanPostProcessor
提供了在bean初始化之前和之后插入自定义逻辑的能力。与BeanFactoryPostProcessor的区别是处理的对象不同,BeanFactoryPostProcessor是对beanfactory进行处理,BeanPostProcessor是对bean进行处理。
注:上面这三个扩展点,可以通过实现Ordered和PriorityOrdered接口来指定执行顺序。实现PriorityOrdered接口的processor会先于实现Ordered接口的执行。
▌4.ApplicationContextAware
可以获得ApplicationContext及其中的bean,当需要在代码中动态获取bean时,可以通过实现这个接口来实现。
▌5.InitializingBean
可以在bean初始化完成,所有属性设置完成后执行特定逻辑,例如对自动装配对属性进行验证等等。
▌6.DisposableBean
用于在bean被销毁前执行特定的逻辑,例如做一些回收工作等。
▌7.ApplicationListener
用来监听spring的标准应用事件或者自定义事件。
七、springboot相关的知识点
▌1.启动流程
主要步骤首先要配置environment,然后准备context上下文,包括执行applicationContext的后置处理、初始化initializer、通知listener处理contextPrepared和contextLoaded事件。最后执行refreshContext,也就是前面介绍过的AbstractApplicationContext类的refresh方法。
▌2.配置文件
然后要知道在Spring Boot中有两种上下文,一种是bootstrap, 另外一种是application。bootstrap是应用程序的父上下文,也就是说bootstrap会先于applicaton加载。bootstrap主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。bootstrap里面的属性会优先加载,默认也不能被本地相同配置覆盖。
▌3.注解
@SpringBootApplication包含了@ComponentScan、@EnableAutoConfiguration、@SpringBootConfiguration三个注解
而@SpringBootConfiguration注解包含了@Configuration注解。也就是springboot的自动配置功能。
@Conditional注解就是控制自动配置的生效条件的注解,例如bean或class存在、不存在时进行配置,当满足条件时进行配置等等。
▌4.特色模块
- starter是springboot提供的无缝集成功能的一种方式,使用某个功能时开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由Spring Boot自动配置进行bean的创建。例如需要使用web功能时,只需要在依赖中引入spring-boot-starter-web即可。
- actuator是用来对应用程序进行监视和管理,通过restful api请求来监管、审计、收集应用的运行情况。
- devtools提供了一系列开发工具的支持,来提高开发效率。例如热部署能力等。
- CLI就是命令行接口,是一个命令行工具,支持使用Groovy脚本,可以快速搭建spring原型项目。
以上为Spring框架需要掌握的内容,前面提到的核心机制、核心流程,建议阅读源码加深理解,下篇文章将重点介绍netty与常用rpc框架的知识,欢迎持续关注
以上内容摘取自《32个Java面试必考点》-新浪微博资深技术专家张雷
必会框架-Spring全家桶,点此了解更多
Spring框架—基础介绍相关推荐
- Spring框架的介绍以及搭建
Spring框架的介绍以及搭建 1.框架和架构 1.1.什么是框架 1.2 架构的发展历程 2.Spring 2.1.Spring框架的优势 3.IOC 3.1.什么是IOC 4.Maven 4.搭建 ...
- 一.Spring框架基础
JAVAEE框架之Spring 一.Spring框架基础 Spring:春天:轻量级的企业级开发框架,核心是IOC(控制反转)和AOP(面向切面编程). 官网:spring.io Spring–> ...
- Spring框架Runtime介绍(导包)
一.Spring框架Runtime介绍,如图 1.1 Test: Spring提供测试功能 1.2 Core Container:Spring核心容器,Spring启动的基本条件, 1.2.1 Bea ...
- mmc驱动框架基础介绍
mmc驱动框架基础介绍 本文主要介绍一下Linux内核的mmc子系统驱动的整体框架. (作者对SDIO设备不熟悉,所以不过多描述:鄙人才疏学浅,有不当之处,还请指教.) 大概包括以下几个部分: mmc ...
- Spring Boot框架基础介绍
Spring Boot 是一款基于 Spring 框架的开源应用程序开发工具,它旨在简化 Spring 应用程序的配置和开发过程.Spring Boot 提供了一种简单的方式来创建可独立运行的.生产级 ...
- Spring 框架简单介绍
考虑到你可能不熟悉 Spring,我这里对它做下简单介绍.我们常说的 Spring 框架,是指 Spring Framework 基础框架.Spring Framework 是整个 Spring 生态 ...
- Spring框架基础概念(面试概念解答)
Spring框架概述 什么是Spring? 三层体系架构 Spring框架的优点 Spring的体系结构 Core Container(核心容器) Data Access/Integration(数据 ...
- Spring框架基础知识
本人博客文章网址:https://www.peretang.com/basic-knowledge-of-spring-framework/ Spring框架简介 Spring , 一个开源的框架 , ...
- Spring 框架基础(04):AOP切面编程概念,几种实现方式演示
本文源码:GitHub·点这里 || GitEE·点这里 一.AOP基础简介 1.切面编程简介 AOP全称:Aspect Oriented Programming,面向切面编程.通过预编译方式和运行期 ...
最新文章
- 一文带你看透 GDB 的 实现原理 -- ptrace真香
- 怎样在bug管理上节省时间
- 使用WCF传输DataTable:DataTable和Xml格式的字符串相互转换(C#)
- 【Java 并发编程】线程池机制 ( 线程池阻塞队列 | 线程池拒绝策略 | 使用 ThreadPoolExecutor 自定义线程池参数 )
- 超四分之一的人工可能被机器取代,AI或成英国脱欧的一大阻碍
- CodeForces - 858D Polycarp's phone book(字典树/map)
- 笔记本电脑电源已接通未充电_dell xps15 电源已接通 未充电 维修方法
- 前端小知识点(10):原型链
- Java接口xss,Java审计之XSS篇
- flink Table API 与SQL入门实战
- 去除桌面图标下的底色[XP系统]
- 深信服智安全 SCSA---1
- java程序员的浪漫代码_java表白代码,能否get到程序员的浪漫?
- vue实现图片切换效果
- 【OpenCV图像处理入门学习教程六】基于Python的网络爬虫与OpenCV扩展库中的人脸识别算法比较
- 官网webp转换工具cwebp简介
- S3C2440 开发板实战(7):字符设备驱动框架+LED驱动
- 15年计算机考研大纲,2015计算机考研大纲
- ffmpeg编解码应用
- Python爬虫:爬取今日头条“街拍”图片(修改版)
热门文章
- 11gOCP 1z0-052 :2013-09-11 MGR_ROLE role........................................................A66
- hahahahahah
- Span元素的 width属性 无效果原因及解决方案
- 用servlet校验密码2
- MySQL8 重置改root密码及开放远程访问
- 开发笔记- iOS监听某些事件的方法简单梳理
- 了解动态链接(六)—— 重定位表
- HTML5地区自转代码
- [转]IP动态切换脚本
- GridView合并列下的行单元格的方法