spring大全

原文

https://mp.weixin.qq.com/s/EriyO-DVNDw7oMZdHphjZg

有人说,“Java程序员都是Spring程序员”,老三不太赞成这个观点,但是这也可以看出Spring在Java世界里举足轻重的作用。
在这里插入图片描述

一句话概括:Spring 是一个轻量级、非入侵式的控制反转 (IoC) 和面向切面 (AOP) 的框架

2003年,一个音乐家Rod Johnson决定发展一个轻量级的Java开发框架,Spring作为Java战场的龙骑兵渐渐崛起,并淘汰了EJB这个传统的重装骑兵。

spring核心七大模块

在这里插入图片描述
Spring 框架是分模块存在,除了最核心的Spring Core Container是必要模块之外,其他模块都是可选大约有 20 多个模块

Spring Core:Spring 核心,它是框架最基础的部分,提供 IOC 和依赖注入 DI 特性。
Spring Context:Spring 上下文容器,它是 BeanFactory 功能加强的一个子接口。
Spring Web:它提供 Web 应用开发的支持。
Spring MVC:它针对 Web 应用中 MVC 思想的实现。
Spring DAO:提供对 JDBC 抽象层,简化了 JDBC 编码,同时,编码更具有健壮性。
Spring ORM:它支持用于流行的 ORM 框架的整合,比如:Spring + Hibernate、Spring + iBatis、Spring + JDO 的整合等。
Spring AOP:即面向切面编程,它提供了与 AOP 联盟兼容的编程实现。

spring特性

在这里插入图片描述

  • IOC 和 DI 的支持

Spring 的核心就是一个大的工厂容器,可以维护所有对象的创建和依赖关系,Spring 工厂用于生成 Bean,并且管理 Bean 的生命周期,实现高内聚低耦合的设计理念。

  • AOP 编程的支持

Spring 提供了面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等切面功能。

  • 声明式事务的支持

支持通过配置就来完成对事务的管理,而不需要通过硬编码的方式,以前重复的一些事务提交、回滚的JDBC代码,都可以不用自己写了。

  • 快捷测试的支持

Spring 对 Junit 提供支持,可以通过注解快捷地测试 Spring 程序。

  • 快速集成功能

方便集成各种优秀框架,Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持

  • 复杂API模板封装

Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了模板化的封装,这些封装 API 的提供使得应用难度大大降低。

spring常用注解

在这里插入图片描述

Web相关注解:

@Controller:组合注解(组合了@Component注解),应用在MVC层(控制层)。
@RestController:该注解为一个组合注解,相当于@Controller和@ResponseBody的组合,注解在类上,意味着,该Controller的所有方法都默认加上了@ResponseBody。
@RequestMapping:用于映射Web请求,包括访问路径和参数。如果是Restful风格接口,还可以根据请求类型使用不同的注解:
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@ResponseBody:支持将返回值放在response内,而不是一个页面,通常用户返回json数据。
@RequestBody:允许request的参数在request体中,而不是在直接连接在地址后面。
@PathVariable:用于接收路径参数,比如@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法。
@RestController:该注解为一个组合注解,相当于@Controller和@ResponseBody的组合,注解在类上,意味着,该Controller的所有方法都默认加上了@ResponseBody。

容器相关注解:

@Component:表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component还是一个元注解。
@Service:组合注解(组合了@Component注解),应用在service层(业务逻辑层)。
@Repository:组合注解(组合了@Component注解),应用在dao层(数据访问层)。
@Autowired:Spring提供的工具(由Spring的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入)。
@Qualifier:该注解通常跟 @Autowired 一起使用,当想对注入的过程做更多的控制,@Qualifier 可帮助配置,比如两个以上相同类型的 Bean 时 Spring 无法抉择,用到此注解
@Configuration:声明当前类是一个配置类(相当于一个Spring配置的xml文件)
@Value:可用在字段,构造器参数跟方法参数,指定一个默认值,支持 #{} 跟 ${} 两个方式。一般将 SpringbBoot 中的 application.properties 配置的属性值赋值给变量。
@Bean:注解在方法上,声明当前方法的返回值为一个Bean。返回的Bean对应的类中可以定义init()方法和destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行init,在销毁之前执行destroy。
@Scope:定义我们采用什么模式去创建Bean(方法上,得有@Bean) 其设置类型包括:Singleton 、Prototype、Request 、 Session、GlobalSession。

AOP相关注解:

@Aspect:声明一个切面(类上) 使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
@After :在方法执行之后执行(方法上)。
@Before:在方法执行之前执行(方法上)。
@Around:在方法执行之前与之后执行(方法上)。
@PointCut:声明切点 在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持(类上)。
事务:

@Transactional:在要开启事务的方法上使用@Transactional注解,即可声明式开启事务。

spring用到的设计模式

在这里插入图片描述
工厂模式 : Spring 容器本质是一个大工厂,使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
代理模式 : Spring AOP 功能功能就是通过代理模式来实现的,分为动态代理和静态代理。
单例模式 : Spring 中的 Bean 默认都是单例的,这样有利于容器对Bean的管理。
模板模式 : Spring 中 JdbcTemplate、RestTemplate 等以 Template结尾的对数据库、网络等等进行操作的模板类,就使用到了模板模式。
观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
适配器模式 :Spring AOP 的增强或通知 (Advice) 使用到了适配器模式、Spring MVC 中也是用到了适配器模式适配 Controller。
策略模式:Spring中有一个Resource接口,它的不同实现类,会根据不同的策略去访问资源。

在这里插入图片描述

在这里插入图片描述

BeanFactory(Bean工厂)是Spring框架的基础设施,面向Spring本身。
ApplicantContext(应用上下文)建立在BeanFactoty基础上,面向使用Spring框架的开发者

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Bean生命周期

在这里插入图片描述
在这里插入图片描述

依赖注入IOC

Spring支持构造方法注入、属性注入、工厂方法注入,其中工厂方法注入,又可以分为静态工厂方法注入和非静态工厂方法注入
在这里插入图片描述

Bean定义和依赖定义

在这里插入图片描述

直接编码方式:我们一般接触不到直接编码的方式,但其实其它的方式最终都要通过直接编码来实现。
配置文件方式:通过xml、propreties类型的配置文件,配置相应的依赖关系,Spring读取配置文件,完成依赖关系的注入。
注解方式:注解方式应该是我们用的最多的一种方式了,在相应的地方使用注解修饰,Spring会扫描注解,完成依赖关系的注入。

自动装配

Spring IOC容器知道所有Bean的配置信息,此外,通过Java反射机制还可以获知实现类的结构信息,如构造方法的结构、属性等信息。掌握所有Bean的这些信息后,Spring IOC容器就可以按照某种规则对容器中的Bean进行自动装配,而无须通过显式的方式进行依赖配置。

Spring提供的这种方式,可以按照某些规则进行Bean的自动装配,元素提供了一个指定自动装配类型的属性:autowire=“<自动装配类型>”

Spring提供了几种自动装配类型

在这里插入图片描述
byName:根据名称进行自动匹配,假设Boss又一个名为car的属性,如果容器中刚好有一个名为car的bean,Spring就会自动将其装配给Boss的car属性
byType:根据类型进行自动匹配,假设Boss有一个Car类型的属性,如果容器中刚好有一个Car类型的Bean,Spring就会自动将其装配给Boss这个属性
constructor:与 byType类似, 只不过它是针对构造函数注入而言的。如果Boss有一个构造函数,构造函数包含一个Car类型的入参,如果容器中有一个Car类型的Bean,则Spring将自动把这个Bean作为Boss构造函数的入参;如果容器中没有找到和构造函数入参匹配类型的Bean,则Spring将抛出异常。
autodetect:根据Bean的自省机制决定采用byType还是constructor进行自动装配,如果Bean提供了默认的构造函数,则采用byType,否则采用constructor。

Spring的Bean主要支持五种作用域:

在这里插入图片描述
singleton : 在Spring容器仅存在一个Bean实例,Bean以单实例的方式存在,是Bean默认的作用域。
prototype : 每次从容器重调用Bean时,都会返回一个新的实例。
以下三个作用域于只在Web应用中适用:

request : 每一次HTTP请求都会产生一个新的Bean,该Bean仅在当前HTTP Request内有效。
session : 同一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean。
globalSession:同一个全局Session共享一个Bean,只用于基于Protlet的Web应用,Spring5中已经不存在了。

Spring 中的单例 Bean 会存在线程安全问题

首先结论在这:Spring中的单例Bean不是线程安全的。

因为单例Bean,是全局只有一个Bean,所有线程共享。如果说单例Bean,是一个无状态的,也就是线程中的操作不会对Bean中的成员变量执行查询以外的操作,那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。

假如这个Bean是有状态的,也就是会对Bean中的成员变量进行写操作,那么可能就存在线程安全的问题。
在这里插入图片描述

单例Bean线程安全问题怎么解决呢?

常见的有这么些解决办法:

1.将Bean定义为多例

这样每一个线程请求过来都会创建一个新的Bean,但是这样容器就不好管理Bean,不能这么办。

