1、前言

其实我接触 Spring Boot 的时间并不长,所以还算一个初学者,这篇文章也算是我对 Spring Boot 学习以及使用过程中的复盘,如果文章出现描述错误或表达不清晰的地方,欢迎大家在评论区留言互动。

没想到 Spring Boot 这两年竟然普及的这么快, 两年前刚毕业的时候,因为待的是二线城市的小公司,公司的技术栈并不追求新颖,而是追求稳定、能用就行的理念,所以项目上就一直使用传统的 SSM、SSH。

当搭建后端框架时,需要手动添加 Maven 配置、各种 XML 配置,反正就是一个项目创建就要配置一遍,从我两年前写的这篇 SSM框架搭建,就可以看出该过程是有多么的繁琐,甚至有时候因为配置错误以致于一上午就又可以愉快的划水了...

而项目部署时也是头大,首先需要安装 Tomcat,然后将项目编译打包成 war 包,再将 war 包放在 Tomcat 的 webapp 目录下部署运行,这个过程就觉得很不方便...

汇总一下构建一个传统项目需要的步骤:

  • 配置 web.xml,加载 Spring 和 Spring MVC
  • 配置数据库连接、配置 Spring 事务
  • 配置加载配置文件的读取,开启注解
  • 配置日志文件
  • Redis、MQ 等等 …
  • 配置完成之后部署 Tomcat 调试
  • 可能还需要考虑各个版本的兼容性,jar 包冲突的各种可行性。

因为如上种种问题,当一接触到 Spring Boot 后就被它简单的操作吸引了...

真羡慕现在的小伙伴,一上来就是用的 Spring Boot 了~ 不用再像我那会一样。

2、Spring Boot 解决的问题

Spring Boot 的出现大大简化了传统 Web 框架的搭建过程,提高了开发效率,Spring Boot 总结后有以下几个特点:

  • 可以快速的创建 Spring 应用。
  • 使用嵌入式的Servlet容器,应用无需打成WAR包
  • 整合了大量第三方框架,做到开箱即用。
  • 约定大于配置。

这几个特点基本上也是面试 Spring Boot 时常问的,也正是因为这几个特点让之前繁琐的搭建过程变的简单。

我们都知道,特点并不是解决问题的关键,所以我们要了解,Spring Boot 到底是如何解决问题的。

2.1、自动配置

之前我们使用 XML 方式时,有相当大的部分就是对 Bean 进行初始化并配置,比如下面这一段就是配置数据库连接信息:

<!-- 配置 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://10.211.55.4:3306/test" />
    <property name="username" value="root" />
    <property name="password" value="123456" />
</bean>

而使用 Spring Boot 后,会根据某些约定的规则对所有配置的 Bean 进行初始化,也就是约定优于配置,然后有的小伙伴就会问,那么什么是约定优于配置呢?

约定优于配置可以这样理解:

  1. 开发人员仅需要规定应用中不符合约定的部分。
  2. 在没有规定配置的地方,采用默认配置

举例说明:

不符合规定的部分:例如,如果模型中有个名为 User 的类,那么数据库中对应的表就会默认命名为 user。只有在偏离这一约定时,例如将该表命名为 “user_info”,才需写有关这个名字的配置。

规定默认配置的地方:

  1. Maven 的目录结构。项目创建后默认有 resources 文件夹,用于存放资源配置文件。默认的编译生成的类都在targe文件夹下面。
  2. Spring Boot默认的配置文件必须是,也只能是后缀名为 yml 或者 properties 的文件,且名称唯一。
  3. application.yml中默认的属性。数据库连接信息必须是以 spring: datasource: 为前缀;再就是其他环境配置,比如端口号、请求路径等,后面单独写一篇文章关于默认配置文件的。

是否对这个 yml 或者 properties 文件中配置了信息就实现了配置有点好奇?

我们还是以数据库连接信息为例:在 Spring Boot 中有一个 DataSourceAutoConfiguration 配置类,这个类会自动查找 application.yml 或者 properties 文件里的 spring.datasource.* 路径,然后相关属性会自动配置到数据源中。这个过程就属于约定大于配置,如果感兴趣的小伙伴可以进入这个类看看。

2.2、内嵌容器

