spring boot 源码解析57-actuator组件:info背后的密码(全网独家)

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

解析

我们平常访问/info时会返回一些自定义的信息,一般人只知道在application.properties中配置info.author=herry 开头的配置,这样就可以在访问/info时,就会返回author: “herry”,但是如下的返回值是如何返回的,很多人就不会了

    {
    author: "herry",
    git: {
    commit: {
    time: 1515694386000,
    id: "自定义的commit.id.abbrev"
    },
    branch: "主干"
    },
    build: {
    version: "0.0.1-SNAPSHOT",
    artifact: "demo",
    description: "Demo project for Spring Boot",
    group: "com.example",
    time: 1515694386000
    }
    }

InfoEndpoint的解析在spring boot 源码解析23-actuate使用及EndPoint解析中有介绍,InfoContributor最终是通过InfoEndpoint来调用的.

同时, InfoEndpoint向EndpointHandlerMapping注册的方式是通过EndpointMvcAdapter的方式来完成的,关于这点,可以看spring boot 源码解析55-spring boot actuator HandlerMapping全网独家揭秘

解析

关于这部分的类图如下:

20191017100433\_1.png

InfoContributor

InfoContributor–> 添加 应用详情.代码如下:

    public interface InfoContributor {

        // 向Info.Builder中添加信息
        void contribute(Info.Builder builder);

    }

Info

很简单的一个封装类,使用了建造者模式

