9配置参数加载,以及spring_boot启动流程分析

不想你离开。 提交于 2020-03-03 06:55:35
(1)配置项方法
src->main->resources->application.yml文件内容
spring:
  application:
    name: mytest
  mandatory-file-encoding: GBK
  http:
    encoding:
      enabled: ture
      charset: GBK

server:
  Port: 9090

myConfig:
  myObject:
    myName: zhangsan
    myAge: 20


调用自己写的配置项myConfig方法
import org.springframework.beans.factory.annotation.Value;
@RestController
@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class MyController {

    @Value("${myConfig.myObject.myName}")
    private String myName;

    @Value("${myConfig.myObject.myAge}")
    private int myAge;

    System.out.println(this.myName);
    System.out.println(this.myAge);


(2)远程git仓库

(3)写一个类
3.1 src->java->创建包com.shengsiyuan.boot.config ->创建类->MyConfigBean.java
package com.shengsiyuan.boot.config;
import org.springframework.beans.factory.annotation.Value;
public class MyConfigBean {
    @Value("${myConfig.myObject.myName}")
    private String myName;

    @Value("${myConfig.myObject.myAge}")
    private String myAge;
    public String getMyName() {
        return myName;
    }
    public void setMyName(String myName) {
        this.myName = myName;
    }
    public String getMyAge() {
        return myAge;
    }
    public void setMyAge(String myAge) {
        this.myAge = myAge;
    }
}

3.2 src->java->创建包com.shengsiyuan.boot.config ->创建类->MyConfig.java
package com.shengsiyuan.boot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig{
    @Bean
    public MyConfigBean myConfigBean(){
        return new MyConfigBean();
    }
}

在Controller.java中调用
@Autowired
private MyConfigBean myConfigBean;
System.out.println("---------------------------");
System.out.println(this.myConfigBean.getMyName());
System.out.println(this.myConfigBean.getMyAge());
System.out.println("---------------------------");

之后打包
E:\spring_lecture>gradle bootJar
打包文件在build->libs->spring_lecture-1.0.jar中
java -jar spring_lecture-1.0.jar
unzip spring_lecture-1.0.jar -d ./spring_lecture

build.gradle文件中
buildscript {
    ext{
        springBootVersion='2.2.5.RELEASE'
    }
    repositories {
        maven { url 'https://plugins.gradle.org/m2/' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        mavenCentral()
    }
    dependencies {
        classpath(
                "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}",
                "io.spring.gradle:dependency-management-plugin:1.0.9.RELEASE"
        )
    }
}

apply {
    plugin("java")
    plugin("maven")
    plugin("idea")
    plugin("org.springframework.boot")
    plugin("io.spring.dependency-management")
}
group 'com.shengsiyuan'
version '1.0'

sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
    maven { url 'https://plugins.gradle.org/m2/' }
    maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
    mavenCentral()
}

dependencies {
    compile(
            "org.springframework.boot:spring-boot-starter-web",
            "org.springframework.boot:spring-boot-loader"  //打包加载相关类有关,要加载进来
    )
}

@Override注解
SE5新增加 @ Override注解,它并不是关键字,但是可以把它当作关键字使用。当你想要覆写(重写)
某个方法时,可以选择添加这个注解,在你不留心重载而并非覆写了该方法时,编译器就会生成一条错误信息。
重载:重载的时候,方法名要一样,但是参数类型或个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。

覆写(重写):若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。
举例(引自海涛zht666):在重写父类的onCreate时,在方法前面加上@Override 系统可以帮你检查方法的正确性。
@Override
public void onCreate(Bundle savedInstanceState)
{…….}
这种写法是正确的,如果你写成:
@Override
public void oncreate(Bundle savedInstanceState)
{…….}
编译器会报如下错误:The method oncreate(Bundle) of type HelloWorld must override or implement a supertype method,以确保你正确重写onCreate方法(因为oncreate应该为onCreate)。
而如果你不加@Override,则编译器将不会检测出错误,而是会认为你为子类定义了一个新方法:oncreate


源码解析
External Libraries->Gradle:org.springframework.boot:spring-boot-loader:2.2.5.RELEASE
->Spring-boot-loader-2.2.5.RELEASE.jar->JarLauncher文件内容如下
------------------------------------------------------------------------------------
/*
 * Copyright 2012-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.loader;

import org.springframework.boot.loader.archive.Archive;

/**这是一个启动器,用来启动Jar文件,依赖的Jar位于/BOOT-INF/lib目录下,
 * 工程应用类是被包含在/BOOT-INF/classes目录下
 * {@link Launcher} for JAR based archives. This launcher assumes that dependency jars are
 * included inside a {@code /BOOT-INF/lib} directory and that application classes are
 * included inside a {@code /BOOT-INF/classes} directory.
 *
 * @author Phillip Webb
 * @author Andy Wilkinson
 * @since 1.0.0
 */
//JarLauncher 继承了一个可执行的归档的启动器
public class JarLauncher extends ExecutableArchiveLauncher {
    //定义了两个final的字符串常量,字符串值代表两个目录
   static final String BOOT_INF_CLASSES = "BOOT-INF/classes/";
   static final String BOOT_INF_LIB = "BOOT-INF/lib/";

   public JarLauncher() {
   }

   protected JarLauncher(Archive archive) {
      super(archive);
   }

   @Override
   protected boolean isNestedArchive(Archive.Entry entry) {
      if (entry.isDirectory()) {  //如果是一个路径,尝试加载BOOT_INF_CLASSES
         return entry.getName().equals(BOOT_INF_CLASSES);
      }
      return entry.getName().startsWith(BOOT_INF_LIB);
   }
    // main方法,抛出一个异常,真正的启动代码是new JarLauncher().launch
    //包含jar 包和war包
   public static void main(String[] args) throws Exception {
      new JarLauncher().launch(args);
   }
}

Launcher.java中
public abstract class Launcher{
    protected void launch(String[] args) throws Exception{
    //抽象方法getClassPathArchives返回归档文件,用于构建类路径
    ClassLoader classLoader = createClassLoader(getClassPathArchives());//类加载器
    }
}}


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!