栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot 学习笔记(四) SpringBoot原理分析 | 四个监听机制 | 通过断点调试进行原理分析 | Admin监控机制的运用 | SpringBoot部署模式切换jar与war

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 学习笔记(四) SpringBoot原理分析 | 四个监听机制 | 通过断点调试进行原理分析 | Admin监控机制的运用 | SpringBoot部署模式切换jar与war

文章目录

参考资料运行环境一、SpringBoot 监听机制二、SpringBoot 原理分析

3.1 init初始化3.2 run 三、 SpringBoot 监控概述

3.1 SpringBoot 监控 - Spring Boot Admin3.2 使用 Admin 案例3.3 查看监控信息3.4 查看访问次数3.5 查看注入Spring容器的Bean3.6 查看部署项目线程实时的运行情况3.7 IDEA 提供的监控可视化 四、SpringBoot 项目部署

4.1 Jar4.2 war 五、收获与总结

参考资料

视频资料

运行环境

windows10JDK 8IDEA 专业版SpringBoot 2.5.6 一、SpringBoot 监听机制


SpringBoot的监听机制,其实是对Java提供的事件监听机制的封装

Java中的事件监听机制定义了以下几个角色:

事件:Event,继承 java.util.EventObject类的对象事件源:Source,任意对象 Object监听器:Listener,实现 java.util.EventListener接口的对象

在 SpringBoot项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成一些操作

ApplicationContextInitializerSpringApplicationRunListenerCommandLineRunnerApplicationRunner

测试的项目结构:

spring.factories 用于指定springboot容器的监听类

org.springframework.context.ApplicationContextInitializer=com.uni.listener.MyApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=com.uni.listener.MySpringApplicationRunListener

MyApplicationContextInitializer.java

package com.uni.listener;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("ApplicationContextInitializer....initialize");
    }
}

MyApplicationRunner.java

package com.uni.listener;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner...run");
        System.out.println(Arrays.asList(args.getSourceArgs()));
    }
}

MyCommandLineRunner.java

package com.uni.listener;

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner...run");
        System.out.println(Arrays.asList(args));
    }
}

MySpringApplicationRunListener.java

package com.uni.listener;

import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;

import java.time.Duration;


public class MySpringApplicationRunListener implements SpringApplicationRunListener {

    public MySpringApplicationRunListener(SpringApplication application, String[] args) {

    }

    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("starting...项目启动中");

    }

    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        System.out.println("environmentPrepared...环境对象开始准备");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("contextPrepared...上下文对象开始准备");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("contextLoaded...上下文对象开始加载");
    }

    @Override
    public void started(ConfigurableApplicationContext context, Duration timetaken) {
        System.out.println("started...上下文对象加载完成");
    }


    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("failed...项目启动失败");
    }
}

运行结果:

二、SpringBoot 原理分析

图片来自视频资料:链接

3.1 init初始化

在SpringBoot启动类的run方法处打一个断点进行调试

接下来进入到第一层,SpringApplication.java 执行了 run方法,不过是调用类本身的重载run方法

另一个run方法又通过 SpringApplication类调用了run方法,注意这里传入了primarySource参数,即启动类的字节码

接着查看类SpringApplication.java的构造方法,并在255行设置断点,接着恢复程序(F9)

逐行查看(F8),观察它的构造顺序

通过257行可以看到,SpringBoot启动类,被划分成数组后转化成了linkedHashSet类型的哈希集合

至此,SpringBoot项目启动的初始化部分了解完毕。

3.2 run

和之前类似,这次在SpringApplication.java类的289行处打一个断点进行调试

下图是上图293行的方法实现,这里是遍历了所有的启动依赖

这一步则是准备环境的方法实现,检查是否有配置的准备环境的监听类

准备环境之后,来到了Banner对象,这里就是打印SpringBoot图标的过程

打印图标

Banner是一个接口,通过查看其相关的类SpringApplicationBannerPrinter.java可以观察到一些默认的参数

根据上图的参数,SpringBoot会扫描 resources/banner.txt里的内容作为启动信息,若没有则会默认输出Spring字样,现可以:

更换SpringBoot的启动提示

                   _ooOoo_  
                  o8888888o  
                  88" . "88  
                  (| -_- |)  
                   O = /O  
               ____/`---'____  
             .   ' \| |// `.  
              / \||| : |||//   
            / _||||| -:- |||||-   
              | | \ - /// | |  
            | _| ''---/'' | |  
              .-__ `-` ___/-. /  
          ___`. .' /--.-- `. . __  
       ."" '< `.____<|>_/___.' >'"".  
      | | : `- `.;` _ /`;.`/ - ` : | |  
          `-. _ __ /__ _/ .-` / /  
======`-.____`-.________/___.-`____.-'======  
                   `=---='  

.............................................  
         佛祖保佑             永无BUG 

将文本的内容放在resources / banner.txt里,没有则创建,然后启动项目,替换成功~

Spring启动源码

SpringApplication.java

public ConfigurableApplicationContext run(String... args) {
    
    long startTime = System.nanoTime();
    DefaultBootstrapContext bootstrapContext = createBootstrapContext();
    ConfigurableApplicationContext context = null;
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
     
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        configureIgnoreBeanInfo(environment);
        Banner printedBanner = printBanner(environment);
        context = createApplicationContext();
        context.setApplicationStartup(this.applicationStartup);
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        Duration timetakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timetakenToStartup);
        }
        listeners.started(context, timetakenToStartup);
        callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, listeners);
        throw new IllegalStateException(ex);
    }
    try {
        Duration timetakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
        listeners.ready(context, timetakenToReady);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, null);
        throw new IllegalStateException(ex);
    }
    return context;
}
三、 SpringBoot 监控概述