Spring Boot 应用程序可以不用部署到外部容器中,比如 Tomcat。Spring Boot 应用可以直接通过 Maven 命令将项目编译成可执行的 jar 包,通过 java -jar 命令启动即可,非常方便。

怎么不需要 Servlet 容器就启动起来了呢?

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

只要加上这个依赖,Spring Boot 就帮我们默认内嵌了 Tomcat,当然同样也支持修改,比如可以使用 jetty(见标签7修改默认内置的Tomcat容器)。

内嵌就内嵌了吧,简单看一下 Tomcat 在 Spring Boot 中是如何启动的。

可以看一下我写的这篇文章:https://www.cnblogs.com/niceyoo/p/14019428.html

2.3、应用监控

应用监控是项目部署中必不可少的环节,以前我们怎么知道系统实际运行的情况呢?

需要我们人为的进行运维监控,比如对 cpu、内存、数据库连接等监控。如果是对系统接口,那么可能会单独写个测试接口来判断当前应用的健康程度,当然,大部分情况接口只要返回200就认为当前应用是健康的。

但是这种情况会存在很大的问题,首先前者会浪费人力资源,后者则因为固定接口形式无法真正意义上判断应用的健康状态。

而 Spring Boot 中提供了一个用于监控和管理自身应用信息的模块—Actuator,通过 Actuator,可以实现对程序内部运行情况进行监控,比如 Bean 加载情况、环境变量、日志信息、线程信息等。当然也可以自定义跟业务相关的监控,通过 Actuator 的端点信息进行暴露。这个有点 DevOps 的意思。

如何集成到 Spring Boot 中呢?

只需要在 pom.xml 中添加如下依赖即可:

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

应用启动则直接可以访问:

  • http://localhost:port/actuator 查看所有端点信息。
  • http://localhost:port/actuator/env 查看该应用全部环境属性。

application配置文件中可配置的参数:

management:
  endpoints:
    web:
      # actuator的访问路径,替换默认/actuator
      base-path: /monitor
      # 设置是否暴露端点 默认只有health和info可见
      exposure:
        # include: env   # 方式1: 暴露端点env,配置多个以,隔开
        include: "*"     # 方式2: 包括所有端点,注意需要添加引号
        # 排除端点,如果不排除则只需要访问该应用的/shutdown 端点就能实现关闭该应用的远程操作
        exclude: shutdown
  server:
    port: 8888  #新开监控端口,不和应用用同一个端口,
  endpoint:
    health:
      show-details: always # 显示db、redis、rabbti连接情况等
    shutdown:
      enabled: true  #默认情况下,除shutdown以外的所有端点均已启用。手动开启

按照如上配置则访问路径为:http://localhost:8888/monitor

我们可以看到有很多节点(图中省略),这些结点被称作 端点,如下是这些端点的描述:

ID 描述 默认启用 默认公开
auditevents 公开当前应用程序的审计事件信息 Yes No
beans 显示应用程序中所有Spring bean的完整列表 Yes No
conditions 显示在配置和自动配置类上评估的条件以及它们是否匹配的原因 Yes No
configprops 显示所有@ConfigurationProperties对照的列表 Yes No
env 从Spring的ConfigurableEnvironment中公开属性 Yes No
flyway 显示已应用的任何Flyway数据库迁移 Yes No
health 显示应用程序健康信息 Yes Yes
httptrace 显示HTTP跟踪信息(默认情况下,最后100个HTTP请求-响应交互) Yes No
info 显示任意应用程序信息 Yes Yes
loggers 显示和修改应用程序中记录器的配置 Yes No
liquibase 显示已应用的任何Liquibase数据库迁移 Yes No
metrics 显示当前应用程序的“指标”信息 Yes No
mappings 显示所有@RequestMapping路径对照的列表 Yes No
scheduledtasks 显示应用程序中调度的任务 Yes No
sessions 允许从Spring Session支持的会话存储中检索和删除用户会话 Yes No
shutdown 让应用程序优雅地关闭 No No
threaddump 执行线程转储 Yes No

如上所知,如果想显示应用程序健康信息,那么就访问 health 端点,即:

http://127.0.0.1:8888/monitor/health

其他的大家可以自行尝试看一下,额外需要注意的是 shutdown 端点,项目中一定要排除,否则只需要访问该应用的 /shutdown 端点就能实现该应用的远程关闭操作,十分危险。

