SpringBoot其实一点都不难

您所在的位置:网站首页 spring好难学 SpringBoot其实一点都不难

SpringBoot其实一点都不难

2024-07-11 22:04:06| 来源: 网络整理| 查看: 265

扫码关注公众号,领取更多资源 在这里插入图片描述

文章目录 Spring BootSpring Boot 核心功能Spring Boot优缺点优点缺点 创建一个简单的Spring Boot项目@SpringBootApplication注解@Configuration@EnableAutoConfiguration注解 SpringApplication.run()执行流程一个好玩的扩展SpringApplication完整执行流程SpringApplicationRunListenerApplicationListenerApplicationContextInitializerCommandLineRunner Spring Boot自动配置基于条件的自动配置调整自动配置的顺序 Spring-Boot-Starter常用依赖应用日志spring-boot-starter-loggingweb应用开发spring-boot-starter-web数据访问spring-boot-starter-jdbc其他的依赖 SpringBoot微服务的注册与发现

Spring Boot

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2FkBIup2-1604679639248)(你们都比我懂的SpringBoot.assets/5-1ZI11GQ23G.jpg)]

        Spring Boot 是由 Pivotal 团队提供用来简化 Spring 的搭建和开发过程的全新框架。随着近些年来微服务技术的流行,Spring Boot 也成了时下炙手可热的热点技术。         Spring Boot 去除了大量的 xml 配置文件,简化了复杂的依赖管理,配合各种 starter 使用,基本上可以做到自动化配置。Spring 可以做的事情,现在用 Spring boot都可以做。         过去使用Spring创建一个可运行的项目需要进行大量的配置工作,很是繁琐,SpringBoot使用习惯优于配置的理念,内置一个默认配置,无需手动,可以让项目快速运行起来。

Spring Boot 核心功能 独立运行的Spring项目         Spring Boot可以以jar包的形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar即可。内嵌Servlet容器         Spring Boot可以选择内嵌Tomcat,Jetty或者Undertow,这样就可以无需使用war包形式部署项目。提供starter,简化Maven配置         Spring Boot提供一系列的starter pom来简化Maven依赖添加。自动配置Spring         Spring Boot可以根据类路径中的jar包,类,自动配置Bean,减少了配置工作量。准生产的应用监控         Spring Boot提供http,ssh,telnet对项目进行实时监控。无代码生成和xml配置         Spring Boot通过注解实现自动配置,可以无需任何xml就能完成所有配置。 Spring Boot优缺点 优点 快速构件项目无配置快速继承主流框架可独立运行提供运行时监控提高开发部署效率与云计算天然集成 缺点 迭代速度快,某些模块改动较大因为不用手动配置,报错难以定位 创建一个简单的Spring Boot项目

        打开http://start.spring.io/,选择Java语言开发,填写项目信息,然后下载代码。如下图:

spring.io页面

        解压后可以得到一个Spring Boot的启动类,代码如下:

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

        直接选择当前启动类选择运行,一个简单的Spring Boot项目就启动成功了。

@SpringBootApplication注解

        @SpringBootApplication是一个复合的注解,他是如下几个注解组合而成:

@Configuration@EnableAutoConfiguration@ComponentScan

        在启动类上加上如上三个注解可以达到与@SpringBootApplication一样的效果,显然后者更加方便些。

@Configuration

        这里的就是Spring IOC中使用的那个配置。既然Spring Boot本质上就是一个Spring应用,那么自然也需要加载某个IOC容器配置,所以加上@Configuration,本质上也是IOC容器的配置类。         所以上面的启动类也可以拆分为如下两个类:

//配置类 @Configuration @EnableAutoConfiguration @ComponentScan public class DemoConfiguration { @Bean public Controller controller() { return new Controller(); } } //启动类 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoConfiguration.class, args); } }

        在如上两个类中,DemoApplication其实就是一个普通的启动类,而DemoConfiguration就是一个普通的配置类而已。

@EnableAutoConfiguration注解

        @EnableAutoConfiguration也是一个复合的注解,主要包含如下两个:

@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)

        其中最关键的是@Import(EnableAutoConfigurationImportSelector.class),他借助EnableAutoConfigurationImportSelector这个类,将当前应用所有符合条件的@Configuration配置都加载到当前Spring Boot应用的IOC容器中去。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16mRt0xE-1604679639266)(你们都比我懂的SpringBoot.assets/屏幕快照 2020-11-02 19.57.40.png)]

SpringApplication.run()执行流程

        SpringApplication在没有特殊要求的情况下,默认使用模板化的情动流程,但是SpringApplication也在合适的流程节点开放了不用类型的扩展,我们可以对这些扩展点对SpringBoot的启动和关闭流程进行修改扩展。

一个好玩的扩展

        在之前的启动类的main方法中只有这么简单的依据话:

SpringApplication.run(DemoApplication.class,args);

        正常情况下,一个SpringBoot项目启动后会在打印台或者日志中打印一个字符画。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fyxtWaQr-1604679639270)(你们都比我懂的SpringBoot.assets/619240-20180902204227757-252997627.png)]

        但是我们可以在SpringApplication中来修改打印的内容,对启动流程进行扩展:

public class DemoApplication { public static void main(String[] args) { //SpringApplication.run(DemoConfiguration.class, args); SpringApplication bootstrap = new SpringApplication(Demo - Configuration.class); bootstrap.setBanner(new Banner() { @Override public void printBanner(Environment environment, Class aClass, PrintStream printStream) { // 比如打印一个我们喜欢的ASCII Arts字符画 } }); bootstrap.setBannerMode(Banner.Mode.CONSOLE); // 其他定制设置... bootstrap.run(args); } }

        修改banner还有一个简单的方式,就是把需要打印的字符放到一个资源文件中,然后通过ResourceBanner加载:

bootstrap.setBanner(new ResourceBanner(new ClassPathResource("banner.txt")));

        正常情况下我们不需要对这个设置进行定制,因为真正的启动逻辑才是我们需要关注的,这只是为了好玩。

SpringApplication完整执行流程

        SpringApplication中的run()方法主要的流程大体可以概括为如下几个步骤:

如果我们直接使用SpringApplication中的静态run(),那么,在这个方法中会自动创建一个SpringApplication的实例对象,然后调用这个实例对象的run()。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fsJsNZkq-1604679639272)(Boot.assets/屏幕快照 2020-11-03 13.22.30.png)]

在实例化SpringApplication的时候,会提前做好如下几件事情

根据classpath中是否存在ConfigurableWebApplicationContext来决定创建的ApplicationContext类型SpringFactoriesLoader在classpath中查找并加载所有可用ApplicationContextInitializerSpringFactoriesLoader在classpath中查找并加载所有可用ApplicationListener推断并设置main方法的定义 在SpringApplication初始化并完成设置后就开始执行run方法的逻辑了,在执行之前,需要通过SpringFactoriesLoader加载所有的SpringApplicationRunListener,调用他们的started(),通知这些类开始执行当前应用。创建并设置当前SpringBoot应用需要使用的Environment,包括配种的PropertySource和Profile。调用所有SpringApplicationRunListener的environmentPrepared()方法根据用户设置,创建对应类型的ApplicationContext,并将之前准备好的Environment设置给创建号的ApplicationContext使用。借助SpringFactoriesLoader,加载之前的ApplicationContextInitializer,然后调用initialize(applocationContext)方法对Application进一步处理。调用所有SpringApplicationRunListener的contextPrepared()方法将通过@EnableAutoConfiguration获取的所有配置以及其他形式的IOC容器配置加载到已经准备完毕的ApplicationContext中。遍历调用所有SpringApplicationRunListener的contextLoaded()方法,告诉所有的SpringApplicationRunListener,ApplicationContext准备完毕。调用ApplicationContext的refresh()方法。执行ApplicationContext中注册的CommandLineRunner。遍历执行SpringApplicationRunListener的finish()方法。

        至此,一个完整的SpringBoot应用启动完毕。启动的过程很多都是一些通知事件的扩展点,如果忽略这些过程,可以将启动的逻辑精简到如下几步:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bUAMoWU9-1604679639274)(你们都比我懂的SpringBoot.assets/5-1ZI1144050494.png)]

        对比可以发现,SpringApplication提供的扩展点占了启动逻辑的很大一部分,除了初始化并准备好ApplicationContext之外,剩下的大部分工作都是通过扩展点完成的,下面对这些扩展点进行详细的讲解。

SpringApplicationRunListener

        SpringApplicationRunListener是一个在SpringBoot的main方法执行过程中接收事件通知的监听者,主要方法如下:

public interface SpringApplicationRunListener { void started(); void environmentPrepared(ConfigurableEnvironment environment); void contextPrepared(ConfigurableApplicationContext context); void contextLoaded(ConfigurableApplicationContext context); void finished(ConfigurableApplicationContext context, Throwable exception); }

        正常情况下,我们并不需要自己实现一个SpringApplicationRunListener,SpringBoot也只是实现了一个EventPublishingRunListener,用于处理SpringBoot启动时不同的ApplicationEvent。         假如我们需要自定义一个SpringApplicationRunListener,在实现类DemoSpringApplicationRunListener的构造方法中需要两个参数SpringApplication和args,然后可以通过SpringFactoriesLoader的规定,在classpath下的META-INF/spring.factories 中添加如下配置:

org.springframework.boot.SpringApplicationRunListener=\com.keevol.springboot.demo.DemoSpringApplicationRunListener

        随后SpringApplication就会在运行的时候调用他了。

