0


SpringBoot——入门及原理

SpringBoot

用来简化

Spring

应用开发,约定大于配置,去繁从简,是由

Pivotal

团队提供的全新框架。其设计目的是用来简化新

Spring

应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置(有特殊需求可以添加自己的配置覆盖默认配置),从而使开发人员不再需要定义样板化的配置。

SpringBoot

可以看成是

J2EE

的一站式解决方案。

一、SpringBoot 的优点

【1】快速创建独立运行的

Spring

项目以及与主流框架集成。
【2】使用嵌入式的

Servlet

容器,应用无需打成

war

包,可以打成

jar

包,通过

java -jar

的方式直接运行。
【3】

starters

(启动器)自动依赖与版本控制。
【4】大量的自动配置,简化开发,也可以修改默认值。
【5】无需配置

XML

,无代码生成,开箱即用。
【6】准生产环境的运行时应用监控。
【7】与云计算的天然集成。

二、解决微服务部署和运维难的问题:Spring Boot

如上的流程依次为: 搭建项目 构建连接 批处理

三、Spring Boot 入门项目

HelloWorld(也可以参考五,快速创建一个 SpringBoot项目)

【1】准备环境:

Maven

settings.xml

配置文件的

profiles

标签添加如下信息:

<profile><id>jdk-1.8</id><activation><activeByDefault>true</activeByDefault><jdk>1.8</jdk></activation><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion></properties></profile>

【2】将

IDEA

Maven

更换为我们自己本地安装的

Maven

。(自行百度更换)创建一个

maven

工程[

jar

],在

pom.xml

中导入如下依赖:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>

【3】编写一个主程序,启动

SpringBoot

应用

@SpringBootApplicationpublicclassHello{publicstaticvoidmain(String[] args)throwsException{//启动spring应用SpringApplication.run(Hello.class, args);}}

【4】编写相关的

Controller

Service

@ControllerpublicclassHelloController{@ResponseBody@RequestMapping("/hello")publicStringhello(){return"hello world!";}}

【5】运行主测试程序。简化部署应用<可以将应用打包成一个可执行的

jar

包>:通过

Maven Projects

中 的

package

(双击)即可。生成

jar

的位置:默认在项目的

target

目录下的“项目名称

.jar

”文件。运行

jar

:在命令行可以通过 “

java -jar jar文件名.jar

” 命令运行项目。

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

四、Hello World 探究(POM文件)

【1】父项目[

spring-boot-starter-parent

]:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent>

【2】进入

spring-boot-starter-parent

发现它还有一个父项目 :

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.0.0.RELEASE</version><relativePath>../../spring-boot-dependencies</relativePath></parent>

【3】进入

spring-boot-dependencies

后,发现如下信息,与之前我们创建的分布式项目继承的

Maven

父项目功能是一样的,用来管理所有

jar

包依赖的版本。称为

SpringBoot

的版本仲裁中心,以后我们导入依赖默认是不需要写版本;(没有在

dependencies

里面管理的依赖,需要声明版本号)

<properties><activemq.version>5.15.3</activemq.version><antlr2.version>2.7.7</antlr2.version><appengine-sdk.version>1.9.62</appengine-sdk.version><artemis.version>2.4.0</artemis.version><aspectj.version>1.8.13</aspectj.version><assertj.version>3.9.1</assertj.version><...此处省略.../></properties>

【4】启动器[

spring-boot-starter-web

]

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
spring-boot-starter-web

spring-boot-starter

spring-boot

场景启动器;进入官网可以到有许多场景启动器,简单点说就是通过此功能将相关

jar

包给组合在起来,我们使用时只需要引入一个

Web Starter

就可以轻松搞定。

Spring Boot

将所有的功能场景都抽取出来,做成一个个的

starters

(启动器),只需要在项目里面引入这些

starter

相关场景,所有依赖都会导入进来。要用什么功能就导入什么场景启动器。

点击

web

右边的

pom

可以看到

SpringBoot

为我们依赖的其它

jar

包,帮我们导入了

web

模块正常运行所依赖的所有组件。如下:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency></dependencies>

【5】主程序类(

Java

类):

@SpringBootApplication

:此注解声明的类,是

SpringBoot

的主配置类,

SpringBoot

就应该运行这个类的

main

方法来启动

SpringBoot

//@ImportResource(locations={"classpath:bean.xml"})//@SpringBootApplication 来标注一个主程序类,说明这是一个SpringBoot应用@SpringBootApplicationpublicclassHellowordQuickStartApplication{publicstaticvoidmain(String[] args){/*SpringBoot应用启动项
        HellowordQuickStartApplication.class 参数必须是用@SpringBootApplication注解修饰的类
        */SpringApplication.run(HellowordQuickStartApplication.class, args);}}