代码如下:

    @JsonInclude(Include.NON_EMPTY)
    public final class Info {

        private final Map<String, Object> details;

        private Info(Builder builder) {
            LinkedHashMap<String, Object> content = new LinkedHashMap<String, Object>();
            content.putAll(builder.content);
            this.details = Collections.unmodifiableMap(content);
        }

        @JsonAnyGetter
        public Map<String, Object> getDetails() {
            return this.details;
        }

        public Object get(String id) {
            return this.details.get(id);
        }

        @SuppressWarnings("unchecked")
        public <T> T get(String id, Class<T> type) {
            Object value = get(id);
            if (value != null && type != null && !type.isInstance(value)) {
                throw new IllegalStateException("Info entry is not of required type ["
                        + type.getName() + "]: " + value);
            }
            return (T) value;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (obj != null && obj instanceof Info) {
                Info other = (Info) obj;
                return this.details.equals(other.details);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return this.details.hashCode();
        }

        @Override
        public String toString() {
            return getDetails().toString();
        }

        public static class Builder {

            private final Map<String, Object> content;

            public Builder() {
                this.content = new LinkedHashMap<String, Object>();
            }

            public Builder withDetail(String key, Object value) {
                this.content.put(key, value);
                return this;
            }

            public Builder withDetails(Map<String, Object> details) {
                this.content.putAll(details);
                return this;
            }

            public Info build() {
                return new Info(this);
            }

        }

    }

EnvironmentInfoContributor

EnvironmentInfoContributor–> 一个提供所有environment 属性中前缀为info的InfoContributor.

代码如下:

    public class EnvironmentInfoContributor implements InfoContributor {

        private final PropertySourcesBinder binder;

        public EnvironmentInfoContributor(ConfigurableEnvironment environment) {
            this.binder = new PropertySourcesBinder(environment);
        }

        @Override
        public void contribute(Info.Builder builder) {
            // 通过PropertySourcesBinder 将info为前缀的环境变量抽取出来
            builder.withDetails(this.binder.extractAll("info"));
        }

    }

MapInfoContributor

代码如下:

    public class MapInfoContributor implements InfoContributor {

        private final Map<String, Object> info;

        public MapInfoContributor(Map<String, Object> info) {
            this.info = new LinkedHashMap<String, Object>(info);
        }

        @Override
        public void contribute(Info.Builder builder) {
            builder.withDetails(this.info);
        }

    }

该类没有自动装配

SimpleInfoContributor

代码如下:

    public class SimpleInfoContributor implements InfoContributor {

        private final String prefix;

        private final Object detail;

        public SimpleInfoContributor(String prefix, Object detail) {
            Assert.notNull(prefix, "Prefix must not be null");
            this.prefix = prefix;
            this.detail = detail;
        }

        @Override
        public void contribute(Info.Builder builder) {
            if (this.detail != null) {
                builder.withDetail(this.prefix, this.detail);
            }
        }

该类没有自动装配

InfoPropertiesInfoContributor

InfoPropertiesInfoContributor –> 一个暴露InfoProperties的InfoContributor.其泛型参数为T extends InfoProperties

  1. 字段,构造器如下:

        private final T properties;
    
        // 暴露的模式
        private final Mode mode;
    
        protected InfoPropertiesInfoContributor(T properties, Mode mode) {
            this.properties = properties;
            this.mode = mode;
        }

    Mode是1个枚举,代码如下:

        public enum Mode {
    
            // 暴露所有的信息
            FULL,
    
            // 只暴露预设的信息
            SIMPLE
    
        }
  2. 其声明了如下几个方法:

    1. generateContent –> 抽取出内容为info endpoint 使用.代码如下:

          protected Map generateContent() {
              // 1. 根据模式的不同暴露出所有的数据
              Map content = extractContent(toPropertySource());
              // 2. 默认空实现,子类可复写
              postProcessContent(content);
              return content;
          }
      1. 根据模式的不同暴露出所有的数据.

        toPropertySource方法实现如下:

            protected PropertySource toPropertySource() {
                // 如果模式为FULL,则返回所有的数据,否则,只暴露预设的信息
                if (this.mode.equals(Mode.FULL)) {
                    return this.properties.toPropertySource();
                }
                return toSimplePropertySource();
            }
        1. 如果模式为FULL,则返回所有的数据,否则,只暴露预设的信息
        2. 返回PropertySource–>SIMPLE 模式,抽象方法,子类实现.代码如下:

              protected abstract PropertySource toSimplePropertySource();

        extractContent代码如下:

            protected Map extractContent(PropertySource propertySource) {
                return new PropertySourcesBinder(propertySource).extractAll("");
            }
      2. 默认空实现,子类可复写.代码如下:

            protected void postProcessContent(Map content) {
            }
    2. copyIfSet –> 如果properties中有配置key的话,则copy到target中.代码如下:

          protected void copyIfSet(Properties target, String key) {
              String value = this.properties.get(key);
              if (StringUtils.hasText(value)) {
                  target.put(key, value);
              }
          }
    3. replaceValue –> 替换值.代码如下:

          protected void replaceValue(Map content, String key, Object value) {
              if (content.containsKey(key) && value != null) {
                  content.put(key, value);
              }
          }
    4. getNestedMap –> 获得嵌套的map 如果map中有给定key的话,否则返回empty map.代码如下:

          protected Map getNestedMap(Map map, String key) {
              Object value = map.get(key);
              if (value == null) {
                  return Collections.emptyMap();
              }
              return (Map) value;
          }

InfoProperties

InfoProperties实现了Iterable接口,其泛型为InfoProperties.Entry.Entry如下:

    public final class Entry {

            private final String key;

            private final String value;

            private Entry(String key, String value) {
                this.key = key;
                this.value = value;
            }

            public String getKey() {
                return this.key;
            }

            public String getValue() {
                return this.value;
            }

    }
  1. 字段构造器如下:

        private final Properties entries;
    
        public InfoProperties(Properties entries) {
            Assert.notNull(entries, "Entries must not be null");
            this.entries = copy(entries);
        }

    copy 方法如下:

        private Properties copy(Properties properties) {
            Properties copy = new Properties();
            copy.putAll(properties);
            return copy;
        }
  2. 其它方法实现如下:

    1. get,如下:

          public String get(String key) {
              return this.entries.getProperty(key);
          }
    2. getDate,如下:

          public Date getDate(String key) {
              String s = get(key);
              if (s != null) {
                  try {
                      return new Date(Long.parseLong(s));
                  }
                  catch (NumberFormatException ex) {
                      // Not valid epoch time
                  }
              }
              return null;
          }
    3. iterator,如下:

          public Iterator iterator() {
              return new PropertiesIterator(this.entries);
          }

      PropertiesIterator 代码如下:

          private final class PropertiesIterator implements Iterator {
      
              private final Iterator> iterator;
      
              private PropertiesIterator(Properties properties) {
                  this.iterator = properties.entrySet().iterator();
              }
      
              @Override
              public boolean hasNext() {
                  return this.iterator.hasNext();
              }
      
              @Override
              public Entry next() {
                  Map.Entry entry = this.iterator.next();
                  return new Entry((String) entry.getKey(), (String) entry.getValue());
              }
      
              @Override
              public void remove() {
                  throw new UnsupportedOperationException("InfoProperties are immutable.");
              }
          }
    4. toPropertySource,代码如下:

          public PropertySource toPropertySource() {
              return new PropertiesPropertySource(getClass().getSimpleName(),
                      copy(this.entries));
          }

BuildProperties

BuildProperties–> 继承自InfoProperties,提供项目构建相关的信息

  1. 构造器如下:

        public BuildProperties(Properties entries) {
            super(processEntries(entries));
        }

    processEntries–>从给的Properties 将time所对应的值转换为时间戳的格式.代码如下:

        private static Properties processEntries(Properties properties) {
            coerceDate(properties, "time");
            return properties;
        }
    
        private static void coerceDate(Properties properties, String key) {
            String value = properties.getProperty(key);
            if (value != null) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
                try {
                    String updatedValue = String.valueOf(format.parse(value).getTime());
                    properties.setProperty(key, updatedValue);
                }
                catch (ParseException ex) {
                    // Ignore and store the original value
                }
            }
        }
  2. 其他方法,都是最终调用InfoProperties#get,如下:

        public String getGroup() {
            return get("group");
        }
    
        public String getArtifact() {
            return get("artifact");
        }
    
        public String getName() {
            return get("name");
        }
    
        public String getVersion() {
            return get("version");
        }
    
        public Date getTime() {
            return getDate("time");
        }

GitProperties

GitProperties–> 继承自InfoProperties,提供git相关的信息比如 commit id 和提交时间。

  1. 构造器如下:

        public GitProperties(Properties entries) {
            super(processEntries(entries));
        }

    processEntries–>将git.properties中的commit.time,build.time 转换为yyyy-MM-dd’T’HH:mm:ssZ 格式的数据.代码如下:

        private static Properties processEntries(Properties properties) {
            coercePropertyToEpoch(properties, "commit.time");
            coercePropertyToEpoch(properties, "build.time");
            return properties;
        }

    coercePropertyToEpoch代码如下:

        private static void coercePropertyToEpoch(Properties properties, String key) {
            String value = properties.getProperty(key);
            if (value != null) {
                properties.setProperty(key, coerceToEpoch(value));
            }
        }

    coerceToEpoch –> 尝试将给定的字符串转换为纪元时间.Git属性信息被指定为秒或使用yyyy-MM-dd’T’HH:mm:ssZ 格式的数据.代码如下:

        private static String coerceToEpoch(String s) {
            Long epoch = parseEpochSecond(s);
            if (epoch != null) {
                return String.valueOf(epoch);
            }
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            try {
                return String.valueOf(format.parse(s).getTime());
            }
            catch (ParseException ex) {
                return s;
            }
        }
    
        private static Long parseEpochSecond(String s) {
            try {
                return Long.parseLong(s) * 1000;
            }
            catch (NumberFormatException ex) {
                return null;
            }
        }
  2. 其他方法,都是最终调用InfoProperties#get,如下:

        public String getBranch() {
            return get("branch");
        }
    
        public String getCommitId() {
            return get("commit.id");
        }
    
        public String getShortCommitId() {
            // 1. 获得commit.id.abbrev
            String shortId = get("commit.id.abbrev");
            if (shortId != null) {
                return shortId;
            }
            // 2.commit.id,如果不等于null并且id长度大于7,则截取前7位
            String id = getCommitId();
            if (id == null) {
                return null;
            }
            return (id.length() > 7 ? id.substring(0, 7) : id);
        }
    
        public Date getCommitTime() {
            return getDate("commit.time");
        }

BuildInfoContributor

BuildInfoContributor–>继承自InfoPropertiesInfoContributor,将BuildProperties暴露出去

  1. 构造器如下:

        public BuildInfoContributor(BuildProperties properties) {
            super(properties, Mode.FULL);
        }
  2. 方法实现如下:

    1. contribute,代码如下:

          public void contribute(Info.Builder builder) {
              builder.withDetail("build", generateContent());
          }

      由于BuildInfoContributor默认的Mode为FULL,因此该方法最终会将BuildProperties中的所有数据暴露出去,其key为build

    2. toSimplePropertySource–> 当BuildInfoContributor的Mode为SIMPLE时调用,一般不会调用该方法代码如下:

          protected PropertySource toSimplePropertySource() {
              Properties props = new Properties();
              // 1. 默认读取META-INF/build-info.properties中的build.group
              copyIfSet(props, "group");
              copyIfSet(props, "artifact");
              copyIfSet(props, "name");
              copyIfSet(props, "version");
              copyIfSet(props, "time");
              return new PropertiesPropertySource("build", props);
          }
      1. 将META-INF/build-info.properties中的build.group, build.artifact, build.name, build.version, build.time 复制到Properties中
      2. 实例化PropertiesPropertySource,名字为build
    3. postProcessContent–> 将build.time 转换为time.代码如下:

          protected void postProcessContent(Map content) {
              // 将build.time 转换为time
              replaceValue(content, "time", getProperties().getTime());
          }

GitInfoContributor

GitInfoContributor–>继承自InfoPropertiesInfoContributor,将GitProperties暴露出去

  1. 构造器如下:

        public GitInfoContributor(GitProperties properties, Mode mode) {
            // 默认是SIMPLE
            super(properties, mode);
        }
    
        public GitInfoContributor(GitProperties properties) {
            this(properties, Mode.SIMPLE);
        }
  2. 方法实现如下:

    1. contribute–>当Mode为full时调用,由于默认是SIMPLE,因此该方法一般不会调用.代码如下:

          public void contribute(Info.Builder builder) {
              builder.withDetail("git", generateContent());
          }
    2. toSimplePropertySource–> 默认调用,代码如下:

          protected PropertySource toSimplePropertySource() {
              Properties props = new Properties();
              // 1. 从git.properties中获得branch
              copyIfSet(props, "branch");
              // 2. 从git.properties中获得commit.id.abbrev
              String commitId = getProperties().getShortCommitId();
              if (commitId != null) {
                  props.put("commit.id", commitId);
              }
              // 2. 从git.properties中获得commit.time
              copyIfSet(props, "commit.time");
              return new PropertiesPropertySource("git", props);
          }
      1. 从git.properties中获得branch,复制到props中
      2. 从git.properties中获得commit.id.abbrev,复制到props中
      3. 从git.properties中获得commit.time,复制到props中
      4. 实例化 PropertiesPropertySource,名字为git
    3. postProcessContent,代码如下:

          protected void postProcessContent(Map content) {
              // 1. 获得commit所对应的map中time所对应的值,将其转换为Date,然后将其进行替换
              replaceValue(getNestedMap(content, "commit"), "time", getProperties().getCommitTime());
              // 2. 获得build所对应的map中time所对应的值,将其转换为Date,然后将其进行替换
              replaceValue(getNestedMap(content, "build"), "time", getProperties().getDate("build.time"));
          }
      1. 获得commit所对应的map中time所对应的值,将其转换为Date,然后将其进行替换
      2. 获得build所对应的map中time所对应的值,将其转换为Date,然后将其进行替换

自动装配

InfoProperties

InfoProperties相关的类–>GitProperties,BuildProperties的自动装配是在ProjectInfoAutoConfiguration中, ProjectInfoAutoConfiguration声明了如下注解:

    @Configuration
    @EnableConfigurationProperties(ProjectInfoProperties.class)

ProjectInfoProperties代码如下:

    @ConfigurationProperties(prefix = "spring.info")
    public class ProjectInfoProperties {

        // 构建的具体的信息,默认加载路径为META-INF/build-info.properties
        private final Build build = new Build();

        // git具体的信息,默认加载路径为classpath:git.properties
        private final Git git = new Git();

        public Build getBuild() {
            return this.build;
        }

        public Git getGit() {
            return this.git;
        }

        /** * Make sure that the "spring.git.properties" legacy key is used by default. * @param defaultGitLocation the default git location to use */
        @Autowired
        void setDefaultGitLocation(
                @Value("${spring.git.properties:classpath:git.properties}") Resource defaultGitLocation) {
            getGit().setLocation(defaultGitLocation);
        }

        /** * Build specific info properties. */
        public static class Build {

            /** * Location of the generated build-info.properties file. */
            private Resource location = new ClassPathResource(
                    "META-INF/build-info.properties");

            public Resource getLocation() {
                return this.location;
            }

            public void setLocation(Resource location) {
                this.location = location;
            }

        }

        /** * Git specific info properties. */
        public static class Git {

            /** * Location of the generated git.properties file. */
            private Resource location;

            public Resource getLocation() {
                return this.location;
            }

            public void setLocation(Resource location) {
                this.location = location;
            }

        }

    }

其中Build的默认配置为META-INF/build-info.properties,Git的默认配置为classpath:git.properties

可通过如下属性来配置:

    spring.info.build.location=classpath:META-INF/build-info.properties # Location of the generated build-info.properties file.
    spring.info.git.location=classpath:git.properties # Location of the generated git.properties file.

在ProjectInfoAutoConfiguration中声明2个@Bean方法:

  1. buildProperties,代码如下:

        @ConditionalOnResource(resources = "${spring.info.build.location:classpath:META-INF/build-info.properties}")
        @ConditionalOnMissingBean
        @Bean
        public BuildProperties buildProperties() throws Exception {
            return new BuildProperties(
                    loadFrom(this.properties.getBuild().getLocation(), "build"));
        }
    • @ConditionalOnResource(resources = “${spring.info.build.location:classpath:META-INF/build-info.properties}”)–>满足如下条件时生效:

      1. 如果spring.info.build.location配置了,则如果spring.info.build.location:classpath配置路径下存在资源文件,则返回true
      2. 如果spring.info.build.location没配置,则如果在classpath:META-INF/build-info.properties中存在的话,则生效
    • @ConditionalOnMissingBean –> BeanFactory中不存在BuildProperties类型的bean时生效

    其创建BuildProperties时调用了loadFrom方法,来加载配置的文件,并且将文件中不是build开头的配置进行过滤.

    loadFrom–> 方法只加载给定location的Properties文件中以prefix开头的配置.如下:

        protected Properties loadFrom(Resource location, String prefix) throws IOException {
            String p = prefix.endsWith(".") ? prefix : prefix + ".";
            Properties source = PropertiesLoaderUtils.loadProperties(location);
            Properties target = new Properties();
            for (String key : source.stringPropertyNames()) {
                if (key.startsWith(p)) {
                    target.put(key.substring(p.length()), source.get(key));
                }
            }
            return target;
        }
  2. gitProperties,代码如下:

        @Conditional(GitResourceAvailableCondition.class)
        @ConditionalOnMissingBean
        @Bean
        public GitProperties gitProperties() throws Exception {
            return new GitProperties(loadFrom(this.properties.getGit().getLocation(), "git"));
        }
    • @ConditionalOnMissingBean–> BeanFactory中不存在GitProperties类型的bean时生效
    • @Conditional(GitResourceAvailableCondition.class) –> 如果以下路径中任意1个存在则生效:

      1. spring.info.git.location配置的路径
      2. spring.git.properties配置的路径
      3. classpath:git.properties配置的路径

    其创建GitProperties时调用了loadFrom方法,来加载配置的文件,并且将文件中不是git开头的配置进行过滤.

InfoContributor

InfoContributor相关的子类的自动装配在InfoContributorAutoConfiguration中进行了配置,其声明了如下注解:

    @Configuration
    @AutoConfigureAfter(ProjectInfoAutoConfiguration.class)
    @AutoConfigureBefore(EndpointAutoConfiguration.class)
    @EnableConfigurationProperties(InfoContributorProperties.class)

InfoContributorProperties代码如下:

    @ConfigurationProperties("management.info")
    public class InfoContributorProperties {

        private final Git git = new Git();

        public Git getGit() {
            return this.git;
        }

        public static class Git {

            /** * Mode to use to expose git information. */
            private GitInfoContributor.Mode mode = GitInfoContributor.Mode.SIMPLE;

            public GitInfoContributor.Mode getMode() {
                return this.mode;
            }

            public void setMode(GitInfoContributor.Mode mode) {
                this.mode = mode;
            }

        }

    }

因此可以通过management.info.git.mode,来配置GitInfoContributor的输出模式,默认为SIMPLE

InfoContributorAutoConfiguration声明了3个bean方法:

  1. envInfoContributor,代码如下:

        @Bean
        @ConditionalOnEnabledInfoContributor("env")
        @Order(DEFAULT_ORDER)
        public EnvironmentInfoContributor envInfoContributor(
                ConfigurableEnvironment environment) {
            return new EnvironmentInfoContributor(environment);
        }
    • @Bean –> 注册1个id为envInfoContributor,类型为EnvironmentInfoContributor的bean
    • @ConditionalOnEnabledInfoContributor(“env”) –> 如果配置有management.info.env .enabled= true或者配置有management.info.enabled = true. 或者没有配置时默认匹配
  2. gitInfoContributor,代码如下:

        @Bean
        @ConditionalOnEnabledInfoContributor("git")
        @ConditionalOnSingleCandidate(GitProperties.class)
        @ConditionalOnMissingBean
        @Order(DEFAULT_ORDER)
        public GitInfoContributor gitInfoContributor(GitProperties gitProperties) {
            return new GitInfoContributor(gitProperties, this.properties.getGit().getMode());
        }
    • @Bean –> 注册1个id为gitInfoContributor,类型为GitInfoContributor的bean
    • @ConditionalOnEnabledInfoContributor(“git”) –> 如果配置有management.info.git.enabled= true或者配置有management.info.enabled = true. 或者没有配置时默认匹配
    • @ConditionalOnMissingBean–> BeanFactory中不存在类型为GitInfoContributor的bean时生效
    • @ConditionalOnSingleCandidate(GitProperties.class) –> 如果BeanFactory中只存在1个GitProperties类型的bean或者存在多个,但是存在1个被指定为Primary的bean时生效
  3. buildInfoContributor,代码如下:

        @Bean
        @ConditionalOnEnabledInfoContributor("build")
        @ConditionalOnSingleCandidate(BuildProperties.class)
        @Order(DEFAULT_ORDER)
        public InfoContributor buildInfoContributor(BuildProperties buildProperties) {
            return new BuildInfoContributor(buildProperties);
        }
    • @Bean –> 注册1个id为buildInfoContributor,类型为InfoContributor的bean
    • @ConditionalOnEnabledInfoContributor(“build”) –> 如果配置有management.info.build.enabled= true或者配置有management.info.enabled = true. 或者没有配置时默认匹配

实战

  1. 要先在spring boot的项目中激活 BuildInfoContributor的配置,需要在META-INF目录下存在build-info.properties,我们可以spring-boot-maven-plugin来完成,其有5个goal:

    1. spring-boot:repackage,默认goal。在mvn package之后,再次打包可执行的jar/war,同时保留mvn package生成的jar/war为.origin
    2. spring-boot:run,运行Spring Boot应用
    3. spring-boot:start,在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
    4. spring-boot:stop,在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
    5. spring-boot:build-info,生成Actuator使用的构建信息文件build-info.properties.默认输出路径为${project.build.outputDirectory}/META-INF/build-info.properties

    因此,我们可以修改pom文件为如下:

        
                    org.springframework.boot
                    spring-boot-maven-plugin
                    
                        
                            
                                build-info
                            
                        
                    
        

    此时我们执行mvn: clean install ,就可以发现在最终生成的jar包中存在build-info.properties,如下:

    20191017100433\_2.png

  2. 同样,要激活GitInfoContributor,我们可以在pom文件中加入如下配置:

        
                    pl.project13.maven
                    git-commit-id-plugin
                    2.1.15
                    
                        
                            
                                revision
                            
                        
                    
                    
                        ${project.basedir}/.git
                    
        

    执行mvn:git-commit-id:revision,就可以发现在最终生成的jar包中存在build-info.properties,如下:

    20191017100433\_3.png

  3. 此时,我们启动应用后,访问如下链接http://127.0.0.1:8080/info,就可以发现其返回内容如下:

        { git: { commit: { time: 1517484030000, id: "8973672" },
            branch: "master"
            },
        build: { version: "0.0.1-SNAPSHOT", artifact: "spring-boot-analysis", name: "spring-boot-analysis", group: "com.roncoo", time: 1517484169000 }
        }

    当然我们可以配置management.info.git.mode=FULL,来输出更多的信息,试一下吧

参考链接:

spring-boot:build-info

Spring Boot的Maven插件Spring Boot Maven plugin详解

Maven插件之git-commit-id-plugin


来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring boot 源码解析57-actuator组件:info背后的密码(全网独家)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