这就完了?

显然不是,上边这样直接访问端点,然后返回 JSON 数据,显然很不直观,毕竟现在很流行可视化嘛~ 咳咳。

所以这时候我们可以通过 Spring Boot Admin 来对 actuator 返回的这些数据进行整理。

关于 Spring Boot Admin 的介绍:

Spring Boot Admin 是用于管理和监控 Spring Boot 应用程序运行状态的。在 Spring Boot 项目中可以通过集成 Spring Boot Admin Client 向 Spring Boot Admin Server 进行注册(通过 HTTP),这样我们就可以在 Spring Boot Admin Server 统一管理 Spring Boot 应用。可视化是端点之上的 Vue 项目。

提供功能如下:

  • 显示健康状态及详细信息,如JVM和内存指标、数据源指标、缓存指标
  • 跟踪并下载日志文件
  • 查看jvm系统-和环境属性
  • 查看Spring启动配置属性
  • 方便loglevel管理
  • 查看线程转储
  • 视图http-traces
  • 查看http端点
  • 查看计划任务
  • 查看和删除活动会话(使用spring-session)
  • 状态更改通知(通过电子邮件、Slack、Hipchat…)
  • 状态变化的事件日志(非持久性)
  • ……

使用 Spring Boot Admin 也是非常的简单,直接添加如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.3.0</version>
</dependency>

配置文件如下:

spring:
  boot:
    admin:
      # 修改上下文路径
      context-path: /admin
      client:
        url: http://127.0.0.1:${server.port}/admin

再在启动类上加上 @EnableAdminServer 注解,齐活,完事。

通过如上界面,我们可以清楚的看到应用的名称和 IP 端口信息,应用名称是默认的,也可以在配置文件中通过 spring.application.name 来自定义名称。

我们还可以点击服务信息进去查看详情,左边是对应的功能菜单,右边是数据展示的页面。详情中有健康信息、线程信息、JVM 内存等信息,都通过图形的方式展示,一目了然。

通过左侧功能菜单可以看到还有 日志、JVM、缓存 等管理功能,大家可以点点看看。

2.4、Spring Boot Starter 开箱即用

关于 Spring Boot Starter 相信大家一定不陌生,很多第三方工具的引入都是涉及到 Starter 包,Starter 包可以说是 Spring Boot 中的核心功能,Starter 的出现,简化了 Spring 很多工作。不懂就问环节:什么是 Starter?

大家可以看一下我转载的这篇文章:

https://www.cnblogs.com/niceyoo/p/14022406.html

总之,Starter 包简化框架集成难度,将 Bean 的自动装配逻辑封装在 Starter 包内部,同时也简化了 Maven Jar 包的依赖,对框架的集成只需要加入一个 Starter 包的配置,降低了烦琐配置的出错几率。

如下是 Spring Boot 提供的开箱即用 Starter 包:

starter desc
spring-boot-starter-web 用于快速构建Web,包含 RESTful 风格框架、SpringMVC和默认的嵌入式容器Tomcat
spring-boot-starter-test 用于测试
spring-boot-starter-data-jpa 带有Hibermate的Spring Data JPA,用于操作数据库。
spring-boot-starter-jdbc 传统的JDBC支持
spring-boot-starter-thymeleaf 支持Thymeleaf模板
spring-boot-starter-mail 支持Java Mail、Spring Email 发送邮件
spring-boot-starter-integration Spring框架创建的一个API,面向企业应用集成(EAI)
spring-boot-starter-mobile SpringMVC的扩展,用来简化手机上的Web应用程序开发
spring-boot-starter-data-redis 快速整合并操作 Redis:通过Spring Data Redis、Redis Client使用Redis
spring-boot-starter-validation Bean Validation是一个数据验证的规范,Hibernate Validator是一个数据验证框架
spring-boot-starter-websocket 相对于非持久的协议HTTP,Websocket 是一个持久化的协议
spring-boot-starter-web-services SOAP Web Services
spring-boot-starter-hateoas 为服务添加HATEOAS功能
spring-boot-starter-security 用Spring Security进行身份验证和授权
spring-boot-starter-data-rest 用Spring Data REST公布简单的REST服务

3、Spring Boot 项目的创建方式

