【总结】Spring Boot、Spring、SpringMVC

image-20210927142537264

一.Spring Boot

加速spring项目构建的工具

核心运行原理

约定优于配置,又称为按约定编程,是一种软件设计范式,旨在减少软件开发人员需要做决定的数量,执行起来简单而又不失灵活。Spring Boot的核心设计完美遵从了此范式。
Spring Boot最核心的功能就是自动配置,该功能的实现也是基于“约定优于配置"的原则。那么SpringBoot是如何约定,又是如何实现自动配置功能的呢?
使用Spring Boot时,我们只需引入对应的Starters,Spring Boot启动时便会自动加载相关依赖,配置相应的初始化参数,以最快捷、简单的形式对第三方软件进行集成,这便是Spring Boot的自动配置功能。

image-20210927142946651

  1. @EnableAutoConfiguration: 该注解由组合注解@SpringBootApplication引入,完成自动配置开启.扫描各个jar包下的spring.factories文件,并加载文件中注册的AutoConfiguration类等。
  2. spring.factories: 配置文件,位于jar包的META-INF目录下,按照指定各式注册了AutoConfiguration类。spring. factories也可以包含其他类型待注册的类。该配置文件不仅存在于Spring Boot项目中,也可以存在于自定义的自动配置(或Starter) 项目中。
  3. AutoConfiguration类: 自动配置类,代表了Spring Boot中-类以*AutoConfiguration命 名的自动配置类。
    其中定义了三方组件集成Spring所需初始化的Bean和条件。
  4. @Conditional: 条件注解及其衍生注解,在AutoConfiguration类 上使用,当满足该条件注解时才会实例
    化AutoConfiguration类。
  5. Starters: 三方组件的依赖及配置,Spring Boot已经预置的组件。Spring Boot默认的Starters项目往往只
    包含了一-个pom依赖的项目。如果是自定义的starter,该项目还需包含spring factories文件、AutoConfiguration类和其他配置类。

@EnableAutoConfiguration

@EnableAutoConfiguration的主 要功能是启动Spring应用程序上下文时进行自动配置,它会尝试猜测并配置项目可能需要的Bean。自动配置通常是基于项目classpath中引入的类和已定义的Bean来实现的。在此过程中,被自动配置的组件来自项目自身和项目依赖的jar包中。

举例:若将tomcat- embedded.jar添加到classpath下,则@EnableAutoConfiguration会认为你准 备使用TomcatServletWebServerFactory类,帮你初始化相关配置。同时,若自定义了基于ServletWebServerFactory的Bean,则@EnableAutoConfiguration将不会 进行TomcatServletWebServerFactory类的初始化。这一系列的操作判断都由Spring Boot来完成。

image-20210927144053350

AutoConfigurationImportSelector

image-20210927144316810

一层层跳找核心点,去找配置文件,加载自动配置类

image-20210927144541173

image-20210927144625671

image-20210927144705415

找到要加载的配置文件

image-20210927144810419

image-20210927145055782

二. Spring

2.1 loC

什么是"控制反转”?
早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他得出的结论是:依赖对象的获得被反转了(需要一个perpson对象,通常情况下是new,但是控制翻转下,不new,把创建对象的权力交给别人,别人给你一个对象,自己不用去创建对象了)。基于这个结论,他为控制反转创造了一个更好的名字:依赖注入。许多非凡的应用(比HelloWorld更加优美、更加复杂)都是由两个或多个类通过彼此的合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么如你所见,这将导致代码高度耦合并且难以测试。

user和其他的没有瓜葛,可以去new

编程中有很多对象是单例的,频繁的在多种语境下复用的,又和别的对象有复杂的关系,这样的对象交给别人去创建,创建的同时还能维护对象之间的关系,当对象之间的关系发生变化时,因为它是基于配置来依赖的,很容易去改动,即依赖注入。

例如service,mapper相互调用又复杂的关系,交给spring管理

为什么需要控制反转呢?

因为程序中有很多的对象要公用的、频繁、有复杂的关系,自己去维护容易出现问题。有了依赖注入,有了更科学的管理。

