Spring是Java应用开发一站式的解决方案,贯穿表现层、业务层、持久层,而且还可以和其他的框架无缝整合。

  • 控制反转,根据配置和反射机制组装对象之间的依赖关系
  • 面向切面编程,将业务逻辑和系统服务分开
  • 轻量级,Srping的大小与和运行程序开销方面都是轻量级的,而且不会侵入系统
  • 应用集成框架

    • 能非常简单的帮我们管理数据库事务
    • Web框架无缝集成,而且自己也提供了一套Spring MVC框架,来方便web层搭建。
    • Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)

      Spring组成

      1. ![](https://cdn.nlark.com/yuque/0/2019/gif/217875/1572593184179-fe497eea-7451-4c74-882c-a7e175f96f0f.gif#align=left&display=inline&height=288&margin=%5Bobject%20Object%5D&originHeight=288&originWidth=555&size=0&status=done&style=none&width=555)

      Spring Core

      核心容器提供Spring框架的基本功能, 以bean的方式组织和管理Java应用中的各个组件及其关系。Spring使用BeanFactory利用Java语言的反射功能来实例化Bean并建立Bean之间的依赖关系,它是工厂模式的实现。Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。

      Bean

      在传统的Java应用中,bean的生命周期很简单,使用Java关键字new进行bean实例化,一旦该bean不再被使用,则由Java自动进行垃圾回收。但是在Spring中,对bean实例的控制权由由spring容器管理,来实现控制反转。我们在获取bean对象是一般通过name或者type,其中type为bean对象的类,name为bean的唯一id,可以手动指定,如果未指定规则如下:
  • 如果不指定bean名称,bean名称的默认规则是类名的首字母小写

  • 如果类名前两个或以上个字母都是大写,那么bean名称与类名一样

    作用域

    Spring通过作用域的方式来规定如何管理bean对象,Spring一共定义了6种作用域,其中4种只在web模式下有效,Spring还支持自定义作用域。
Scope 描述
singleton (默认的)在每个Spring IoC容器中,一个bean定义对应只会有唯一的一个bean实例
prototype 每次获取bean对象时,spring容器新建一个bean实例
request(Web) 一个bean定义对应于单个HTTP 请求的生命周期。也就是说,每个HTTP 请求都有一个bean实例,且该实例仅在这个HTTP。该作用域仅适用于WebApplicationContext环境。
session(Web) 一个bean 定义对应于单个HTTP Session 的生命周期,也就是说,每个HTTP Session 都有一个bean实例,且该实例仅在这个HTTP Session 的生命周期里有效。该作用域仅适用于WebApplicationContext环境。
application(Web) 一个bean 定义对应于单个ServletContext 的生命周期。该作用域仅适用于WebApplicationContext环境。
websocket(Web) 一个bean 定义对应于单个websocket 的生命周期。该作用域仅适用于WebApplicationContext环境。

创建过程

image.png

  1. 获取Bean解配置解析成BeanDefinition存储在容器中,查看是够有缓存的单例Bean,否则根据beanName和beanDefiniation创建Bean
  2. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
  3. Instantiation() 调用Bean的构造函数
  4. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
  5. popolateBean() 构建bean中的关系
  6. BeanPostProcessor.postProcessBeforeInitiazation()
    • BeanNameAware 如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String)方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值
    • BeanClassLoaderAware
    • BeanFactoryAware 如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory,setBeanFactory(BeanFactory)传递的是 Spring 工厂自身
    • EnvironmentAware
    • EmbeddedValueResolverAware
    • ApplicationContextAware 如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用
      setApplicationContext(ApplicationContext)方法,传入 Spring 上下文
    • postProcessBeforeInitialization 也就是@PostConstruct接口的实现
    • @Schedule
  7. initializeBean,如果 Bean 在 Spring 配置文件中配置了”init-method”属性会自动调用其配置的初始化方法,配置的三种方法
  8. BeanPostProcessor.postProcessAfterInitiazation()如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
    postProcessAfterInitialization(Object obj, String s)方法

    清理过程

  9. 当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用那个其实现的 destroy()方法

  10. 如果这个 Bean 的 Spring 配置中配置了”destroy-method”属性,会自动调用其配置的销毁方法。