创建 Spring Boot 有两种方式:

  • 手动创建一个 Maven 项目,然后添加 Spring Boot 需要的依赖;
  • 通过 Spring Initializr 脚手架创建;

工具环境 IDEA,下文是基于 Spring Initializr 脚手架创建。

通过 IDEA 创建 Spring Boot 项目实在是太简单了:

关于下一步之后,无非就是选择创建项目的方式(Maven/Gradle),Spring Boot 版本(2.2.2.RELEASE),引入的依赖(Web/SQL/NoSQL/Security等),在这就不赘述了。

4、Spring Boot 编译打包

Spring Boot 项目打包无非就 「打 jar 包、打 war 包」 这两种情况,这两者的应用场景不同,各有优缺点。

jar 包部署优点:

  • 无须搭建本地web容器,默认内置 Tomcat 容器,可以直接以 java -jar 形式运行;
  • 因为自带web容器,可以避免由于web容器的差异造成不同环境结果不一致问题。
  • 借助容器化,可以进行大规模的部署。

jar 包部署缺点:

  • jar 应用体积过大「可以参考瘦身指南」
  • 数据源无法通过界面进行管理。
  • 修改web容器相关配置比较困难,需要借助代码实现。

war 包部署优点:

  • 可以借助web容器管理界面对应用进行管理。
  • web容器配置较为灵活,配置和程序分离。「jar包方式其实也可以」
  • 应用体积较小,甚至可以借助web容器的包管理功能进一步减小应用大小。

war 包部署缺点:

  • 本地需要搭建web容器
  • 调试较为困难,需要借助web容器。
  • 部署较为困难

至于最终选择哪个,本文不追究,毕竟都是要根据实际项目来说的。

以打 jar 包为例

首先需要在 pom.xml 文件中配置 spring-boot-maven-plugin 打包插件,也就是我们通常看到的:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

这样就可以在 Tmerinal 控制台通过 maven 命令进行打包了:mvn package

或者是可以直接在 IDEA 右侧的 Maven 标签:

有小伙伴可能好奇,难道不需要设置 <packaging>jar</packaging> 吗?

<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">
    ...
    <packaging>jar</packaging>
    ...
</project>

其实默认的 就是 jar 方式。

5、Spring Boot 多环境配置

通常在实际开发中,往往涉及到好几个环境,比如开发环境、本地环境、测试环境等等,通常不同环境下的配置信息是不一样的「比如端口号?数据库连接信息等」,因为我们每次只能使用一个配置环境,如果频繁的修改配置以达到效果,自然是麻烦的不行,且很容易出错。

而在 Spring Boot 中,我们可以通过 spring.profiles.active 来激活对应的配置文件。

比如创建如下三个文件:

application.yml「主文件」

  • application-dev.yml:开发环境
  • application-local.yml:本地环境
  • application-test.yml:测试环境

我们想要使用 dev 开发环境,只需要在 application.yml 中使用 spring.profiles.active=dev 就可以完成指定:

spring:
 profiles:
  active: dev

6、替换内置的 Tomcat 容器

尽管Spring Boot内置了 Tomcat ,但是在高并发场景下的 Tomcat 相对来说比较弱。比如在相同的机器配置下,模拟相等的请求数,Undertow在性能和内存使用方面都是最优的。并且Undertow新版本默认使用持久连接,这将会进一步提高它的并发吞吐能力。所以,如果是高并发的业务系统,Undertow 是最佳选择。

问题是怎么替换?

因为 spring-boot-starter-web 中默认自带的容器是 Tomcat,如果想要替换成 Undertow 也是非常简单的。

首先需要排除 spring-boot-starter-web 包中的 Tomcat,然后单独增加 undertow 容器的依赖:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
  <!-- 排除Tomcat依赖 -->
 <exclusions>
  <exclusion>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
  </exclusion>
 </exclusions>
</dependency>

<!-- 添加 Undertow依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

7、配置文件的读取

以前读取 spring 的配置文件,都是通过工具类类读取,其实无非就是读取 xml 文件,比如,通过 ClassPathXmlApplicationContext 加载到文件,然后再通过 上下文拿到 对应的Bean,再取参等。

而在 Spring Boot 中读取配置文件有三种方式:

  1. Environment

  2. @Value

  3. @ConfigurationProperties