@SpringBootApplication

(主要由:

@SpringBootConfiguration/@EnableAutoConfiguration/@ComponentScan

组成)

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters ={@Filter(type =FilterType.CUSTOM, classes =TypeExcludeFilter.class),@Filter(type =FilterType.CUSTOM, classes =AutoConfigurationExcludeFilter.class)})public@interfaceSpringBootApplication{
@SpringBootConfiguration

:标注在某个类上,表示此类是一个

SpringBoot

的配置类。由以下注解组合形成:配置类 == 配置文件,配置类也是容器的一个组件,底层由

@Component

等等组成。

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Configuration//表示此类是一个配置类  是spring的一个组件public@interfaceSpringBootConfiguration{
@EnableAutoConfiguration

:开启自动配置功能。也是一个组合注解,由以下注解组成(部分重要注解):

@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public@interfaceEnableAutoConfiguration{
@AutoConfigurationPackage

:自动依赖相关的配置包,也是一个组合注解,主要由

@import

等注解组合

@Import({Registrar.class})//给容器中导入一个组件;导入的组件由此组建决定。public@interfaceAutoConfigurationPackage{

进入

@Import(Registrar.class)

中的

Registrar

类中,通过断点,可以查看到我注释的一些信息。

staticclassRegistrarimplementsImportBeanDefinitionRegistrar,DeterminableImports{Registrar(){}//registerBeanDefinitions方法中的metadata可以查看到我们启动类使用的注解 @SpringBootApplicationpublicvoidregisterBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry){AutoConfigurationPackages.register(registry,newString[]{(newAutoConfigurationPackages.PackageImport(metadata)).getPackageName()});}//new AutoConfigurationPackages.PackageImport(metadata) 可以解析出我们当前主启动所在的package包publicSet<Object>determineImports(AnnotationMetadata metadata){returnCollections.singleton(newAutoConfigurationPackages.PackageImport(metadata));}}
@Import(Registrar.class)

作用:将主配置类的所在包以及下边所有子包里面的所有组件扫描到

Spring

容器中。这也就能理解为什么会自动扫描我们写的

@Controller

类了。

@Import(AutoConfigurationImportSelector.class)

:进入

AutoConfigurationImportSelector.class

类中,查看如下方法:

publicString[]selectImports(AnnotationMetadata annotationMetadata){if(!this.isEnabled(annotationMetadata)){returnNO_IMPORTS;}else{try{AutoConfigurationMetadata autoConfigurationMetadata =AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AnnotationAttributes attributes =this.getAttributes(annotationMetadata);// 主要用到的是 这个 configurations 后面会有重点说明List<String> configurations =this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations =this.removeDuplicates(configurations);
            configurations =this.sort(configurations, autoConfigurationMetadata);Set<String> exclusions =this.getExclusions(annotationMetadata, attributes);this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations =this.filter(configurations, autoConfigurationMetadata);this.fireAutoConfigurationImportEvents(configurations, exclusions);returnStringUtils.toStringArray(configurations);}catch(IOException var6){thrownewIllegalStateException(var6);}}}

这是导入组件的选择器方法,将所有需要导入的组件以全类名的方式返回,这些组件最终被添加到容器中。其中

List<String> configurations

会给容器中导入非常多的自动配置类[

xxxAutoConfiguration

],就是给容器中导入这个场景需要的所有组件,并配置好这些组件。有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;自动配置类共109个,如下部分所示:

☹ 那么我们就有疑问,这些自动配置类都是从哪里来的?
进入这个方法:

this.getCandidateConfigurations(annotationMetadata, attributes)
protectedList<String>getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes){// *** 后边需要了解的方法 ***//SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);List<String> configurations =SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(),this.getBeanClassLoader());Assert.notEmpty(configurations,"No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");return configurations;}

进入

SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader)

方法,具体注释说明:

publicstaticList<String>loadFactoryNames(Class<?> factoryClass,@NullableClassLoader classLoader){//org.springframework.context.ApplicationContextInitializerString factoryClassName = factoryClass.getName();return(List)loadSpringFactories(classLoader).getOrDefault(factoryClassName,Collections.emptyList());}privatestaticMap<String,List<String>>loadSpringFactories(@NullableClassLoader classLoader){MultiValueMap<String,String> result =(MultiValueMap)cache.get(classLoader);if(result !=null){return result;}else{try{//通过类加载器(classLoader获取)META-INF/spring.factories(也就是配置了109个自动配置类的文件) 资源Enumeration<URL> urls = classLoader !=null?classLoader.getResources("META-INF/spring.factories"):ClassLoader.getSystemResources("META-INF/spring.factories");LinkedMultiValueMap result =newLinkedMultiValueMap();while(urls.hasMoreElements()){URL url =(URL)urls.nextElement();UrlResource resource =newUrlResource(url);//将urls 当做一个properties配置文件Properties properties =PropertiesLoaderUtils.loadProperties(resource);Iterator var6 = properties.entrySet().iterator();while(var6.hasNext()){Entry<?,?> entry =(Entry)var6.next();//将META-INF/spring.factories文件中的EnableAutoConfiguration下的配置进行加载   如下图所示List<String> factoryClassNames =Arrays.asList(StringUtils.commaDelimitedListToStringArray((String)entry.getValue()));
                    result.addAll((String)entry.getKey(), factoryClassNames);}}

            cache.put(classLoader, result);return result;}catch(IOException var9){thrownewIllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var9);}}}