钩子函数执行顺序

  1. 实例化函数
  2. @PostConstruct注解执行
  3. InitializingBean.afterPropertiesSet开始执行
  4. ApplicationListener.onApplicationEvent开始执行
  5. @Predestory开始执行
  6. DisposableBean.destory开始执行

TODO

Spring Context

Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,如JNDI、EJB、电子邮件、国际化、校验和调度功能。

Spring AOP

通过配置管理特性,Spring AOP模块直接将面向切面编程功能集成到了Spring框架中,并通过预编译方式和运行期动态代理实现程序功能实现切面编程。AOP可以实现对一些通用任务的管理,比如:

  • 事务的处理
  • 资源池,如数据库连接池的管理
  • 系统统一的认证、权限管理等
  • 应用系统的异常捕捉及处理

    核心概念

    在什么时候?在哪里?执行哪些操作?如何实现?这些问题就是切面编程的要点,实际上切面编程有相应的术语对应。

  • 切面(Aspect),切面是通知和切点的结合。通知和切点共同定义了切面的全部内容——它是什么,在何时和何处完成其功能。比如事务管理是一个切面,权限管理也是一个切面。

  • 通知(Advice)通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题。
    • 前置通知(Before):在目标方法被调用之前调用通知功能
    • 后置通知(After):在目标方法完成之后调用通知,不关心方法的输出是什么。是“返回通知”和“异常通知”的并集。
    • 返回通知(After-returning):在目标方法成功执行之后调用通知
    • 异常通知(After-throwing):在目标方法抛出异常后调用通知
    • 环绕通知(Around)通知包裹了被通知的方法,可同时定义前置通知和后置通知。
  • 切点(Pointcut)切点定义了在何处工作,也就是真正被切入的地方,也就是在哪个方法应用通知。切点的定义会匹配通知所有要织入的一个或多个连接点。我们通常使用明确的类和方法名称,或是利用正则表达式定义所匹配的类和方法名称来指定这些切点。
  • 连接点(Join point)连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时,抛出异常时,甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。**
  • 织入(Weaving)织入是把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在目标对象的生命周期里有多个点可以织入。
    • 编译器:切面在目标类编译时被织入。这种方式需要特殊的编译器。
    • 类加载期:切面在目标类被引入应用之前增强该目标类的字节码。
    • 运行期:切面在应用运行的某个时刻被织入。

      实现

      Spring 提供了两种方式来生成代理对象: JDKProxy 和 Cglib ,具体使用哪种方式 生成由AopProxyFactory 根据 AdvisedSupport 对象的配置来决定。 默认的策略是如果目标类是接口,则使用 JDK 动态代理技术,否则使用 Cglib 来生成代理。

Spring DAO

Spring提供操作数据库的模块,JDBC、DAO的抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理,和不同数据库供应商所抛出的错误信息。同时对数据库事务和分布式事务进行了包装。

事务传播机制

  • REQUIRED,表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。
  • SUPPORTS,表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行
  • MANDATORY, 表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常
  • NESTED, 表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚
  • NEVER, 表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常
  • REQUIRES_NEW,表示当前方法必须运行在它自己的事务中。
  • NOT_SUPPORTED,表示该方法不应该在一个事务中运行。

@Transtractional

Spring ORM

Spring框架插入了若干个ORM框架,从而提供了ORM对象的关系工具,其中包括了Hibernate、JDO和 MyBatis SQL Map等,所有这些都遵从Spring的通用事物和DAO异常层次结构。

Spring Web

Web上下文模块建立在应用程序上下文模块之上,为基于web的应用程序提供了上下文。所以Spring框架支持与Struts集成,web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

Spring Web MVC

