zoukankan      html  css  js  c++  java
  • SprintBoot学习(二)

    Spring Boot的入口类

    1、名为xxxApplication的就是入口类,在main方法中使用SpringApplication.run(SpringBootTestApplication.class, args);启动Spring Boot应用项目。

    2、@SpringBootApplication是由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan的组合注解。其中@EnableAutoConfiguration让Spring Boot 根据类路径中的jar包依赖为当前项目进行自动配置。

    Spring Boot定制banner

    1、查找顺序:依次在 Classpath 下找 文件 banner.gif , banner.jpg ,  banner.png 和 banner.txt,都没有找到的话, 用默认的 SpringBootBanner , 就是我们最常见到的那个。

     2、测试案例:

    新banner.txt

    ${AnsiColor.BRIGHT_YELLOW}
    ////////////////////////////////////////////////////////////////////
    //                                                                //
    //                          ${AnsiColor.BRIGHT_RED}_ooOoo_${AnsiColor.BRIGHT_YELLOW}                               //
    //                         ${AnsiColor.BRIGHT_RED}o8888888o${AnsiColor.BRIGHT_YELLOW}                              //
    //                         ${AnsiColor.BRIGHT_RED}88${AnsiColor.BRIGHT_YELLOW}" . "${AnsiColor.BRIGHT_RED}88${AnsiColor.BRIGHT_YELLOW}                              //
    //                         (| ^_^ |)                              //  
    //                         O  =  /O                              //  
    //                      ____/`---'\____                           //  
    //                    .'  \|     |//  `.                         //  
    //                   /  \|||  :  |||//                          //  
    //                  /  _||||| -:- |||||-                         //  
    //                  |   | \  -  /// |   |                       //  
    //                  | \_|  ''---/''  |   |                       //  
    //                    .-\__  `-`  ___/-. /                       //  
    //                ___`. .'  /--.--  `. . ___                     //  
    //              ."" '<  `.___\_<|>_/___.'  >'"".                  //  
    //            | | :  `- \`.;` _ /`;.`/ - ` : | |                 //  
    //               `-.   \_ __ /__ _/   .-` /  /                 //  
    //      ========`-.____`-.___\_____/___.-`____.-'========         //  
    //                           `=---='                              //  
    //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //  
    //            佛祖保佑       永不宕机     永无BUG                   //
    ////////////////////////////////////////////////////////////////////  

    运行结果:

    3、关闭banner

    SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class);
    springApplication.setBannerMode(Banner.Mode.OFF);
    springApplication.run(args);

    Spring Boot配置文件

    1、Spring Boot使用一个全局的配置文件application.properties 或application.yml,作用是对一些默认配置的配置值进行修改。

    2、profile配置:输Spring 针对不同的环境对不同的配置提供的支持,全局的profile配置使用application-{profile}.properties,通过application.properties中设置spring.profiles.active = prod来指定活动的profile。

    测试案例:

    spring.profiles.active=daily
    #修改访问路径
    server.servlet.context-path=/springboot
    my.username=Amy
    

    3、日志配置:默认情况下使用Logback做为日志框架

    测试案例:

    spring.profiles.active=daily
    #修改访问路径
    server.servlet.context-path=/springboot
    my.username=Amy
    #指定日志文件保存地址
    logging.file=D:/study/SpringBoot/log.log
    debug=true

    4、常规属性配置:在Spring环境下需要用@PropertySource来指定文件的位置再用@Value来指定注入的值。再Spring Boot 中只需要用@Value的注解

    配置文件:

    ser.nikename=Saber
    user.age=21
    

    启动类:

    package com.example.spring_boot_test;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @SpringBootApplication//开启自动配置
    public class SpringBootTestApplication {
    
    
        //通过@Value注入值
        @Value("${my.username}")
        private String userName;
    
        public static void main(String[] args) {
            //关闭banner
            /*SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class);
            springApplication.setBannerMode(Banner.Mode.OFF);
            springApplication.run(args);*/
            SpringApplication.run(SpringBootTestApplication.class, args);
        }
    
        @RequestMapping("/")
        String index() {
            return "hello " + userName + " spring boot !!!";
        }
    
    }

    5、类型安全的配置:如果每次使用@Value注解逐一注入属性会很麻烦,因此可以通过@ConfigurationProperties将properties属性和一个bean关联起来,从而实现类型安全的配置。

    配置文件:

    ser.nikename=Saber
    user.age=21

    类型安全的Bean:

    package com.example.spring_boot_test.entity;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    
    @Component//要使用这个注解,这样就可以在 component scan时候被发现了,不然会无法自动注入,
    @PropertySource({"classpath:/my.properties"})//注意路径的书写格式
    @ConfigurationProperties(prefix = "user")
    public class User {
        String nikename;
        int age;
    
        public String getNikename() {
            return nikename;
        }
    
        public void setNikename(String nikename) {
            this.nikename = nikename;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }

    启动类:

    package com.example.spring_boot_test;
    
    import com.example.spring_boot_test.entity.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @SpringBootApplication//开启自动配置
    public class SpringBootTestApplication {
    
        @Autowired
        private User user;
    
        //通过@Value注入值
        @Value("${my.username}")
        private String userName;
    
        public static void main(String[] args) {
            //关闭banner
            /*SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class);
            springApplication.setBannerMode(Banner.Mode.OFF);
            springApplication.run(args);*/
            SpringApplication.run(SpringBootTestApplication.class, args);
        }
    
        @RequestMapping("/")
        String index() {
            System.out.println(user.getNikename() + ":" + user.getAge());
            return "hello " + userName + " spring boot !!!";
        }
    
    
    }

    Spring Boot运行原理

    1、@SpringBootApplication是由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan的组合注解。核心功能由EnableAutoConfiguration提供。

    • @Configuration:@SpringBootConfiguration的本质是@Configuration,@Configuration相当于把该类作为spring的xml配置文件中的<beans>,作用为配置spring容器(应用上下文),任何一个标注了@Configuration的Java类定义都是一个JavaConfig配置类。
    • @ComponentScan:@ComponentScan自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。
    • @EnableAutoConfiguration:@EnableAutoConfiguration的部分源码如下:
      @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 {};
      
      }        

      其中@Import注解将所有符合自动配置条件的bean定义加载到IoC容器,AutoConfigurationImportSelector通过getCandidateConfigurations方法来扫描具有MWTA-INF/spring.factories文件的jar包(spring-boot-autoconfigure.jar),spring.factories文件声明了自动配置。然后根据@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为查找的Key,获取对应的一组@Configuration类,然后通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,最后汇总为一个并加载到IoC容器。

    Spring Boot执行流程

     

    Spring Boot的执行流程主要分为两大部分:创建一个SpringApplication对象实例 ,调用这个创建好的SpringApplication的实例方法。

     1、创建一个SpringApplication对象实例

    public SpringApplication(Class... primarySources) {
      //创建一个SpringApplication对象实例 this((ResourceLoader)null, primarySources); } public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) { this.sources = new LinkedHashSet(); this.bannerMode = Mode.CONSOLE; this.logStartupInfo = true; this.addCommandLineProperties = true; this.headless = true; this.registerShutdownHook = true; this.additionalProfiles = new HashSet(); this.isCustomEnvironment = false; this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); //推断应用类型this.webApplicationType = this.deduceWebApplicationType(); //使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationContextInitializer。 this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); //使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationListener。 this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); //通过抛出异常来获取到异常栈从而得到入口类的名称设置main方法的定义类。 this.mainApplicationClass = this.deduceMainApplicationClass(); }

    2、调用这个创建好的SpringApplication的实例方法

    public ConfigurableApplicationContext run(String... args) {
       //计时开始
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        //获取所有通过SpringFactoriesLoader可以查找到并加载的SpringApplicationRunListener
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();
    
        Collection exceptionReporters;
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //创建并配置当前Spring Boot应用将要使用的Environment(包括配置要使用的PropertySource以及Profile)。
            //遍历调用所有SpringApplicationRunListener的environmentPrepared()的方法,告诉他们:“当前SpringBoot应用使用的Environment准备好了咯!”。
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            //是否打印banner
            Banner printedBanner = this.printBanner(environment);
            // 创建上下文对象,根据用户是否明确设置了applicationContextClass类型以及初始化阶段的推断结果,决定该为当前SpringBoot应用创建什么类型的
            context = this.createApplicationContext();
         //异常报警
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
         //spring上下文对象的前置处理
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
         //spring上下文对象的刷新
            this.refreshContext(context);
         //spring上下文对象的后置处理
            this.afterRefresh(context, applicationArguments);
         //计算器关闭
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
            //遍历执行listeners,调用它们的started()方法,告诉这些SpringApplicationRunListener,“嘿,SpringBoot应用要开始执行咯!”。
            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }
    
        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }

    Spring Boot中的starter pom

    1、Spring Boot为我们提供了简化企业级开发的绝大多数场景的stater pom,只要使用了应用场景所需要的starter pom就会得到Spring Boot为我们提供的自动配置的bean。

    2、自定义starter pom 测试案例:

    • 新建maven工程

       填写完工程名点击finish,工程创建完成

    • 修改pom文件如下:
      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
      
          <groupId>com.example</groupId>
          <artifactId>spring-boot-starter-hello</artifactId>
          <version>1.0-SNAPSHOT</version>
          <packaging>jar</packaging>
          <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-autoconfigure</artifactId>
                  <version>1.4.3.RELEASE</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-configuration-processor</artifactId>
                  <version>1.4.3.RELEASE</version>
                  <optional>true</optional>
              </dependency>
          </dependencies>
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-maven-plugin</artifactId>
                  </plugin>
              </plugins>
          </build>
          
      </project>
    • 属性配置:
      package com.example.spring_boot_starter_hello;
      
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.context.annotation.PropertySource;
      //类型安全的属性配置
      @PropertySource({"classpath:/my.properties"})//注意路径的书写格式
      @ConfigurationProperties(prefix = "hello")
      public class HelloServiceProperties {
      
          private static final String MSG="world";
      
          private String msg=MSG;
      
          public String getMsg() {
              return msg;
          }
      
          public void setMsg(String msg) {
              this.msg = msg;
          }
      }

      是类型安全的属性配置与properties文件中的属性相对应。

    • service类
      package com.example.spring_boot_starter_hello;
      
      public class HelloService {
      
          private String msg;
      
          public String sayHello(){
              return "hello "+msg;
          }
      
          public String getMsg() {
              return msg;
          }
      
          public void setMsg(String msg) {
              this.msg = msg;
          }
      }
    • 自动配置类
      package com.example.spring_boot_starter_hello;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
      import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
      import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
      import org.springframework.boot.context.properties.EnableConfigurationProperties;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      //@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>,作用为:配置spring容器(应用上下文)
      @Configuration
      //开启属性输入
      @EnableConfigurationProperties(HelloServiceProperties.class)
      //判断HelloService这个类在类路径中是否存在,且在没有这个bean的情况下会自动配置这个bean
      @ConditionalOnClass(HelloService.class)
      //当设置hello=enable的情况下,如果没有设置默认为true,即条件符合
      @ConditionalOnProperty(prefix = "hello",value = "enabled",matchIfMissing = true)
      public class HelloServiceAutoConfiguration {
          @Autowired
          private HelloServiceProperties helloServiceProperties;
          //使用Java配置的方式配置bean
          @Bean
          //当容器没有这个bean的时候会新建bean
          @ConditionalOnMissingBean(HelloService.class)
          public  HelloService helloService(){
              HelloService helloService = new HelloService();
              helloService.setMsg(helloServiceProperties.getMsg());
              return helloService;
          }
      }
    • 注册配置,在src/main/resources下新建META-INF/spring.factories,内容如下:
      #注册自动配置类
      org.springframework.boot.autoconfigure.EnableAutoConfiguration=
      com.example.spring_boot_starter_hello.HelloServiceAutoConfiguration
    • 使用starter 在之前的Spring Boot 中将自定义的starter作为依赖,在pom文件中新增spring-boot-stater-hello的依赖。修改pom文件如下:
      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
      
          <groupId>com.example</groupId>
          <artifactId>spring-boot-test</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <packaging>jar</packaging>
      
          <name>spring_boot_test</name>
          <description>Demo project for Spring Boot</description>
      
          <!--spring boot的父级依赖-->
          <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>2.0.5.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>
              <!--添加web依赖的起步依赖-->
              <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>
      
              <!--需要添加依赖ConfigurationProperties才会起作用-->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-configuration-processor</artifactId>
                  <optional>true</optional>
              </dependency>
      
              <!--添加spring-boot-stater-hello的依赖-->
              <dependency>
                  <groupId>com.example</groupId>
                  <artifactId>spring-boot-starter-hello</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
      
          </dependencies>
      
          <!--添加springboot的编译插件-->
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-maven-plugin</artifactId>
                  </plugin>
              </plugins>
          </build>
      
      
      </project>

      通过mvn  install安装到本地,或者发布到远程maven私服上。

    • 在properties文件中增加属性:hello.msg=hello
    • 在Spring Boot中注入HelloService并使用
      package com.example.spring_boot_test;
      
      import com.example.spring_boot_starter_hello.HelloService;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      import javax.annotation.Resource;
      
      
      @RestController
      @SpringBootApplication//开启自动配置
      public class SpringBootTestApplication {
      
          @Resource
          private HelloService helloService;
      public static void main(String[] args) { //关闭banner /*SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class); springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args);*/ SpringApplication.run(SpringBootTestApplication.class, args); } @RequestMapping("hello") String hello() { return helloService.sayHello(); } }

    转载请于明显处标明出处

    https://www.cnblogs.com/AmyZheng/p/9791552.html

  • 相关阅读:
    英语46级CET外语大学词汇
    TOEFL词汇笔记英语托福英语
    19道常见的JS面试算法题
    Vue.js---指令与事件、语法糖
    Qt--多线程间的互斥
    const关键字总结
    Numpy和Pandas的使用入门
    python爬虫爬取天气数据并图形化显示
    JCEF-鼠标右键菜单
    JCEF-tab形式展示浏览器
  • 原文地址:https://www.cnblogs.com/AmyZheng/p/9791552.html
Copyright © 2011-2022 走看看