SpringBoot快速入门使用, @EnableAutoConfiguration自动配置原理解析

首先聊聊SpringBoot相对于Spring得优缺点:
Spring优点:
  Spring是Java企业级轻量级代替品,Spring为开发者提供通过依赖注入、面向切面编程,用简单得java对象实现了Enterprise Java Beans得功能。
Spring缺点:
   配置文件文件相对繁琐冗余;
   依赖坐标不能统一管理容易引起冲突不容易排查。
SpringBoot特点:
   基于Spring快速开发体验;
   建项目导入起步依赖,无需配置文件即可使用也可以写修改默认值来满足特定得需求;
   SpringBoot不是对Spring功能的增强而是提供给开发人员一种快速使用Spring得方式
SringBoot核心功能:
  起步依赖就是将某种功能得坐标打包在一起,提供一些默认功能和参数;
  自动配置就是应用启动时得过程决定Spring配置应用哪些,该过程是Spring自动完成得。

快速创建项目一、

  使用IDEA创建普通java项目,然后在POM文件导入相应的起步依赖坐标
在这里插入图片描述
POM文件依赖坐标:
项目要继承SpringBoot的起步依赖spring-boot-starter-parent

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

SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动依赖

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

快速创建项目二、

  使用IDEA直接创建SpringBoot项目
在这里插入图片描述

填写包名/项目名称选择java version版本
在这里插入图片描述
选择自己项目所要依赖得起步坐标在这里插入图片描述
写一个启动类和Controller:(启动类加载的时候可加载到同级目录下所有的子目录)

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * 描述:SpringBoot启动类
 * @author nj
 * @create 2020-12-16 10:34
 */
@SpringBootApplication
public class SpringBootApplicationDemo {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplicationDemo.class);
    }
}
@Controller
public class NjTestControllerSptingBoot {
    @ResponseBody
    @RequestMapping("/nj/TestDemo")
    public String TestDemo(){
        return "TestControllerSptingBoot";
    }
}

SpringBoot启动类上面的注解@SpringBootApplication:
@SpringBootApplication注解
   @SpringBootConfiguration 等同于@Configuration,标注该类是Spring的一个配置类,启用Spring Boot的自动配置机制
   @EnableAutoConfiguration 自动配置功能开启
   @ComponentScan 扫描注解类


SpringBoot自动配置原理解析:

  启动类

package com.nj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author 南江
 * @Description: ${todo}
 * @date 2020/12/14 23:07
 */
@SpringBootApplication
public class SpringBootApplicationTestNj {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplicationTestNj.class);
    }
}

  按ctrl点击查看@SpringBootApplication注解
在这里插入图片描述
  再点击@EnableAutoConfiguration注解
@Import(AutoConfigurationImportSelector.class) 导入了AutoConfigurationImportSelector类

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

  再继续点击AutoConfigurationImportSelector查看源码

public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return StringUtils.toStringArray(configurations);
        }
    }



protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        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方法作用就是从META-INF/spring.factories文件中读取指定类对应得类名称
在这里插入图片描述
  META-INF/spring.factories文件中有关自动配置信息如下显示:
在这里插入图片描述
  以ServletWebServerFactoryAutoConfiguration为例继续点击查看源码:
在这里插入图片描述
@EnableConfigurationProperties(ServerProperties.class) 代表加载ServerProperties服务器配置属性类
  继续点击查看ServerProperties源码:
在这里插入图片描述
在ServerProperties源码当中prefix = “server” 表示SpringBoot配置文件中的前缀,SpringBoot会将配置文件中以server开始的属性映射到该类的字段中。映射关系如下:
在这里插入图片描述


启动时log日志:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.1.RELEASE)