ApplicationListener

        SpringApplication是java中监听者模式的一种实现方式。如果需要添加自定的SpringListener,可以有如下两种方式:

通过SpringApplication.addListeners(...)或者SpringApplication.setListeners(...)添加一个或多个自定义的listener。借助SpringFactoriesLoader,在META-INF/spring.factories中添加如下配置: org.springframework.context.ApplicationListener= \org.springframework.boot.builder.ParentContextCloserApplicationListener, \org.springframework.boot.cloudfoundry.VcapApplicationListener, \org.springframework.boot.context.FileEncodingApplicationListener ApplicationContextInitializer

       ApplicationContextInitializer的目的就是在ConfigurableApplicationContext的ApplicationContext执行refresh()之前,对ConfigurableApplicationContext的实例做一些设置或处理。        实现一个自定义的ApplicationContextInitializer有如下两种方法:

SpringApplication.addInitializers(...)通过添加SpringFactoriesLoader配置 org.springframework.context.ApplicationContextInitializer= \org.springframework.boot.context.ConfigurationWarningsApplication-ContextInitializer, \org.springframework.boot.context.ContextIdApplicationContextInitia-lizer, CommandLineRunner

       CommandLineRunner的源码很简单,如下:

public interface CommandLineRunner{ void run(String... args) throws Exception; }

       需要注意的两点:

所有的CommandLineRunner需要在ApplicationContext完全初始化之后执行。只要存在于ApplicationContext中的CommandLineRunner都会被执行,无需手动添加。

       以上几个扩展点都建议使用@org.springframework.core.annotation.Order进行注解或者实现org.springframework.core.Ordered接口,便于对他们的执行顺序进行调整,避免阻塞。

Spring Boot自动配置

       之前在将@EnableAutoConfiguration的时候说了,这个配置可以借助SpringFactoriesLoader的帮助,将注解了@Configuration的Java类汇总并加载到ApplicationContext中去。        实际上,@EnableAutoConfiguration还能够对自动配置进行正价细化的配置和控制。

基于条件的自动配置

       在Spring框架中,可以使用@Conditional这个注解配合@Configuration或者@Bean来设置一个配置或者实例是否生效,生成一个类似于if-else条件的生成逻辑。

关注公众号回复“Conditional”获取注解相关详解

       如果要基于条件配置,只需要在@Conditional中指定自己的Condition实现类就好了,如下:

@Conditional({DemoConditional1.class,DemoConditional2.class...})

       @Conditional除了可以注解在类和方法上之外,还可以注解在其他Annotation实现类上,组成一个符合的注解,SpringBoot中已经实现了一批,如下:

@ConditionalOnBean:当容器里有指定的 Bean 的条件下。@ConditionalOnClass:当类路径下有指定的类的条件下。@ConditionalOnExpression:基于 SpEL 表达式作为判断条件。@ConditionalOnJava:基于 JVM 版本作为判断条件。@ConditionalOnJndi:在 JNDI 存在的条件下查找指定的位置。@ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下。@ConditionalOnMissingClass:当类路径下没有指定的类的条件下。@ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下。@ConditionalOnProperty:指定的属性是否有指定的值。@ConditionalOnResource:类路径是否有指定的值。@ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选的 Bean。@ConditionalOnWebApplication:当前项目是 Web 项目的条件下。 调整自动配置的顺序

       除了可以设置基于条件的配置,我们还可以对当前配置或者组件的加载顺序进行调整,以便于在创建加载过程中解决依赖分析和组装的问题。        @AutoConfigureBefore或者@AutoConfigureAfter可以配置当前组件或者配置的加载在其他的之前或者之后进行。比如需要某个配置的加载在另外一个之后,可以进行如下配置:

@Configuration @AutoConfigureAfter(JmxAutoConfiguration.class) public class AfterMBeanServerReadyConfiguration { @AutoWired MBeanServer mBeanServer; //通过 @Bean 添加必要的 bean 定义 } Spring-Boot-Starter常用依赖

       之前说过,SpringBoot对开发者的影响主要有以下两点:

基于Spring的配置理念,约定优先于配置提供了各种自动配置依赖的模块,使开发更加高效和快速

       SpringBoot提供了很多以Spring-Boot-Starter开头的依赖模块,这些模块有着默认的配置,正常情况下开箱即用,下面对常用的几个模块做一下介绍:

应用日志spring-boot-starter-logging

       Java中有很多日志工具,比如log4j,log4j2,sel4j等等,在SpringBoot中,我们可以直接引用现成的依赖包,即可达到开箱即用的效果。比如添加如下Maven依赖:

org.springframework.boot spring-boot-starter-logging