这些依赖关系可以通过把对象的依赖注入交给框架或者IoC容器来完成。

什么是‘"IoC容器” ?
控制反转的实现有很多种方式。在Spring中, loC容器是实现这个模式的载体,它可以在对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入对方法调用的依赖。这种依赖注入是可以递归的,对象被逐层注入。它把对象的依赖关系有序地建立起来,简化了对象依赖关系的管理,在很大程度上简化了面向对象系统的复杂性。

通过使用IoC容器,对象依赖关系的管理被反转了,转到loC容器中来了,对象之间的相互依赖关系由loC容器进行管理,并由loc容器完成对象的注入。

image-20210927151507308

IoC容器的初始化

image-20210927151800175

装载bean过程:

ResourceLoader获取你需要的bean加载进内存,读到信息后封装到BeanDefinition,向容器注册bean

IoC容器的依赖注入

image-20210927154838156

image-20210927155038919

image-20210927155547010

利用FactoryBean装载一个特殊的对象,在写代码的时候这个类是别人设计的,没有加注解,还想让它加载到容器里:

image-20210927160316844

AOP是通过动态代理机制实现的,动态代理底层现生成一个对象。

FactoryBean的用意是为了装载那些创建比较复杂的目标bean

2.2AOP

image-20210927161339464

记日志,各处调用的都有,如果记日志的方法变了,那改动这些代码,工程量巨大。

单独把这些逻辑抽取出来,单独去实现。

方面:分散代码中的业务逻辑的关注点,将关注点抽取出来封装一下

把之前在分散地方的零碎的代码挪到了统一的地方去实现,就叫方面编程

image-20210927162307960

术语理解:

1、目标对象:那些有共同需求的分散的对象,比如程序里,每一个service都要记日志,那每一个service就是目标对象

2、连接点:要拦截对象的哪些方法(代表一个方法)

3、切点:抽取出来的逻辑,可以将它附加在不同类上。通过切点去定义这个逻辑应该加在那些类的那个方法之上(切点使得逻辑和连接点产生关联)

4、通知:我在连接点的那个地方调(开始,结束,抛异常。。。)

切点是为了定义方法,通知是为了定义那个方法中的位置

5、织入:定义一个统一的组件,怎么就能在散落的地方调用呢?通过织入。

6、切面:关注点,就是解决问题的类(不在分散的地方编程了,在同一的地方去解决,这个类就是切面)

image-20210927163343857

例如程序中的每个service都是Target,在service中以find方法开头的为连接点,(在100个方法里面有1000个以find方法开头的,这1000个连接点上都要记日志,分四步解决)

1、创建一个类(方面),同意解决问题 @Aspect注解修饰的类

2、定义一个方法,在方法上使用PonitCut修饰,规定哪些类的哪些方法需要附加这个逻辑

3、在方法中的那个位置去解决问题呢,在写方法声明before。。。。

以上做完后,这个类自动生效。为什么?在特定的时机,这个逻辑会被织入到方法对应的位置去

4、织入(运行时织入,生成代理对象)

JDK的动态代理

image-20210927164238552

利用类来实现Proxy

image-20210927164840583

代理对象也要放到工厂里面去 FeactoryBean

三. Spring MVC

3.1主要流程

image-20210927165318744

DispatcherServlet:分发请求。根据请求的路径url,分发给controller的方法。

1、请求来了先去遍历HandlerMapping(url和controller方法映射)(里面封装了controller方法,拦截器),对信息封装(封装了那个controller ,拦截器)

2、知道了要去调那个controller,就去调用HandlerAdapter(Controller),在controller方法的前后可能会有拦截器拦截,所以先调拦截器的preHandle(),controller调用之后,会返回ModelAndView(数和模板路径),

3、拿到了ModelAndView,知道了视图在哪里,数据是什么,调ViewReslover,将数据和模板给他,让他解析,将数据装到模板里面去。由View具体给客户端做响应

4、调用拦截器的方法

第三步没有用到模板引起就用不到

核心源码:

image-20210927170219990

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值