2020-12-16 11:45:18.802  INFO 7660 --- [           main] com.nj.SpringBootApplicationDemo         : Starting SpringBootApplicationDemo on DESKTOP-Q8T0FQQ with PID 7660 (E:\njproject2\njSpringBootDemo\SpringBootTestDemo\target\classes started by jinxin in E:\njproject2\njSpringBootDemo)
2020-12-16 11:45:18.806  INFO 7660 --- [           main] com.nj.SpringBootApplicationDemo         : No active profile set, falling back to default profiles: default
2020-12-16 11:45:18.851  INFO 7660 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e276e: startup date [Wed Dec 16 11:45:18 CST 2020]; root of context hierarchy
2020-12-16 11:45:20.569  INFO 7660 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-12-16 11:45:20.600  INFO 7660 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-12-16 11:45:20.600  INFO 7660 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.29
2020-12-16 11:45:20.610  INFO 7660 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [F:\JDK1.8\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;F:\Clients\;C:\Perl64\site\bin;C:\Perl64\bin;C:\Program Files\ImageMagick-7.0.9-Q8;C:\Program Files\ImageMagick-7.0.8-Q16;F:\python3\Scripts\;F:\python3\;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;F:\apache-maven\apache-maven-3.5.0\bin;F:\JDK1.8\bin;F:\JDK1.8\jre\bin;F:\OpenVPN\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;F:\SVN\bin;F:\nodejs\;C:\Program Files\VanDyke Software\SecureFX\;F:\flex_sdk_3.6a\bin;F:\apache-ant-1.10.7\bin;C:\Program Files (x86)\NetSarang\Xshell 7\;C:\Users\jinxin\AppData\Local\Microsoft\WindowsApps;F:\JDK1.8\bin;F:\JDK1.8\jre\bin;C:\Users\jinxin\AppData\Roaming\npm;F:\vscode\Microsoft VS Code\bin;C:\Users\jinxin\AppData\Local\BypassRuntm;;.]
2020-12-16 11:45:21.199  INFO 7660 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-12-16 11:45:21.200  INFO 7660 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2350 ms
2020-12-16 11:45:21.321  INFO 7660 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
2020-12-16 11:45:21.324  INFO 7660 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2020-12-16 11:45:21.324  INFO 7660 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2020-12-16 11:45:21.324  INFO 7660 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2020-12-16 11:45:21.324  INFO 7660 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2020-12-16 11:45:21.446  INFO 7660 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-12-16 11:45:21.634  INFO 7660 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e276e: startup date [Wed Dec 16 11:45:18 CST 2020]; root of context hierarchy
2020-12-16 11:45:21.700  INFO 7660 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/nj/TestDemo]}" onto public java.lang.String com.nj.controller.NjTestControllerSptingBoot.TestDemo()
2020-12-16 11:45:21.704  INFO 7660 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2020-12-16 11:45:21.705  INFO 7660 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2020-12-16 11:45:21.729  INFO 7660 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-12-16 11:45:21.729  INFO 7660 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-12-16 11:45:21.885  INFO 7660 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2020-12-16 11:45:21.918  INFO 7660 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-12-16 11:45:21.921  INFO 7660 --- [           main] com.nj.SpringBootApplicationDemo         : Started SpringBootApplicationDemo in 3.683 seconds (JVM running for 5.731)

通过日志发现(Tomcat initialized with port(s): 8080 (http)),Tomcat started on port(s): 8080 (http) with context path ‘’ tomcat已经起步,端口监听8080,web应用的虚拟工程名称为空
SpringBoot的配置文件:

<resource>
     <directory>${basedir}/src/main/resources</directory>
          <excludes>
               <exclude>**/application*.yml</exclude>
               <exclude>**/application*.yaml</exclude>
               <exclude>**/application*.properties</exclude>
          </excludes>
</resource>

   以上三个配置文件加载顺序自身而下,所以后加载得会覆盖前面得配置
SpringBoot是基于约定的很多配置都是有默认值的,如果想使用自己的配置替换默认配置可以使用以上三种文件形式的配置文件进行配置。
application.properties文件是是键值对类型的文件,YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,YAML是一种直观的能够被电脑识别的的数据数据序列化格式,YML文件是以数据为核心的,比传统的xml方式更加简洁。
YML文件的拓展名为.yml或者.yaml

#配置tomcat参数 语法为key: value(value前必须有个空格)
server:
  port: 8081
  servlet:
    path: /test
#配置普通参数
age: 13

#配置普通对象
person:
  name: zhangsan
  age: 14
  address: China
#或者
person2: {name: lisi,age: 15,address: Chinese}

#配置map
map: 
 key1: value1
 key2: value2

#配置List、Set数据
city:
  - xian
  - xianyang
  - shanghai
  - shenzhen
city2: {xianyang,xian,shanghai,beijing}

#集合当中的元素是对象形式
student:
  - name: zhangsan
    age: 20
    score: 100
  - name: lisi
    age: 21
    score: 99
  - name: wangwu
    age: 22
    score: 96
student: [{name: zhangsan,age: 20,score: 100},{name: lisi,age: 21,score: 99},{name: wangwu,age: 22,score: 96}]

配置文件(application.yml)参数配合Controller获取参数一起配合使用

package com.nj.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 描述:
 *
 * @author nanjang
 * @create 2020-12-16 10:37
 */
@Controller
public class NjTestControllerSptingBoot {

    @Value("${age}")
    private String age;

    @Value("${person2.name}")
    private String name;

    @Value("${person2.address}")
    private String address;

    @ResponseBody
    @RequestMapping("/nj/TestDemo")
    public String TestDemo(){
        return "age="+age + "name="+name+"address="+address;
    }
}

另一种获取参数方式就是利用@ConfigurationProperties注解进行映射,此时需要导入坐标

package com.nj.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
 * 描述:
 *
 * @author nanjang
 * @create 2020-12-16 10:37
 */
@Controller
@ConfigurationProperties(prefix = "person2")
public class NjTestControllerSptingBoot {

    @Value("${age}")
    private String age;
    
    private String name;

    private String address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @ResponseBody
    @RequestMapping("/nj/TestDemo")
    public String TestDemo(){
        return "age="+age + "name="+name+"address="+address;
    }
}

运行结果展示:
测试结果
以上是SpringBoot快速入门体验,了解配置文件和SpringBoot自动配置原理解析!!!后续会更新SpringBoot整mybatis/oracle/redis。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值