我们一一看看这三种方式:

application.yml 中的模拟数据:

niceyoo:
  name: 张三
  age: 24
7.1、Environment

Environment 用于管理当前的应用环境信息,定义了获取 Profile 的方法,同时继承了 PropertyResolver,PropertyResolver 提供了属性访问的相关方法。

也就是我们可以使用 Environment 的 getProperty() 方法读取指定配置 Key 的内容。

代码中体现:

@Controller
@RequestMapping(value = "/test")
public class TestController {

    @Autowired
    private Environment environment;

    @PostMapping("/test")
    @ResponseBody
    public void test(@RequestBody User user) {
        String name = environment.getProperty("niceyoo.name");
        Integer age = Integer.valueOf(environment.getProperty("niceyoo.age"));
        System.out.println(name+" " +age);
    }
}
7.2、@Value

@Value 方式就简单多了,直接在接收的属性上加上该注解即可:

@Controller
@RequestMapping(value = "/test")
public class TestController {

    @Value("niceyoo.name")
    private String name;

    @Value("niceyoo.age")
    private Integer age;

    @PostMapping("/test")
    @ResponseBody
    public void test(@RequestBody User user) {
        System.out.println(name+" " +age);
    }
}
7.3、@ConfigurationProperties

使用该注解可以直接注入到实体类中,方便值的同一管理。

比如我们创建一个 Model 实体类,定义 name、age 属性,然后实现 get\set 方法,再在实体类上加上 @Configuration 和 @ConfigurationProperties(prefix="niceyoo") 注解,并指定前缀为 niceyoo。

@Configuration
@ConfigurationProperties(prefix="niceyoo")
public class Model {
    private String name;
    private Integer age;
    省略get、set方法
}

这样就可以将 niceyoo 下面的值直接对应到实体上了,其中加入 @Configuration 注解,我们在使用时可以直接通过 @Autowired 进行注入。

取值代码:

@Controller
@RequestMapping(value = "/test")
public class TestController {

    @Autowired
    private Model model;

    @PostMapping("/test")
    @ResponseBody
    public void test(@RequestBody User user) {
        System.out.println(model.getName()+" " +model.getAge());
    }
}

总结

以前 Spring 主打轻量级应用框架,但随着外界不断地进行扩充,像是 Shiro、Security、MQ、Redis、ElasticSearch 等等等等, 总之就是 Spring 几乎可以做任何事了,但是相应的问题也来了。

Spring 每集成一个第三方软件,就需要手动增加一些配置,随着新软件的加入,以至于需要引入越来越多的配置,且这些配置各玩各的,难以理解,难以管理,我记得我实习时的那家公司就是这样,各种五花八门的配置文件,以至于经常配置出错,然后解决配置相关的问题就需要好久。

工欲善其行,必先利其器。

Spring Boot 的出现可以说真正的颠覆了以前传统的 Web 项目,开发人员再也不用配置繁琐的 xml 文件了,简直是解放了双手,整个项目的配置文件也变得简洁了。

正所谓简洁并不意味着简单,Spring Boot 只是将众多复杂的功能进行了封装,让我们在使用的时候足够的简单。

关于 Spring Boot 的知识点可以说太多太多了,文中只是把自己能想到的几点描述了出来。

欢迎大家在留言区互动,

博客园持续更新,欢迎关注。希望这篇文章对大家有所帮助。

博客园:https://www.cnblogs.com/niceyoo