Spring MVC框架是一个全功能的构建Web应用程序的MVC实现。是围绕一个 DispatcherServlet 来设计的,这个 Servlet会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等,甚至还能支持文件上传

  1. Http 请求到 DispatcherServlet
  2. HandlerMapping 寻找处理器,由 DispatcherServlet 控制器查询一个或多个 HandlerMapping,找到处理请求的
    Controller。
  3. 调用处理器 Controller,DispatcherServlet 将请求提交到 Controller
  4. Controller 调用业务逻辑处理后,返回 ModelAndView
  5. DispatcherServlet 查询 ModelAndView ,DispatcherServlet 查询一个或多个 ViewResoler 视图解析器,
    找到 ModelAndView 指定的视图。
  6. ModelAndView 反馈浏览器 HTTP

Spring功能

Spring Security

提供鉴权,防止重放攻击的功能

定时任务

https://blog.csdn.net/j080624/article/details/80959271

事件机制

ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。
事件机制默认是同步的,但是可以再spring中配置成异步的。

名词解释

  • 非侵入式设计,从框架的角度可以理解为:无需继承框架提供的任何类这样我们在更换框架时,之前写过的代码几乎可以继续使用。
  • 轻量级和重量级,轻量级是相对于重量级而言的,轻量级一般就是非入侵性的、所依赖的东西非常少、资源占用非常少、部署简单等等,其实就是比较容易使用,而重量级正好相反
  • 框架,是能完成一定功能的半成品。框架能够帮助我们完成的是:项目的整体框架、一些基础功能、规定了类和对象如何创建,如何协作等,当我们开发一个项目时,框架帮助我们完成了一部分功能,我们自己再完成一部分,那这个项目就完成了。
  • POJO( Plain Old Java Objects), 即POJO是一个简单的普通的Java对象,它不包含业务逻辑或持久逻辑等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不继承或不实现任何其它Java框架的类或接口。
  • DAO(Data Access Object) 映射于数据库对象,主要对数据的操作,增加、修改、删除等原子性操作。
  • JavaBean 一般指符合某种设计规范的类(类似的概念还有POJO),该类必须是具体类的也必须是公共类,而且要具有无参数的构造器,实现serializable接口,JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性,java内部还提供了java.beans库来操作Bean对象
  • AOP(Aspect Oriented Programming)面向切面编程,OOP(面向对象编程)通过的是继承、封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。OOP从纵向上区分出一个个的类来,而AOP则从横向上向对象中加入特定的代码。AOP与装饰器模式非常相似,都是在尽量降低逻辑耦合度不侵入原逻的基础上,来实现额外的功能,切面常用来实现下面这些功能。
  • IOC表示Inversion of control,即“控制反转”。传统模式下,对象的创建与管理都是由开发人员编写代码直接完成的,而使用Spring后,将创建与管理交给了框架,则称之为控制反转。其中,比较重要的环节是为对象的某些属性进行赋值,称之为DI,即Dependency Injection,表示“依赖注入”,通俗的来说,是为其属性赋值,也称之为“为其属性注入值”。Spring通过DI实现了IoC,即DI是实现手段,而IoC是需要实现的目标

参考文档
Spring中文手册:https://www.springcloud.cc/spring-boot.html#boot-features-activemq
https://spring.io/guides
spring demo:demo.zip
spring启动细节:https://blog.csdn.net/wanderlustlee/article/details/80350736
https://coderbee.net/index.php/uncategorized/20140105/697#%E5%B9%B6%E5%8F%91
https://www.jianshu.com/p/603d125f21b3
Spring快速入门:https://www.cnblogs.com/wmyskxz/p/8820371.html
自动装配beans文件:https://blog.csdn.net/qwe5810658/article/details/74343228
spring中的线程安全:https://www.cnblogs.com/atwanli/articles/4740184.html
Spring基础:https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html
spring-bean生命周期:https://www.jianshu.com/p/1dec08d290c1
https://www.jianshu.com/p/8e2d400492c7
https://www.jianshu.com/p/6d7f01bc9def
https://www.cnblogs.com/xiaoxing/p/10270285.html
https://www.cnblogs.com/lay2017/p/11735802.html