什么是 Spring Boot?

如果必须启动一个新的 Spring 项目,我们必须添加构建路径或 maven 依赖项,配置 application server,添加 Spring 配置。因此,启动一个新的 Spring 项目需要大量的工作,因为我们目前必须从头开始做所有事情。 Spring Boot 是这个问题的解决方案。Spring boot 构建在现有 Spring 框架之上。使用 Spring boot,可以避免以前必须执行的所有样板代码和配置。

Spring Boot 的优点是什么?

编码:减少开发、测试的时间和工作量。

配置:使用 JavaConfig 有助于避免使用 XML。没有 web.xml 文件,只需添加带 @ configuration 注释的类。

避免大量 maven 导入和各种版本冲突。

部署:不需要单独的 Web 服务器。这意味着您不再需要启动 Tomcat 或其他任何东西。

Spring Boot 启动流程⭐

首先 prepareEnvironment 配置环境,然后准备 Context 上下文,ApplicationContext 的后置处理器,初始化 lnitializers,通知处理上下文准备和加载时间,然后开始refresh。

prepareEnvironment

createApplicationContext
postProcessApplicationContext
applylnitializers
listeners.contextPrepared
listeners.contextLoaded
refreshContext

Spring Boot提供了两种常用的配置文件:

  • properties文件
  • yml文件

Spring Boot 的核心注解是哪个?⭐

启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:

@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。

@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

@ComponentScan:Spring组件扫描。

Spring Boot 自动配置原理是什么⭐

@EnableAutoConfiguration这个注解开启自动配置,它的作用:

  • 利用EnableAutoConfigurationImportSelector给容器中导入一些组件
  • 这个类父类有一个方法:selectImports(),这个方法返回 configurations
  • List configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置
    • 将 类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中
  • 加载某个组件的时候根据注解的条件判断每个加入的组件是否生效,如果生效就把类的属性和配置文件绑定起来
  • 这时就读取配置文件的值加载组件

SpringBoot、SpringMVC和Spring区别

spring boot只是一个配置工具,整合工具,辅助工具.

springmvc是框架,项目中实际运行的代码

Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring 的ioc和 aop,ioc 提供了依赖注入的容器, aop解决了面向横切面的编程,然后在此两者的基础上实现了其他延伸产品的高级功能。

用最简练的语言概括就是:

  • Spring 是一个“引擎”;
  • Spring MVC 是基于Spring的一个 MVC 框架;
  • Spring Boot 是基于Spring的条件注册的一套快速开发整合包

SpringBoot 拦截器和过滤器

​ 1、Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。

2、Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行。

3、Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

@WebFilter(urlPatterns = "/*", filterName = "logFilter")
public class LogCostFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        long start = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("LogFilter Execute cost=" + (System.currentTimeMillis() - start));
    }
 
    @Override
    public void destroy() {
 
    }
}

这段代码的逻辑比较简单,就是在方法执行前先记录时间戳,然后通过过滤器链完成请求的执行,在返回结果之间计算执行的时间。这里需要主要,这个类必须继承Filter类,这个是Servlet的规范,这个跟以前的Web项目没区别。 这里直接用@WebFilter就可以进行配置,同样,可以设置url匹配模式,过滤器名称等。这里需要注意一点的是@WebFilter这个注解是Servlet3.0的规范,并不是Spring boot提供的。除了这个注解以外,我们还需在配置类中加另外一个注解:@ServletComponetScan,指定扫描的包。

@SpringBootApplication
@MapperScan("com.pandy.blog.dao")
@ServletComponentScan("com.pandy.blog.filters")
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

上面我们已经介绍了过滤器的配置方法,接下来我们再来看看如何配置一个拦截器。我们使用拦截器来实现上面同样的功能,记录请求的执行时间。首先我们实现拦截器类:

public class LogCostInterceptor implements HandlerInterceptor {
    long start = System.currentTimeMillis();
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        start = System.currentTimeMillis();
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
    }
 
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

这里我们需要实现HandlerInterceptor这个接口,这个接口包括三个方法,preHandle是请求执行前执行的,postHandler是请求结束执行的,但只有preHandle方法返回true的时候才会执行,afterCompletion是视图渲染完成后才执行,同样需要preHandle返回true,该方法通常用于清理资源等工作。除了实现上面的接口外,我们还需对其进行配置:

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

这里我们继承了WebMVCConfigurerAdapter,看过前面的文章的朋友应该已经见过这个类了,在进行静态资源目录配置的时候我们用到过这个类。这里我们重写了addInterceptors这个方法,进行拦截器的配置,主要配置项就两个,一个是指定拦截器,第二个是指定拦截的URL。

spring boot处理一个http请求的全过程

  • 由前端发起请求
  • 根据路径,Springboot会加载相应的Controller进行拦截
  • 拦截处理后,跳转到相应的Service处理层
  • 跳转到ServiceImplement(service实现类)
  • 在执行serviceimplement时会加载Dao层,操作数据库
  • 再跳到Dao层实现类
  • 执行会跳转到mapper层
  • 然后MallMapper会继续找对应的mapper.xml配置文件
  • 之后便会跳转到第4步继续执行,执行完毕后会将结果返回到第1步,然后
  • 便会将数据以JSON的形式返回到页面,同时返回状态码,正常则会返回200,便会回到步骤1中查询判断。