       那么SpringBoot就会自动使用logback作为应用的日志框架,在应用启动的时候,初始化LoggingApplicationListener并使用。        如果我们要对日志系统做响应的设置,可以通过如下几种方式进行配置:

在classpath下使用自己定制的logback.xml配置文件在系统中任意位置添加logback.xml配置文件,然后通过application.yml指定文件位置。 logging: config: xml_path

       初次之外,还有其他的日志框架,可自行选择,比如: spring-boot-starter-log4j和 spring-boot-starter-log4j2等等,在实际项目中只需要引用一个即可。

web应用开发spring-boot-starter-web

       通常情况下,我们开发的项目都是一个web项目,需要使用相应的容器来部署。在SpringBoot的maven依赖中添加下面的配置,就可以得到一个可直接运行的web应用。

org.springframework.boot spring-boot-starter-web

       在引入这个依赖之后,启动当前项目,会自动嵌入一个默认的tomcat容器,当前服务就运行在这个容器之中。        spring-boot-starter-web默认将当前项目打包成jar包,在运行的时候可以直接使用java -jar xxx.jar来运行,然后访问响应的请求地址就可以得到响应的response。

数据访问spring-boot-starter-jdbc

       如果项目中需要使用到数据库,那么添加如下依赖:

org.springframework.boot spring-boot-starter-jdbc

       正常情况下我们在一个服务中只需要使用一个数据库,那么这种情况下,只需要在application.yml中添加如下配置即可:

spring: datasource: url: jdbc:mysql://host:port/databaseName username: username password: password

       某些特殊情况下,如果一个服务中需要使用到多个DataSource,那么只需要配置如下实例就好:

@Bean public DataSource dataSource1() throws Throwable { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(...); dataSource.setUsername(...); dataSource.setPassword(...); // TODO other settings if necessary in the future. return dataSource; } @Bean public DataSource dataSource2() throws Throwable { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(...); dataSource.setUsername(...); dataSource.setPassword(...); // TODO other settings if necessary in the future. return dataSource; }

       但是在添加完上面的代码之后,直接启动会报错,我们需要在启动类上排除SpringBoot在启动的时候对默认的DataSource的加载。

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })

       或者在上面配置多个的DataSource上加上@Primary,可同时达到默认的DataSource和定制化的多个DataSource同时加载的两全其美的效果。        除此之外,还有很多适配不同数据库的依赖,spring-boot-starter-data-jpa、spring-boot-starter-data-mongodb 等,在实际项目中可以根据不同的数据库自行选择。

其他的依赖

       SpringBoot还有很多其他的maven依赖,比如:

spring-boot-starter-aopspring-boot-starter-securityspring-boot-starter-actuator …        具体的包可以去Maven官网查找,可以根据当前业务查找到我们需要使用的包以及选择对应的版本。 SpringBoot微服务的注册与发现

       SpringBoot微服务部署到响应的环境之后需要对外提供服务,通常情况下,微服务很少单兵作战,而是同时部署多个节点集群部署。        在这种情况下,如果访问者发出一个请求,这个请求具体访问哪一个节点,如何才能找到对应的节点,这个过程就是服务的发现,而一个服务需要作为一个主题对外提供服务,这个构件主体的过程就成为服务的注册过程。        服务的注册和发现在结构上可以简单的展现为下图的三角关系: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-29UetIAo-1604679639276)(你们都比我懂的SpringBoot.assets/5-1ZP2140S44F-20201106000426003.png)]

       在这整个三角关系中,提供服务的注册者Service Registry是整个关系的核心,他负责登记和保存哪些服务是可以对外提供服务的。当服务的访问者Service Accessor发出请求访问某个服务节点的时候,需要先访问服务注册者,获取可以访问的服务节点信息,这样服务访问者就可以根据返回的信息访问响应的服务。        SpringBoot的微服务注册与发现是有SpringBoot微服务提供服务方式来决定的,如果是基于Dubbo框架的微服务发现方式 ,则很可能是基于Redis或者Zookeeper的注册和发现机制。

       上面这种方式,服务的访问者需要了解服务注册机制,获取到服务节点之后再去访问对应的微服务。但是对于用户而言,服务的访问者就是使用者,不应该过多的去了解服务端有多少节点,而且需要多次访问才能获取响应的请求结果。        一个更好的方案是在服务访问者和注册者之后添加一个服务访问代理,访问者直接对代理发出请求,获取可用节点,对可用节点再次发出请求的工作都交给服务代理去做。优化之后的结构如下: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-860QtbMW-1604679639277)(你们都比我懂的SpringBoot.assets/5-1ZP21412231L.png)]

       经过这样的调整之后,服务的访问者只需要与服务代理打交道,具体服务代理如何发现服务并访问的,对于访问者来说都只是一个黑盒,并不需要做过多的关心。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