SpringBoot 自带监控功能 Actuator, 一帮助实现对程序内部运行情况监控,比如监控状况,Bean加载情况、配置属性、日志信息等。

使用步骤:导入起步依赖坐标即可

pom.xml


	org.springframework.boot
    spring-boot-starter-actuator

访问:http://localhost:8080/acruator

返回结果是一个JSON格式的数据,health表示SpringBoot项目里的application所有health字段的内容

接着手动打开配置项目的health监控

application.properties

# 开启健康检查的完整信息
management.endpoint.health.show-details=always

启动项目后访问:http://localhost:8080/acruator/health

现在添加Redis依赖,同时本机不启动Redis,再查看监控的内容

pom.xml


    org.springframework.boot
    spring-boot-starter-data-redis

启动项目,访问 http://localhost:8080/actuator/health,将结果在 https://www.json.cn 里格式化后:

{
    "status":"DOWN",
    "components":{
        "diskSpace":{
            "status":"UP",
            "details":{
                "total":296022437888,
                "free":128095268864,
                "threshold":10485760,
                "exists":true
            }
        },
        "ping":{
            "status":"UP"
        },
        "redis":{
            "status":"DOWN",
            "details":{
                "error":"org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379"
            }
        }
    }
}

可以观察到,导入Redis起步依赖后,SpringBoot能自动监听Redis的启动情况。

显示所有的监控 endpoint

application.properties

# 显示所有的监控 endpoint
management.endpoints.web.exposure.include=*

启动项目,访问 http://localhost:8080/actuator

网址里提供了许多其他的监控地址,这里查看一下bean的监控地址:http://localhost:8080/actuator/beans

http://localhost:8080/actuator/mappings 显示监控SpringBoot项目中类的调用信息

3.1 SpringBoot 监控 - Spring Boot Admin

Spring Boot Admin 是一个开源社区项目,用于管理和监控 SpringBoot 应用程序Spring Boot Admin 有两个角色,客户端(Client)和服务端(Server)应用程序作为Spring Boot Admin Client 向为 Spring Boot Admin Server 注册Spring Boot Admin Server 的UI界面将 Spring Boot Admin Client 的 Actuator Endpoint 上的一些监控信息 3.2 使用 Admin 案例

使用步骤:

admin-server:

    创建 admin-server 模块导入依赖坐标 admin-starter-server

pom.xml(部分)

    
       1.8
       2.6.0
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            de.codecentric
            spring-boot-admin-starter-server
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    
    
        
            
                de.codecentric
                spring-boot-admin-dependencies
                ${spring-boot-admin.version}
                pom
                import
            
        
    
    在引导类上启动监控功能@EnableAdminServer

admin-client:

    创建 admin-client 模块导入依赖坐标 admin-starter-client

pom.xml

    
        1.8
        2.6.0
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            de.codecentric
            spring-boot-admin-starter-client
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    
    
        
            
                de.codecentric
                spring-boot-admin-dependencies
                ${spring-boot-admin.version}
                pom
                import
            
        
    

    配置相关信息:server地址等

服务端配置 application.properties

server.port=9000

客户端配置 application.properties

# 执行 admin.server 地址
spring.boot.admin.client.url=http://localhost:9000

management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=*
    启动server和client服务,访问server

3.3 查看监控信息

访问:http://localhost:9000/applications,查看监控信息

3.4 查看访问次数

UserController.java

package com.uni;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/findAll")
    public String findAll() { return "success"; }
}

访问客户端访问三次:http://localhost:8080/user/findAll

访问服务端,并查看请求结果

3.5 查看注入Spring容器的Bean

3.6 查看部署项目线程实时的运行情况

3.7 IDEA 提供的监控可视化

四、SpringBoot 项目部署

SpringBoot项目开发完毕后,支持两种方式部署到服务器:

jar包(官方推荐)war包 4.1 Jar

默认模式,创建SpringBoot项目后打包默认为Jar包

在IDEA中通过Maven插件进行打包

然后在终端运行jar包

java -jar *.jar

4.2 war

pom.xml

   war

SpringBoot启动类需要继承 SpringBootServletInitializer类并重写一个配置的方法

package com.uni;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class SpringbootDeployApplication extends SpringBootServletInitializer {

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

    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringbootDeployApplication.class);
    }
}

然后使用 Maven打包成war包

若要指定包名则在 pom.xml 里的标签里加上包名即可

将war包配置到外部的Tomcat

启动 Tomcat

访问网址:http://localhost:8080/springboot

五、收获与总结

通过本次的学习,了解到了SpringBoot的四个监听机制,同时跟着视频资料对SpringBoot项目启动的过程进行了简单的调试,通过打断点来观察其运行的原理,调用了哪些类,然后调用了哪些方法,方法的作用等等。

第一次了解到SpringBoot的监听机制,这使笔者想到上学期刚学过的web里面servlet的监听器listener,可以监听servlet或者变量之类的。

通过这几天的学习,现在可以简单的使用SpringBoot进行开发,比如写一个web后端页面,使用全注解开发,然后配置的话只需要在application前缀的配置文件里进行修改,springboot的起步依赖机制真的太方便了,希望在以后的学习与实践中能够熟练运用。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703720.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号