2.在Bean对象中尽量避免定义可变的成员变量

削足适履了属于是,也不能这么干。

3.将Bean中的成员变量保存在ThreadLocal中⭐

我们知道ThredLoca能保证多线程下变量的隔离,可以在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal里,这是推荐的一种方式。

AOP:面向切面编程

。简单说,就是把一些业务逻辑中的相同的代码抽取到一个独立的模块中,让业务逻辑更加清爽。

在这里插入图片描述
在这里插入图片描述

JDK 动态代理和 CGLIB 代理

Spring的AOP是通过动态代理来实现的,动态代理主要有两种方式JDK动态代理Cglib动态代理,这两种动态代理的使用和原理有些不同
在这里插入图片描述

JDK 动态代理

Interface:对于 JDK 动态代理,目标类需要实现一个Interface。
InvocationHandler:InvocationHandler是一个接口,可以通过实现这个接口,定义横切逻辑,再通过反射机制(invoke)调用目标类的代码,在次过程,可能包装逻辑,对目标方法进行前置后置处理。
Proxy :Proxy利用InvocationHandler动态创建一个符合目标类实现的接口的实例,生成目标类的代理对象。

CgLib 动态代理

使用JDK创建代理有一大限制,它只能为接口创建代理实例,而CgLib 动态代理就没有这个限制。
CgLib 动态代理是使用字节码处理框架 ASM,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。
CgLib 创建的动态代理对象性能比 JDK 创建的动态代理对象的性能高不少,但是 CGLib 在创建代理对象时所花费的时间却比 JDK 多得多,所以对于单例的对象,因为无需频繁创建对象,用 CGLib 合适,反之,使用 JDK 方式要更为合适一些。同时,由于 CGLib 由于是采用动态创建子类的方法,对于 final 方法,无法进行代理。
在这里插入图片描述

AOP 一般有 5 种环绕方式:

前置通知 (@Before)
返回通知 (@AfterReturning)
异常通知 (@AfterThrowing)
后置通知 (@After)
环绕通知 (@Around)
在这里插入图片描述

Spring AOP 和 AspectJ AOP 区别

在这里插入图片描述

spring 事务

在这里插入图片描述
编程式事务
编程式事务管理使用 TransactionTemplate,需要显式执行事务。

声明式事务

声明式事务管理建立在 AOP 之上的。其本质是通过 AOP 功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前启动一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务

优点是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过 @Transactional 注解的方式,便可以将事务规则应用到业务逻辑中,减少业务代码的污染。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

声明式事务在哪些情况下会失效

在这里插入图片描述

异常

在这里插入图片描述

Spring MVC 的核心组件

DispatcherServlet:前置控制器,是整个流程控制的核心,控制其他组件的执行,进行统一调度,降低组件之间的耦合性,相当于总指挥。
Handler:处理器,完成具体的业务逻辑,相当于 Servlet 或 Action。
HandlerMapping:DispatcherServlet 接收到请求之后,通过 HandlerMapping 将不同的请求映射到不同的 Handler。
HandlerInterceptor:处理器拦截器,是一个接口,如果需要完成一些拦截处理,可以实现该接口。
HandlerExecutionChain:处理器执行链,包括两部分内容:Handler 和 HandlerInterceptor(系统会有一个默认的 HandlerInterceptor,如果需要额外设置拦截,可以添加拦截器)。
HandlerAdapter:处理器适配器,Handler 执行业务方法之前,需要进行一系列的操作,包括表单数据的验证、数据类型的转换、将表单数据封装到 JavaBean 等,这些操作都是由 HandlerApater 来完成,开发者只需将注意力集中业务逻辑的处理上,DispatcherServlet 通过 HandlerAdapter 执行不同的 Handler。
ModelAndView:装载了模型数据和视图信息,作为 Handler 的处理结果,返回给 DispatcherServlet。
ViewResolver:视图解析器,DispatcheServlet 通过它将逻辑视图解析为物理视图,最终将渲染结果响应给客户端。

Spring MVC 的工作流程

在这里插入图片描述

  1. 客户端向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。

  2. DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)

  3. DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller

  4. HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet

  5. DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,然后返回真正的视图。

  6. DispatcherServlet将模型数据填充到视图中

  7. DispatcherServlet将结果响应给客户端

Spring MVC 虽然整体流程复杂,但是实际开发中很简单,大部分的组件不需要开发人员创建和管理,只需要通过配置文件的方式完成配置即可,真正需要开发人员进行处理的只有 Handler(Controller) 、View 、Model