我们进入其中一个自动配置类中看看

SpringBoot

是不是真的帮我们已经配置好了一些属性[

WebMvcAutoConfiguration

]:

//这里我就摘出一些重要的配置,来帮我我们观察即可。@ConfigurationpublicclassWebMvcAutoConfiguration{@Bean@ConditionalOnMissingBean/** 视图解析器 , SpringBoot中的所有配置文件都是.java形式,方法的名字,就是以前xml中的id。
        等等都是用注解表示的,这个我们后面会重点说明,这里就先了解一下*///我们可以看到SpringBoot已经帮我们配置好了视图解析器 等等一些功能 我们直接使用就好publicInternalResourceViewResolverdefaultViewResolver(){InternalResourceViewResolver resolver =newInternalResourceViewResolver();
        resolver.setPrefix(this.mvcProperties.getView().getPrefix());
        resolver.setSuffix(this.mvcProperties.getView().getSuffix());return resolver;}}

总结:

SpringBoot

在启动的时候从类路径下的

META-INF/spring.factories

中获取

EnableAutoConfiguration

指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作。如此一来,就具有我们在

SSM

等环境下写了一大堆配置文件后才具有的功能。而这些所有配置文件都在

spring-boot-autoconfigure-2.0.0.RELEASE.jar

中。

五、使用 Spring Initializer 快速创建 Spring Boot 项目

注意:

Artifact

中不能大小写混合使用。

通过需求选择

starts

,例如选择

Web

我们就会发现

pom.xml

文件中,就会自动配置了我们引入的

starts

<!-- 摘取一部分 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version><relativePath/><!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies>

**添加

controller

层:** 新注解

@RestController == @ResponseBody

@Controller

的合体;

//这个类的所有方法返回的数据直接写给浏览器(如果是对象转为JSON)//@ResponseBody@Controller@RestControllerpublicclassHelloWordController{@RequestMapping("/hello")publicStringhello(){return"hell";}}

优点: 默认生成的

SpringBoot

项目,我们只需要编写自己的逻辑。默认生成的

Resources

配置文件的目录结构:
【1】

static

:保存所有的静态资源。 [

js/css/image

]
【2】

templates

:保存所有的模板页面[

SpringBoot

默认

jar

包使用嵌入式的

Tomcat

,默认不支持

JSP

页面]但可以使用模板引擎。(

freemarker

thymeleaf


【3】

application.properties

SpringBoot

应用的配置文件。默认的配置都在此文件可以修改。

标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/zhengzhaoyang122/article/details/134494028
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。

“SpringBoot——入门及原理”的评论:

还没有评论