从使用传统Web框架到切换到Spring Boot后的总结的更多相关文章

  1. JAVA后台框架优化之微服spring boot

    1.为什么要微服? 首先我们目前后台系统业务链目前还是相对不是那么复杂,但随着项目的拆分,业务的快速推进,各项目模块的接口也随之增加,开发的复杂度不断增加,为以后扩展埋下隐患,而规划新的框架目前主要解 ...

  2. (4)Spring Boot使用别的json解析框架【从零开始学Spring Boot】

    此文章已经废弃,请看新版的博客的完美解决方案: 78. Spring Boot完美使用FastJson解析JSON数据[从零开始学Spring Boot] http://412887952-qq-co ...

  3. 4. 使用别的json解析框架【从零开始学Spring Boot】

    转载:http://blog.csdn.net/linxingliang/article/details/51585921 此文章已经废弃,请看新版的博客的完美解决方案: 78. Spring Boo ...

  4. Spring Boot第四弹,一文教你如何无感知切换日志框架?

    持续原创输出,点击上方蓝字关注我吧 目录 前言 Spring Boot 版本 什么是日志门面? 如何做到无感知切换? 如何切换? 引入依赖 指定配置文件 日志如何配置? 总结 前言 首先要感谢一下读者 ...

  5. Spring与Web框架(例如Spring MVC)漫谈——关于Spring对于多个Web框架的支持

    在看Spring MVC的官方文档时,最后一章是关于Spring对于其它Web框架的支持(如JSF,Apache Struts 2.x,Tapestry 5.x),当然Spring自己的MVC框架Sp ...

  6. 使用 Spring Boot 快速构建 Spring 框架应用--转

    原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/ Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2 ...

  7. 使用 Spring Boot 快速构建 Spring 框架应用,PropertyPlaceholderConfigurer

    Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2002 年发布以来,Spring 框架已经成为企业应用开发领域非常流行的基础框架.有大量的企业应用基于 Spring 框架来开发.S ...

  8. 使用 Spring Boot 快速构建 Spring 框架应用

    Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2002 年发布以来,Spring 框架已经成为企业应用开发领域非常流行的基础框架.有大量的企业应用基于 Spring 框架来开发.S ...

  9. 我的自定义框架 || 基于Spring Boot || 第一步

    今天在园子里面看到一位大神写的springboot做的框架,感觉挺不错,遂想起来自己还没有一个属于自己的框架,决定先将大神做好的拿过来,然后加入自己觉得需要的模块,不断完善 目前直接复制粘贴过来的,后 ...

随机推荐

  1. Linux杂谈:进程锁核+实时线程导致的读写锁死循环

    发现问题 公司项目测试的时候,发现运行一段时间后会出现cpu百分之百的情况. 想着可能是哪里出现了死循环,于是打算用gdb跟一下,结果gdb居然无法attach到进程...... 定位问题 查了查去, ...

  2. netstat与ss

    netstat -t:tcp协议的连接 -u:udp协议的链接 -l:监听状态的连接 -a:所有状态的连接 -p:连接相关的进程 -n:数字格式显示 -r:显示路由表,类似于route或ip rout ...

  3. How to using code find the menu label of Menus【X++】

    // VAR Changed by Xie Yu Fan.Fandy 谢宇帆 static void XIE_FindMenu(Args _args) { Dialog dlg = new Dialo ...

  4. Docker 实战(2)- 配置 Jenkins 容器上的持续集成环境

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 搭建 Jenkins 容器 就是 ...

  5. day89:luffy:使用Celery完成我的订单超时取消&Polyv视频加密播放

    目录 1.我的订单超时取消 2.PoliV视频播放 1.我的订单超时取消 使用Celery完成超时取消功能 mycelery/order/tasks.py from mycelery.main imp ...

  6. VBA_50段代码总结

    ''                                                          30个有用的VBA代码 '目录: '1--合理使用数组:'2--一次保存并关闭所 ...

  7. 使用flexbox的自适应照片布局

    作者:Tim Vam Damme 让我们来看看一种超轻量级的方法,它可以为一组任意大小的照片创建水平砖砌效果.将任何照片丢到上面,它们将边对边无缝对齐. 该解决方案不仅轻巧,而且非常简单.我们将使用无 ...

  8. Spring源码之IOC容器创建、BeanDefinition加载和注册和IOC容器依赖注入

    总结 在SpringApplication#createApplicationContext()执行时创建IOC容器,默认DefaultListableBeanFactory 在AbstractApp ...

  9. 02 Filter过滤器

    Filter 一.Filter过滤器 Filter过滤器它是JavaWeb的三大组件之一.三大组件分别是:Servlet程序.Listener监听器.Filter过滤器 Filter过滤器是JavaE ...

  10. Kafka高性能揭秘:sequence IO、PageCache、SendFile的应用详解

    大家都知道Kafka是将数据存储于磁盘的,而磁盘读写性能往往很差,但Kafka官方测试其数据读写速率能达到600M/s,那么为什么Kafka性能会这么高呢? 首先producer往broker发送消息 ...