当然我们现在大部分的开发都是前后端分离,Restful风格接口,后端只需要返回Json数据就行了

在这里插入图片描述
客户端向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet

DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理

DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller

Controller被封装成了ServletInvocableHandlerMethod,HandlerAdapter处理器适配器去执行invokeAndHandle方法,完成对Controller的请求处理

HandlerAdapter执行完对Controller的请求,会调用HandlerMethodReturnValueHandler去处理返回值,主要的过程:

5.1. 调用RequestResponseBodyMethodProcessor,创建ServletServerHttpResponse(Spring对原生ServerHttpResponse的封装)实例

5.2.使用HttpMessageConverter的write方法,将返回值写入ServletServerHttpResponse的OutputStream输出流中

5.3.在写入的过程中,会使用JsonGenerator(默认使用Jackson框架)对返回值进行Json序列化

执行完请求后,返回的ModealAndView为null,ServletServerHttpResponse里也已经写入了响应,所以不用关心View的处理


springBoot

Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具
在这里插入图片描述
Spring Boot 以约定大于配置核心思想开展工作,相比Spring具有如下优势:

Spring Boot 可以快速创建独立的Spring应用程序。
Spring Boot 内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了。
Spring Boot 无需再像Spring一样使用一堆繁琐的xml文件配置。
Spring Boot 可以自动配置(核心)Spring。SpringBoot将原有的XML配置改为Java配置,将bean注入改为使用注解注入的方式(@Autowire),并将多个xml、properties配置浓缩在一个appliaction.yml配置文件中。
Spring Boot 提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能。
Spring Boot 可以快速整合常用依赖(开发库,例如spring-webmvc、jackson-json、validation-api和tomcat等),提供的POM可以简化Maven的配置。当我们引入核心依赖时,SpringBoot会自引入其他依赖。

springBoot自动配置原理

在这里插入图片描述

SpringBoot 启动大致流程

在这里插入图片描述

springCloud

SpringCloud是Spring官方推出的微服务治理框架

在这里插入图片描述

什么是微服务

2014 年 Martin Fowler 提出的一种新的架构形式。微服务架构是一种架构模式,提倡将单一应用程序划分成一组小的服务,服务之间相互协调,互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务之间采用轻量级的通信机制(如HTTP或Dubbo)互相协作,每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境中,另外,应尽量避免统一的,集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具(如Maven)对其进行构建。
微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事情,从技术角度看就是一种小而独立的处理过程,类似进程的概念,能够自行单独启动或销毁,拥有自己独立的数据库。

微服务架构主要要解决哪些问题

服务很多,客户端怎么访问,如何提供对外网关?
这么多服务,服务之间如何通信? HTTP还是RPC?
这么多服务,如何治理? 服务的注册和发现。
服务挂了怎么办?熔断机制。

有哪些主流微服务框架?

Spring Cloud Netflix
Spring Cloud Alibaba
SpringBoot + Dubbo + ZooKeeper

SpringCloud有哪些核心组件

在这里插入图片描述

参考

[1]. 《Spring揭秘》

[2]. 面试官:关于Spring就问这13个:https://mp.weixin.qq.com/s/-gLXHd_mylv_86sTMOgCBg

[3]. 15个经典的Spring面试常见问题 :https://mp.weixin.qq.com/s/OMlwHHnGcN7iZ8lerUvW7w

[4].面试还不知道BeanFactory和ApplicationContext的区别?:https://juejin.cn/post/6844903877574131726

[5]. Java面试中常问的Spring方面问题(涵盖七大方向共55道题,含答案:https://juejin.cn/post/6844903654659473416#heading-8

[6] .Spring Bean 生命周期 (实例结合源码彻底讲透:https://segmentfault.com/a/1190000020747302

[7]. @Autowired注解的实现原理 :https://juejin.cn/post/6844903957135884295

[8].万字长文,带你从源码认识Spring事务原理,让Spring事务不再是面试噩梦https://segmentfault.com/a/1190000022754620

[9].【技术干货】Spring事务原理一探https://zhuanlan.zhihu.com/p/54067384

[10]. Spring的声明式事务@Transactional注解的6种失效场景:https://blog.csdn.net/j1231230/article/details/105534599

[11].Spring官网

[12].Spring使用了哪些设计模式?:https://zhuanlan.zhihu.com/p/336671458

[13].《精通Spring4.X企业应用开发实战》

[14].Spring 中的bean 是线程安全的吗?:https://www.cnblogs.com/myseries/p/11729800.html

原文

https://mp.weixin.qq.com/s/EriyO-DVNDw7oMZdHphjZg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值