关于spring-boot-编程思想:Java新手如何创建一个spring-boot-web项目呢

写作背景:基于之前的教训,万事开头难。于是这边记录下结尾局部。方面前期能够间接应用,缩小学习老本。 依赖文件: <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo12</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo12</name> <description>demo12</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.24</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build></project>Java版本,8.0 ...

September 23, 2023 · 3 min · jiezi

关于spring-boot-编程思想:Spring-Boot-单体应用一键升级成-Spring-Cloud-Alibaba

背景随着 Apache Dubbo、Nacos 以及 Spring Cloud 等服务框架的风行,越来越多的企业开始采纳微服务架构来构建其应用程序。微服务架构使企业可能将其应用程序拆分成多个小型服务,这些服务能够独立部署和扩大。这种架构模式也使企业更容易实现麻利开发和继续交付,从而进步了其业务效率和响应能力。 微服务四大件:注册核心、服务提供者、服务消费者、服务治理 现在,随着服务提供者、服务消费者、服务注册核心以及服务治理等微服务几大件的呈现和成熟,使得咱们应用微服务开发,不仅能够做到疾速开发,更可能谋求微服务的高效和稳固。 单体 or 微服务? 从上图咱们能够看到,随着业务规模的增大,抉择单体架构与微服务架构的抉择趋势,他们之间存在一个交点。在交点之后,抉择微服务架构,业务规模越大越能够享受到微服务架构带来的效率的晋升。咱们能够察看到,这个交点在继续地向左挪动。数字化过程的疾速倒退广泛让企业的 IT 零碎更简单,开源以及云计算推动的技术标准化,正在大幅度地升高微服务架构的技术门槛,在云上小公司也能够很好地玩转微服务。随着这个趋势的到来,还在应用单体架构的企业也逐步思考向微服务转型。咱们发现在云上大部分 Java 利用依然是基于 SpringBoot 的,Spring Boot 利用因为其架构实现的简略性,客户端只需通过 http 和域名就能实现服务调用。因而,许多中小型公司依然采纳该形式进行利用开发。从技术角度上看,咱们如何降级 SpringBoot 利用至微服务架构,享受到微服务治理带来的技术红利,咱们须要减少 SpringCloud 的 maven 依赖?须要业务进行代码革新?本文能够答复你,不须要一行代码改变。 本计划能够通过 MSE 无侵入实现 Java 利用的注册、发现与治理能力。 以后 MSE 提供的注册核心产品能力次要集中在非长久化服务发现,即服务的状态保护在 client,须要业务方依赖 SDK 被动注册服务,并维持心跳;本计划提供了一种的长久化服务发现能力。解决跨平台服务发现问题,如跨 K8s 服务发现、非 K8s 服务和 K8s 服务相互发现等。无侵入实现基于 Spring Boot 利用的服务治理能力,如全链路灰度、限流降级、平安可信等。计划实际与摸索为了验证该场景,咱们提供了一个略微比较复杂的Demo,通过该 Demo 来别离演示如何通过 MSE 无侵入实现 Spring Boot 利用的服务注册与服务治理。Demo 是依据 K8s Service 进行服务发现并且通过简略的 HttpClient 进行申请调用,具体申请如下: ➜ ~ curl http://47.97.117.48/A/spring_boot A[10.0.3.238] -> B[10.0.3.227] -> C[10.0.3.230]%架构如下所示: ...

May 8, 2023 · 1 min · jiezi

关于spring-boot-编程思想:Spring-Boot自定义配置与自动配置共存

Spring Boot 是一个疾速开发框架,能够简化 Spring 应用程序的开发,其中自定义配置是其中一个十分重要的个性。 在 Spring Boot 中,自定义配置容许开发者以本人的形式来配置应用程序。自定义配置能够用于笼罩默认配置,也能够用于增加新的配置项。本文将具体介绍 java框架面试题-Spring Boot 自定义配置与主动配置共存,并提供 Java 代码案例。 一.Spring Boot自定义配置的过程Spring Boot是一种基于Spring框架的疾速开发应用程序的工具。它应用主动配置和约定大于配置的形式,简化了开发人员的工作量。在Spring Boot中,能够应用application.properties或application.yml文件来配置应用程序的属性。然而,有时候须要自定义配置,以满足特定的需要。 上面给大家带来的是自定义配置的过程和代码案例的详细分析: 1.创立一个配置类首先,创立一个Java类,用于自定义配置。这个类须要应用@Configuration注解,以批示它是一个配置类。此外,如果须要在配置类中应用其余的Spring组件,比方@Bean注解,还须要应用@ComponentScan注解来扫描这些组件。 @Configuration@ComponentScanpublic class MyConfig { //定义配置项 } 2.定义配置项在配置类中,能够定义须要自定义的配置项。这些配置项能够是应用程序中的任何属性,例如数据库连贯参数、邮件服务器设置、缓存策略等等。配置项须要应用@Bean注解,以批示它是一个Spring Bean。在@Bean注解中,须要应用@ConfigurationProperties注解来指定配置项的前缀和属性。 @Configuration@ComponentScanpublic class MyConfig { @Bean @ConfigurationProperties(prefix = "myapp.database") public DataSource dataSource() { //定义数据源配置} @Bean @ConfigurationProperties(prefix = "myapp.email") public EmailProperties emailProperties() { //定义邮件服务器配置} } 在下面的例子中,咱们定义了两个配置项:dataSource和emailProperties。这些配置项的前缀别离为“myapp.database”和“myapp.email”。 3.增加配置文件接下来,须要增加一个application.properties或application.yml文件,以存储自定义配置。 在这个文件中,须要为每个配置项指定一个值。如果应用的是application.properties文件,须要依照“前缀.属性=值”的格局来配置。如果应用的是application.yml文件,须要依照以下格局来配置: myapp: database: driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/mydbusername: myuserpassword: mypassemail: host: smtp.gmail.comport: 587username: myemail@gmail.compassword: myemailpassword在下面的例子中,咱们为dataSource和emailProperties两个配置项指定了值。 4.应用自定义配置当初,能够在应用程序中应用自定义配置了。只须要在须要应用配置的类中,应用@Autowired注解来主动注入配置类中的Bean即可。 @RestControllerpublic class MyController { @Autowired private DataSource dataSource; ...

April 12, 2023 · 3 min · jiezi

关于spring-boot-编程思想:使用Spring-Boot管理监控应用程序状态

应用Spring Boot治理监控应用程序状态1个Spring Boot执行器Spring Boot执行器是Spring Boot提供的应用程序的自检和监控性能,如健康检查、审计、索引收集、HTTP跟踪等。,能够帮忙开发者和运营商监控和治理Spring Boot利用。该模块收集利用的外部信息并向内部模块公开,反对HTTP和JMX,能够与一些第三方监控零碎(如Prometheus)集成。1.1致动器端点端点是执行器的外围组件,用来监控应用程序的各种状态。Spring Boot致动器内置有许多端点,通常分为三类: 利用类:次要包含配置信息、Spring Bean信息、配置文件信息、环境信息等。Metric class:运行时应用程序的信息,包含堆栈、衰弱状态、线程池信息、HTTP申请统计等。操作类:如关机,提供敞开利用等操作类性能。 1.2增加依赖关系在pom.xml中增加执行器的启动器:springframework.boot弹簧靴起动器致动器 1.3拜访端点增加依赖项后,启动服务,您能够通过以下申请查看公开的端点: http://localhost:9099/actuator该申请返回:{" _links": {"自我":{" href ":" http://localhost:9099/actuator ",“模板化”:假},"衰弱门路":{" href ":" http://localhost:9099/actuator/health/{ * path } ",“模板化”:真},"衰弱":{" href ":" http://localhost:9099/actuator/health ",“模板化”:假 }}复制代码从返回的后果能够看出,默认状况下只关上了/actuator/health端点。拜访端点{"status":"UP"} 复制代码其余未关上的端点能够独立配置为关上或敞开。在application.yml中增加以下配置,以关上所有端点并显示具体的运行状况: 管理层:端点:网页:曝光率:包含:“*”端点:衰弱:显示详细信息:始终2 Spring Boot治理Spring Boot执行器提供各种端点。Spring Boot管理员能够在一个界面中显示执行器中的信息,并提供实时报警性能。在微服务环境中,应用Spring Boot治理,通常包含服务器和客户端。服务器只运行Spring Boot治理服务器来收集每个客户端的数据并显示在可视化界面中。运行客户端Spring Boot治理客户端,或通过服务发现和注册获取应用程序信息。我不在这里演示的Spring Boot治理服务器上。我将应用以后的hero-springboot-demo作为服务器和客户端。在前面的实战章节中,Admin服务器将是独立的,客户端不会应用客户端,而是通过服务进行注册和发现。2.1增加依赖关系在pom.xml中增加Spring Boot治理服务器的依赖关系: 去代码中心化弹簧-启动-治理-启动-服务器2.7.4去代码中心化spring-boot-治理-启动器-客户端2.7.4复制代码留神版本号。因为Spring Boot的版本用的是2.7.x,所以Spring Boot Admin服务器的版本应该也是2.7.x,不要乱来!2.2关上治理服务器在启动类demo application @ enableadminserver上增加正文,以关上Spring Boot治理服务器。 @EnableAdminServer@启用异步@ mapper scan(" com . yygnb . demo . mapper ")@SpringBootApplication公共类演示应用程序{...}复制代码2.3配置客户端在application.yml中增加以下配置: 配置上下文门路;治理服务器的;为客户机配置管理服务器的地址。 春天:利用:名称:英雄-跳羚-演示开机:管理员:客户:URL:“http://localhost:9099/monitor”上下文门路:“/monitor”复制代码2.4拜访治理服务器重新启动服务,并在浏览器中拜访Spring Boot治理服务器:http://本地主机:9099/monitor复制代码您能够看到,以后利用的在治理服务器上注册为客户端: 3个自定义警报当利用状态异样时,Spring Boot管理员会实时主动报警,报警形式可由咱们自定义。这里模仿日志的形式。在配置包下,创立DemoNotifier类,该类继承自AbstractEventNotifier: @Slf4j@组件公共类DemoNotifier扩大AbstractEventNotifier {受爱护的演示告诉程序(实例存储库){超级(储存库);}@笼罩受爱护的Mono doNotify(InstanceEvent事件,Instance实例){返回mono . from runnable(()--> log . error("实例信息:{},{},{} ",instance.getRegistration()。getName(),event.getInstance(),event . gettype())); }}复制代码此时,当注册到此治理服务器的其余客户机启动和进行时,以后应用程序将监听事件并输入日志。你能够发送邮件、信息等。在实战中。4登录权限下面配置的治理服务器能够不必登录就能够拜访,然而只有在real development中登录后能力拜访。治理服务器还提供了一个登录页面。4.1增加依赖关系在pom.xml中增加Spring Security的依赖项: ...

September 10, 2022 · 1 min · jiezi

关于spring-boot-编程思想:Spring-BootVue3-动态菜单完成思绪梳理

Spring Boot+Vue3 动静菜单实现思路梳理对于 Spring Boot + Vue3 的动静菜单,松哥之前已经写了两篇文章了,这两篇文章次要是从代码上和大家分析动静菜单最终的实现形式,然而还是有小伙伴感觉没太看明确,感觉不足一个纲要挈领的思路,所以,明天松哥再整一篇文章和大家再来捋一捋这个问题,心愿这篇文章能让小伙伴们彻底搞明显这个问题。 1. 整体思路首先咱们来看整体思路。 有父有子:像系统管理那种,既有父菜单,又有子菜单。只有一个一级菜单,这种又细分为三种情况 一般的菜单,点击之后在左边主页面打开某个功能页面。一个超链接,但不是外链,是一个在以后零碎中打开的内部网页,点击之后,会在左边的主页面中新开一个选项卡,这个选项卡中浮现的是一个内部网页(本质上是通过 iframe 标签引入的一个内部网页)。一个超链接,并且还是一个外链,点击之后,间接在阅读器中打开一个新的选项卡,新的选项卡中展示一个内部链接。 四种菜单对应的 JSON 格局别离如下:有父有子: { "name": "Monitor", "path": "/monitor", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统监控", "icon": "monitor", "noCache": false, "link": null }, "children": [{ "name": "Online", "path": "online", "hidden": false, "component": "monitor/online/index", "meta": { "title": "在线用户", "icon": "online", "noCache": false, "link": null } }, { "name": "Job", "path": "job", "hidden": false, "component": "monitor/job/index", "meta": { "title": "定时工作", "icon": "job", "noCache": false, "link": null } }]}复制代码 ...

July 22, 2022 · 5 min · jiezi

关于spring-boot-编程思想:Spring-BootVue3-动态菜单完成思绪梳理

Spring Boot+Vue3 动静菜单实现思路梳理对于 Spring Boot + Vue3 的动静菜单,松哥之前已经写了两篇文章了,这两篇文章次要是从代码上和大家分析动静菜单最终的实现形式,然而还是有小伙伴感觉没太看明确,感觉不足一个纲要挈领的思路,所以,明天松哥再整一篇文章和大家再来捋一捋这个问题,心愿这篇文章能让小伙伴们彻底搞明显这个问题。 1. 整体思路首先咱们来看整体思路。 有父有子:像系统管理那种,既有父菜单,又有子菜单。只有一个一级菜单,这种又细分为三种情况 一般的菜单,点击之后在左边主页面打开某个功能页面。一个超链接,但不是外链,是一个在以后零碎中打开的内部网页,点击之后,会在左边的主页面中新开一个选项卡,这个选项卡中浮现的是一个内部网页(本质上是通过 iframe 标签引入的一个内部网页)。一个超链接,并且还是一个外链,点击之后,间接在阅读器中打开一个新的选项卡,新的选项卡中展示一个内部链接。 四种菜单对应的 JSON 格局别离如下: 有父有子: { "name": "Monitor", "path": "/monitor", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统监控", "icon": "monitor", "noCache": false, "link": null }, "children": [{ "name": "Online", "path": "online", "hidden": false, "component": "monitor/online/index", "meta": { "title": "在线用户", "icon": "online", "noCache": false, "link": null } }, { "name": "Job", "path": "job", "hidden": false, "component": "monitor/job/index", "meta": { "title": "定时工作", "icon": "job", "noCache": false, "link": null } }]}复制代码 ...

July 15, 2022 · 5 min · jiezi

关于spring-boot-编程思想:SpringBoot的自动配置下篇架构师如何自定义自己的条件注解与自动配置

本专栏将从根底开始,循序渐进,以实战为线索,逐渐深刻SpringBoot相干常识相干常识,打造残缺的云原生学习步骤,晋升工程化编码能力和思维能力,写出高质量代码。心愿大家都可能从中有所播种,也请大家多多反对。专栏地址:SpringBoot专栏本文波及的代码都已放在gitee上:gitee地址如果文章知识点有谬误的中央,请斧正!大家一起学习,一起提高。 Spring Boot的外围性能就是为整合第三方框架提供主动配置,而本文则带着大家实现了本人的主动配置和Starter,一旦真正把握了本文的内容,就会对Spring Boot产生“一览众山小”的感觉。文章目录 自定义条件注解 自定义主动配置自定义条件注解 在SpringBoot中,所有自定义条件注解其实都是基于@Conditional而来的,应用 @Conditional定义新条件注解要害就是要有一个Condition实现类, 该Condition实现 类 就负责条件注解的解决逻辑, 该实现类所实现的 matches()办法决定了条件注解的要求是否失去满足 面是自定义条件注解的 Condition实现类的代码。src/main/java/com/example/_003configtest/condition/MyCondition.java package com.example._003configtest.condition;import com.example._003configtest.annotation.ConditionalCustom;import org.springframework.context.annotation.Condition;import org.springframework.context.annotation.ConditionContext;import org.springframework.core.env.Environment;import org.springframework.core.type.AnnotatedTypeMetadata;import java.util.Map;public class MyCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //获取@ConditionalCustom注解的全副属性,其中ConditionalCustom是自定义的注解 Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ConditionalCustom.class.getName()); //获取注解的value属性值 String[] vals = (String[]) annotationAttributes.get("value"); //env是application.properties或application.yml中配置的属性 Environment env = context.getEnvironment(); //遍历每个value的每个属性值 for (String val : vals) { //如果某个属性值对应的配置属性不存在,则返回false if(env.getProperty(val.toString())== null){ return false; } } return true; }}从下面的逻辑能够看到,自定义条件注解的解决逻辑比较简单:就是要求value属性所指定的所有配置属性必须存在,至于这些配置属性的值是什么无所谓,这些配置属性是否有值也无所谓。 ...

July 11, 2022 · 4 min · jiezi

关于spring-boot-编程思想:Spring-Boot-和-Spring-到底有啥区别

Spring 为基于Java的企业应用提供了全面的编程和配置模型,并应用于任何的部署平台。 编程模型包含: DI, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP. Test Spring MVC Data Access:Transaction, DAO, JDBC,ORM 等等一系列生产中须要用的模块,使开发人员能够专一于本人的业务逻辑。 Spring Boot 基于Spring,仿佛能够了解为一个应用spring框架实现的类库,为开发者提供更简便的应用形式,缩小配置,按约定主动拆卸等。 通过‘Starter’ 依赖项来简化依赖项,Starter中包含运行的所有依赖项。 主动拆卸,代码中应用Component及相干子注解标注的类会被主动扫描并实例化到IOC容器,不在须要xml配置。 在可能的状况下主动配置第三方类库,会主动遍历每个jar包下是否存在META-INFO/spring.factories文件,存在即从期中读取EnableAutoConfiguration标注的类全限定名,实例化该类,并执行期中的配置逻辑。 内嵌服务器(如:tomcat、jetty),能够编译成Jar间接运行。 关键词:java培训 Spring全套视频学习材料:http://www.atguigu.com/download.shtml

April 24, 2022 · 1 min · jiezi

关于spring-boot-编程思想:SpringBoot-生产中-16-条最佳实践

SpringBoot 生产中 16 条最佳实际Spring Boot是最风行的用于开发微服务的Java框架。在本文中,我将与你分享自2016年以来我在业余开发中应用Spring Boot所采纳的最佳实际。这些内容是基于我的集体教训和一些熟知的Spring Boot专家的文章。在本文中,我将重点介绍Spring Boot特有的实际(大多数时候,也实用于Spring我的项目)。以下依**次列出了最佳实际,排名不分先后。 1、应用自定义BOM来保护第三方依赖**这条实际是我依据理论我的项目中的经验总结出的。Spring Boot我的项目自身应用和集成了大量的开源我的项目,它帮忙咱们保护了这些第三方依赖。然而也有一部分在理论我的项目应用中并没有包含进来,这就须要咱们在我的项目中本人保护版本。如果在一个大型的我的项目中,包含了很多未开发模块,那么保护起来就十分的繁琐。怎么办呢?事实上,Spring IO Platform就是做的这个事件,它自身就是Spring Boot的子项目,同时保护了其余第三方开源库。咱们能够借鉴Spring IO Platform来编写本人的根底我的项目platform-bom,所有的业务模块我的项目应该以BOM的形式引入。这样在降级第三方依赖时,就只须要降级这一个依赖的版本而已。 <dependencyManagement>    <dependencies>        <dependency>            <groupId>io.spring.platform</groupId>            <artifactId>platform-bom</artifactId>            <version>Cairo-SR3</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement>复制代码 \ 2、应用主动配置Spring Boot的一个次要个性是应用主动配置。这是Spring Boot的一部分,它能够简化你的代码并使之工作。当在类门路上检测到特定的jar文件时,主动配置就会被激活。应用它的最简略办法是依赖Spring Boot Starters。因而,如果你想与Redis进行集成,你能够首先包含: <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-redis</artifactId></dependency>复制代码如果你想与MongoDB进行集成,须要这样: <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>复制代码借助于这些starters,这些繁琐的配置就能够很好地集成起来并协同工作,而且它们都是通过测试和验证的。这十分有助于防止可怕的Jar天堂。 `dzone.com/articles/wh…`通过应用以下注解属性,能够从主动配置中排除某些配置类: @EnableAutoConfiguration(exclude = {ClassNotToAutoconfigure.class})  复制代码但只有在相对必要时才应该这样做。无关主动配置的官网文档可在此处找到: `docs.spring.io/spring-boot…` 3、应用Spring Initializr来开始一个新的Spring Boot我的项目这一条最佳实际来自Josh Long (Spring Advocate,@starbuxman)。 Spring Initializr 提供了一个超级简略的办法来创立一个新的Spring Boot我的项目,并依据你的须要来加载可能应用到的依赖。 应用Initializr创立应用程序可确保你取得通过测试和验证的依赖项,这些依赖项实用于Spring主动配置。你甚至可能会发现一些新的集成,但你可能并没有意识到这些。 4、思考为常见的组织问题创立本人的主动配置这一条也来自Josh Long(Spring Advocate,@starbuxman)——这个实际是针对高级用户的。如果你在一个重大依赖Spring Boot的公司或团队中工作,并且有独特的问题须要解决,那么你能够创立本人的主动配置。这项工作波及较多工作,因而你须要思考何时获益是值得投入的。与多个略有不同的定制配置相比,保护单个主动配置更容易。如果将这个提供Spring Boot配置以开源库的模式公布进来,那么将极大地简化数千个用户的配置工作。 5、正确设计代码目录构造只管容许你有很大的自在,然而有一些根本规定值得恪守来设计你的源代码构造。防止应用默认包。确保所有内容(包含你的入口点)都位于一个名称很好的包中,这样就能够防止与拆卸和组件扫描相干的意外状况;将Application.java(利用的入口类)保留在顶级源代码目录中;我倡议将控制器和服务放在以性能为导向的模块中,但这是可选的。一些十分好的开发人员倡议将所有控制器放在一起。不论怎样,保持一种格调! 6、放弃@Controller的简洁和专一Controller应该非常简单。你能够在此处浏览无关GRASP中无关控制器模式局部的阐明。你心愿控制器作为协调和委派的角色,而不是执行理论的业务逻辑。以下是次要做法: en.wikipedia.org/wiki/GRASP(… 1、控制器应该是无状态的!默认状况下,控制器是单例,并且任何状态都可能导致大量问题;2、控制器不应该执行业务逻辑,而是依赖委托;3、控制器应该解决应用程序的HTTP层,这不应该传递给服务;4、控制器应该围绕用例/业务能力来设计。要深刻这个内容,须要进一步地理解设计REST API的最佳实际。无论你是否想要应用Spring Boot,都是值得学习的。 7、围绕业务性能构建@ServiceService是Spring Boot的另一个外围概念。我发现最好围绕业务性能/畛域/用例(无论你怎么称说都行)来构建服务。在利用中设计名称相似 AccountService, UserService, PaymentService这样的服务,比起像 DatabaseService、 ValidationService、 CalculationService这样的会更适合一些。你能够决定应用Controler和Service之间的一对一映射,那将是现实的状况。但这并不意味着,Service之间不能相互调用! 8、使数据库独立于外围业务逻辑之外我之前还不确定如何在Spring Boot中最好地解决数据库交互。在浏览了罗伯特·C·马丁的“Clear Architecture”之后,对我来说就清晰多了。你心愿你的数据库逻辑于服务分离出来。现实状况下,你不心愿服务晓得它正在与哪个数据库通信,这须要一些形象来封装对象的持久性。 罗伯特C.马丁强烈地阐明,你的数据库是一个“细节”,这意味着不将你的应用程序与特定数据库耦合。过来很少有人会切换数据库,我留神到,应用Spring Boot和古代微服务开发会让事件变得更快。 9、放弃业务逻辑不受Spring Boot代码的影响思考到“Clear Architecture”的教训,你还应该爱护你的业务逻辑。将各种Spring Boot代码混合在一起是十分迷人的……不要这样做。如果你能抵制引诱,你将放弃你的业务逻辑可重用。局部服务通常成为库。如果不从代码中删除大量Spring注解,则更容易创立。 10、举荐应用构造函数注入这一条实际来自Phil Webb(Spring Boot的我的项目负责人, @phillip_webb)。放弃业务逻辑免受Spring Boot代码侵入的一种办法是应用构造函数注入。不仅是因为 @Autowired注解在构造函数上是可选的,而且还能够在没有Spring的状况下轻松实例化bean。 11、相熟并发模型我写过的最受欢迎的文章之一是“介绍Spring Boot中的并发”。我认为这样做的起因是这个畛域常常被误会和漠视。如果使用不当,就会呈现问题。 在Spring Boot中,Controller和Service是默认是单例。如果你不小心,这会引入可能的并发问题。你通常也在解决无限的线程池。请相熟这些概念。如果你正在应用新的WebFlux格调的Spring Boot应用程序,我曾经解释了它在“Spring’s WebFlux/Reactor Parallelism and Backpressure”中是如何工作的。 ...

April 5, 2022 · 1 min · jiezi

关于spring-boot-编程思想:HBaseSpring-Boot实战分布式文件存储

download:HBase+Spring Boot实战分布式文件存储复制下崽:https://www.zxit666.com/3899/一、v-show 和 v-if 的区别在 vue 中 v-show 和 v-if 都能够管制元素是否在页面中事实 v-show 的显示暗藏是操作元素css的 display 属性,所以应用 v-show 来暗藏元素的时候,元素的 dom 节点仍旧还在页面中;v-if 的显示暗藏则是将 dom 元素整个增加或删除 v-if 的切换有一个部分编译/卸载的过程,切换过程中适合地销毁和重建外部的事件监听和子组件;v-show 只是简略的操作css的 display 属性 v-if 是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染 v-show 由 false 变为 true 的时候不会触发组件的生命周期,v-if 由 false 变为 true的时候,触发组件的 beforeCreate 、 create 、 beforeMount 、 mounted 生命周期钩子,由 true 变为 false 的时候触发组件的 beforeDestory 、destoryed 办法 在性能耗费方面 v-if 有更高的切换耗费; v-show 有更高的初始渲染耗费 二、v-show 和 v-if 应用场景v-if 与 v-show 都能管制 dom 元素在页面的显示和暗藏 v-if 相比 v-show 开销更大的(间接操作 dom 节点减少与删除),如果须要十分频繁地切换,则应用 v-show 较好,如果在运行时条件很少扭转,则应用 v-if 较好 ...

March 27, 2022 · 2 min · jiezi

关于spring-boot-编程思想:Spring-Boot-发布定时任务的一些小技巧

1. ElasticJob1.1 简介ElasticJob 是一个分布式作业调度解决方案,它的官网是: Elastic Job 的前身是由当当开源的一款分布式任务调度框架 dd-job,不过在 2020 年 5 月 28 日退出到了 Apache 基金会,成为 Apache 下的一个开源我的项目: ElasticJob 通过弹性调度、资源管控、以及作业治理的性能,打造一个实用于互联网场景的散布式调度解决方案,并通过凋谢的架构设计,提供多元化的作业生态。 应用 ElasticJob 可能让开发工程师不再放心工作的线性吞吐量晋升等非功能需求,使他们可能更加专一于面向业务编码设计;同时,它也可能解放运维工程师,使他们不用再放心工作的可用性和相干治理需要,只通过轻松的减少服务节点即可达到自动化运维的目标。 ElasticJob 是面向互联网生态和海量工作的散布式调度解决方案,由两个互相独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成。 其中 ElasticJob-Lite 定位为轻量级无中心化解决方案,应用 jar 的模式提供分布式工作的协调服务: 1.2 性能列表弹性调度 反对工作在分布式场景下的分片和高可用可能程度扩大工作的吞吐量和执行效率工作解决能力随资源装备弹性伸缩资源分配 在适宜的工夫将适宜的资源分配给工作并使其失效雷同工作聚合至雷同的执行器对立解决动静调配追加资源至新调配的工作作业治理 生效转移错过作业重新执行自诊断修复作业依赖(TODO) 基于有向无环图(DAG)的作业间依赖基于有向无环图(DAG)的作业分片间依赖

March 16, 2022 · 1 min · jiezi

关于spring-boot-编程思想:Spring-Boot-五种热部署方式

模板热部署在 Spring Boot 中,模板引擎的页面默认是开启缓存的,如果批改了页面的内容,则刷新页面是得不到批改后的页面的,因而咱们能够在application.properties中敞开模版引擎的缓存,如下:Thymeleaf的配置: spring.thymeleaf.cache=false FreeMarker的配置: spring.freemarker.cache=false Groovy的配置: spring.groovy.template.cache=false Velocity的配置: spring.velocity.cache=false 2、应用调试模式Debug实现热部署此种形式为最简略最疾速的一种热部署形式,运行零碎时应用Debug模式,无需装任何插件即可,java培训然而无发对配置文件,办法名称扭转,减少类及办法进行热部署,应用范畴无限。 3、spring-boot-devtools在 Spring Boot 我的项目中增加 spring-boot-devtools依赖即可实现页面和代码的热部署。 如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId></dependency>此种形式的特点是作用范围广,零碎的任何变动包含配置文件批改、办法名称变动都能笼罩,然而后遗症也非常明显,它是采纳文件变动后重启的策略来实现了,次要是节俭了咱们手动点击重启的工夫,进步了实效性,在体验上回稍差。spring-boot-devtools 默认敞开了模版缓存,如果应用这种形式不必独自配置敞开模版缓存。 4、Spring Loaded此种形式与Debug模式相似,适用范围无限,然而不依赖于Debug模式启动,通过Spring Loaded库文件启动,即可在失常模式下进行实时热部署。此种须要在 run confrgration 中进行配置。 5、JRebelJrebel是Java开发最好的热部署工具,对 Spring Boot 提供了极佳的反对,JRebel为免费软件,试用期14天。,可间接通过插件装置。

January 14, 2022 · 1 min · jiezi

关于spring-boot-编程思想:SQL查找是否存在别再count了

依据某一条件从数据库表中查问 『有』与『没有』,只有两种状态,那为什么在写SQL的时候,还要SELECT count(*) 呢? 无论是刚入道的程序员新星,还是精湛疆场多年的程序员老白,都是判若两人的count 目前少数人的写法屡次REVIEW代码时,发现如现景象: 业务代码中,须要依据一个或多个条件,查问是否存在记录,不关怀有多少条记录。广泛的SQL及代码写法如下 #### SQL写法:SELECT count(*) FROM table WHERE a = 1 AND b = 2#### Java写法:int nums = xxDao.countXxxxByXxx(params);if ( nums > 0 ) { //当存在时,执行这里的代码} else { //当不存在时,执行这里的代码}是不是感觉很OK,没有什么问题 举荐下本人看的 Spring Boot 书籍: https://docs.qq.com/doc/DQ05qV0xDdGNoRU16 优化计划举荐写法如下: #### SQL写法:SELECT 1 FROM table WHERE a = 1 AND b = 2 LIMIT 1#### Java写法:Integer exist = xxDao.existXxxxByXxx(params);if ( exist != NULL ) { //当存在时,执行这里的代码} else { //当不存在时,执行这里的代码}SQL不再应用count,而是改用LIMIT 1,让数据库查问时遇到一条就返回,不要再持续查找还有多少条了 ...

November 29, 2021 · 1 min · jiezi

关于spring-boot-编程思想:Spring-Boot-Vue3-前后端分离-实战wiki知识库系统

download:Spring Boot + Vue3 前后端拆散 实战wiki知识库零碎咱们在上一篇初步尝试了keycloak,手动建设了一个名为felord.cn的realm并在该realm下建了一个名为felord的用户。明天就来尝试一下对应的Spring Boot Adapter,来看看keycloak是如何爱护Spring Boot利用的。 关注并星标 码农小胖哥,第一工夫获取相干干货文章。 客户端置信不少同学用过微信开放平台、蚂蚁开放平台。首先咱们须要在这些开放平台上注册一个客户端以获取一套相似用户名和明码的凭证。有的叫appid和secret;有的叫clientid和secret,都是一个意思。其实keycloak也差不多,也须要在对应的realm中注册一个客户端。下图不仅仅清晰地阐明了keycloak中Masterrealm和自定义realm的关系,还阐明了在一个realm中用户和客户端的关系。

August 30, 2021 · 1 min · jiezi

关于spring-boot-编程思想:Spring-Boot-Vue3-前后端分离-实战wiki知识库系统资源分享

download:Spring Boot + Vue3 前后端拆散 实战wiki知识库零碎package whu.extract.pubtime.core; import java.util.ArrayList;import java.util.Calendar;import java.util.Collections;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern; import whu.utils.TimeUtil; /** Created On 2014年3月13日 下午2:49:05@description 获取网页的公布工夫 */public class FetchPubTime { /** 示意url中间断的8位日期,例如http://www.baidu.com/20140311/2356.html */private static String url_reg_whole= "([-|/|_]{1}20\\d{6})";/** 示意 用-或者/隔开的日期,有年月日的,例如 http://www.baidu.com/2014-3-11/2356.html */private static String url_reg_sep_ymd = "([-|/|_]{1}20\\d{2}[-|/|_]{1}\\d{1,2}[-|/|_]{1}\\d{1,2})";/** 示意 用-或者/隔开的日期,只有年和月份的,例如 http://www.baidu.com/2014-3/2356.html */private static String url_reg_sep_ym = "([-|/|_]{1}20\\d{2}[-|/|_]{1}\\d{1,2})";private static Calendar current = Calendar.getInstance();/** 格局正确的工夫正则表达式*/private static String rightTimeReg = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"; /** * @param url * @param urlContent * @return */public static String getPubTimeVarious(String url,String urlContent) { String pubTime = getPubTimeFromUrl(url); //链接外面没有,匹配文本中的 if(pubTime == null) { if(urlContent!=null&&!urlContent.trim().equals("")) return extractPageDate(urlContent); } return pubTime;} /**从url外面抽取出公布工夫,返回YYYY-MM-DD HH:mm:ss格局的字符串 * @param url * @return */public static String getPubTimeFromUrl(String url){ Pattern p_whole = Pattern.compile(url_reg_whole); Matcher m_whole = p_whole.matcher(url); if(m_whole.find(0)&&m_whole.groupCount()>0) { String time = m_whole.group(0); time = time.substring(1,time.length()); //每一步都不可能超出以后工夫 if(current.compareTo(TimeUtil.strToCalendar(time, "yyyyMMdd"))>=0) { return time.substring(0,4)+"-"+time.substring(4,6)+"-"+ time.substring(6,8)+" "+"00:00:00"; } } p_whole = null; m_whole = null; Pattern p_sep = Pattern.compile(url_reg_sep_ymd); Matcher m_sep = p_sep.matcher(url); if(m_sep.find(0)&&m_sep.groupCount()>0) { String time = m_sep.group(0); time = time.substring(1,time.length()); String[] seg = time.split("[-|/|_]{1}"); Calendar theTime = Calendar.getInstance(); theTime.set(Calendar.YEAR,Integer.parseInt(seg[0])); theTime.set(Calendar.MONTH, Integer.parseInt(seg[1])); theTime.set(Calendar.DAY_OF_MONTH, Integer.parseInt(seg[2])); if(current.compareTo(theTime)>=0) { return seg[0]+"-"+seg[1]+"-"+seg[2]+" "+"00:00:00"; } } p_sep = null; m_sep = null; Pattern p_sep_ym = Pattern.compile(url_reg_sep_ym); Matcher m_sep_ym = p_sep_ym.matcher(url); if(m_sep_ym.find(0)&&m_sep_ym.groupCount()>0) { String time = m_sep_ym.group(0); time = time.substring(1,time.length()); Calendar theTime = Calendar.getInstance(); String[] seg = time.split("[-|/|_]{1}"); theTime.set(Calendar.YEAR,Integer.parseInt(seg[0])); theTime.set(Calendar.MONTH, Integer.parseInt(seg[1])); theTime.set(Calendar.DAY_OF_MONTH, 1); if(current.compareTo(theTime)>=0) { return seg[0]+"-"+seg[1]+"-"+"01"+" "+"00:00:00"; } } return null;}

August 7, 2021 · 2 min · jiezi

关于spring-boot-编程思想:新版-Spring-Boot双版本1521-打造企业级微信点餐系统

download:新版 Spring Boot双版本(1.5/2.1) 打造企业级微信点餐零碎* To change this license header, choose License Headers in Project Properties.To change this template file, choose Tools | Templatesand open the template in the editor. */package datei.steuern; import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.List;import java.util.logging.Level;import java.util.logging.Logger; /** * @author s.watson */public class FileTools { public FileTools() { } /** formatPath 本义文件目录 *@param path@return */public static String formatPath(String path) { ...

August 5, 2021 · 6 min · jiezi

关于spring-boot-编程思想:使用-rocketmqspringbootstarter-来配置发送和消费-RocketMQ-消息

简介:本文将 rocktmq-spring-boot 的设计实现做一个简略的介绍,读者能够通过本文理解将 RocketMQ Client 端集成为 spring-boot-starter 框架的开发细节,而后通过一个简略的示例来一步一步的解说如何应用这个 spring-boot-starter 工具包来配置,发送和生产 RocketMQ 音讯。 作者 | 辽天起源 | 阿里巴巴云原生公众号 导读:本文将 rocktmq-spring-boot 的设计实现做一个简略的介绍,读者能够通过本文理解将 RocketMQ Client 端集成为 spring-boot-starter 框架的开发细节,而后通过一个简略的示例来一步一步的解说如何应用这个 spring-boot-starter 工具包来配置,发送和生产 RocketMQ 音讯。 在 Spring 生态中玩转 RocketMQ 系列文章: 《如何在 Spring 生态中玩转 RocketMQ?》《罗美琪和春波特的故事...》《RocketMQ-Spring 毕业两周年,为什么能成为 Spring 生态中最受欢迎的 messaging 实现?》本文配套可交互教程已登录阿里云知口头手实验室,PC 端登录 start.aliyun.com 在浏览器中立刻体验。 通过本文,您将理解到: Spring 的音讯框架介绍rocketmq-spring-boot 具体实现应用示例 前言 上世纪 90 年代末,随着 Java EE(Enterprise Edition) 的呈现,特地是 Enterprise Java Beans 的应用须要简单的描述符配置和死板简单的代码实现,减少了宽广开发者的学习曲线和开发成本,由此基于简略的 XML 配置和一般 Java 对象(Plain Old Java Objects)的 Spring 技术应运而生,依赖注入(Dependency Injection), 管制反转(Inversion of Control)和面向切面编程(AOP)的技术更加敏捷地解决了传统 Java 企业及版本的有余。 ...

April 26, 2021 · 3 min · jiezi

关于spring-boot-编程思想:SpringBoot-2x系列Spring-JDBC

JDBC介绍 从这篇文章开始,咱们将会介绍SpringBoot另外一个外围的技术,即数据库拜访技术,提到数据拜访,学习Java的同学霎时能就想起JDBC技术,JDBC 是 Java Database Connectivity 的全称,是Java语言中用来标准客户端程序如何来拜访数据库的利用程序接口,提供了诸如查问和更新数据库中数据的一套规范的API,这套规范不同的数据库厂家之间独特准守,并提供各自的具体实现。如图所示: http://img.mukewang.com/5ffeb... 这样设计的益处,就是Java程序只须要和JDBC API交互,从而屏蔽了拜访数据库的简单的实现,大大降低了Java程序拜访数据库的复杂度。对于日常开发而言,咱们只须要把握JDBC API 标准中的几个外围编程对象即可,这些对象包含DriverManger、Connection、Statement及ResultSet。DriverManager DriverManager次要负责加载不同数据库厂家提供的驱动程序包(Driver),并且依据不同的申请向Java程序返回数据库连贯(Connection)对象,先看下Driver接口的定义: public interface Driver { //获取数据库连贯 Connection connect(String url, java.util.Properties info) throws SQLException;boolean acceptsURL(String url) throws SQLException;DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info) throws SQLException;int getMajorVersion();int getMinorVersion();boolean jdbcCompliant();public Logger getParentLogger() throws SQLFeatureNotSupportedException;}复制代码 Driver中有个重要的办法 connect,来提供Connection对象 不同的数据库对Driver,有具体的实现,以MySql为例: public class Driver extends NonRegisteringDriver implements java.sql.Driver { // 通过 DriverManager 注册 Driver static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); }}…}复制代码 ...

January 13, 2021 · 4 min · jiezi

关于spring-boot-编程思想:使用easyexcel-导入excel表格

应用easyexcel 导入excel表格1. 增加依赖pom.xml<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.7</version></dependency>2. 创立接管的实体类import lombok.Data;@Datapublic class StaffExcelRequest { /** * * 员工姓名 */ private String name; /** * * 工号 */ private String jobNumber; /** * * 职位名称 */ private String jobTitle; /** * * 手机号 */ private String mobile;}3. 创立监听事件public class ExcelListener extends AnalysisEventListener<StaffExcelRequest> { private static final Logger LOGGER = LoggerFactory.getLogger(ExcelListener.class); /** * 存储验证通过的数据 */ @Getter private List<StaffExcelRequest> list = new ArrayList<>(); /** * 假如这个是一个DAO,当然有业务逻辑这个也能够是一个service。当然如果不必存储这个对象没用。 */ private StaffService staffService; /** * 返回谬误 */ @Setter @Getter private List<Map<String,String>> maps = new ArrayList<Map<String,String>>(); private Map<String,String> map = new HashMap<>(); /** * 头部占用的行数 */ @Setter public Integer headerInteger = 1; public ExcelListener() { // 这里是demo,所以轻易new一个。理论应用如果到了spring,请应用上面的有参构造函数 } /** * 如果应用了spring,请应用这个构造方法。每次创立Listener的时候须要把spring治理的类传进来 * * @param staffService */ public ExcelListener(StaffService staffService) { this.staffService = staffService; } /** * 这个每一条数据解析都会来调用 * * @param data * one row value. Is is same as {@link AnalysisContext#readRowHolder()} * @param context */ @Override public void invoke(StaffExcelRequest data, AnalysisContext context) { // 开始计数,以后是多少行 headerInteger++; if (data.getName() == null || data.getName().equals("")) { map.put("code","400"); map.put("msg","第["+headerInteger+"]行,员工姓名不能为空"); maps.add(map); return; } if (data.getJobNumber() == null || data.getJobNumber().equals("")) { map.put("code","400"); map.put("msg","第["+headerInteger+"]行,员工工号不能为空"); maps.add(map); return; } LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data)); list.add(data); } /** * 所有数据解析实现了 都会来调用 * * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保留数据,确保最初遗留的数据也存储到数据库 saveData(); LOGGER.info("所有数据解析实现!"); } /** * 加上存储数据库 */ private void saveData() { LOGGER.info("{}条数据,开始存储数据库!", list.size()); List<Staff> staffCollection = new ArrayList<>(); for (StaffExcelRequest request : list) { // 创立实体类,用于保留数据 Staff entity = new Staff(); staff.setName(request.getName()); staffCollection.add(entity); } boolean b = staffService.saveBatch(staffCollection); LOGGER.info("存储数据库胜利!"+b); }}4. 创立controller@PostMapping("/import")// @RequiresPermissions("staff:import")public BaseResultData importExcel(@RequestParam("file") MultipartFile file) throws IOException { // 解决上传文件 if (file.isEmpty()) { return BaseResultData.ERROR(1,"上传失败,请抉择文件"); } // 流导入 InputStream inputStream = file.getInputStream(); // 监听器 ExcelListener listener = new ExcelListener(staffService); // 读取excel EasyExcel.read(inputStream, StaffExcelRequest.class,listener).sheet().doRead(); // 查看是否有异样 List<Map<String, String>> maps = listener.getMaps(); String temp = ""; if (maps.size() > 0) { for (Map<String, String> map : maps) { temp += map.get("msg")+"\n"; } } // 返回信息 HashMap<String, String> hashMap = new HashMap<>(); hashMap.put("success",listener.getList().size()+""); hashMap.put("error",temp); return BaseResultData.SUCCESS(hashMap);}

December 8, 2020 · 2 min · jiezi

关于spring-boot-编程思想:从零搭建Spring-Boot的Hello-World

场景介绍本教程将应用IntelliJ IDEA搭建一个简略Spring Boot我的项目,并将这个我的项目部署到阿里云服务器ECS上。 背景常识背景常识Spring BootSpring Boot是近几年十分风行的一款微服务框架,具备简化配置、疾速搭建、内嵌Tomcat或Jetty容器的特点,让开发人员专一于业务实现,基于Maven或Gradle插件创立可执行的JARs和WARs。 云服务器ECS云服务器(Elastic Compute Service,简称ECS)是阿里云提供的性能卓越、稳固牢靠、弹性扩大的IaaS(Infrastructure as a Service)级别云计算服务。云服务器ECS免去了您洽购IT硬件的后期筹备,让您像应用水、电、天然气等公共资源一样便捷、高效地应用服务器,实现计算资源的即开即用和弹性伸缩。阿里云ECS继续提供创新型服务器,解决多种业务需要,助力您的业务倒退。 步骤一:创立资源(未开明ECS)1.在[阿里云从零搭建Spring Boot的Hello World体验场景]处(https://developer.aliyun.com/... 开始体验开明资源后,查看本次试验资源。 2.单击 收费开明 创立所需资源。 步骤二:装置Java开发环境1.下载并装置JDK8,下载地址参见Java SE 8u261。 2.配置Java环境变量。 a. 关上命令窗口,执行以下命令。阐明:执行命令前,请批改JAVA_HOME参数C:\Program Files\Java\jdk1.8.0_211为您的JDK装置目录。执行后果如下。 b.执行以下命令,验证环境变量配置是否胜利。java -version执行后果如下。 步骤三:装置并配置IntelliJ IDEA此步骤次要介绍应用IntelliJ IDEA装置Spring Assistant插件。1.下载并装置IntelliJ IDEA,下载地址参见 IntelliJ IDEA。2.双击运行IntelliJ IDEA。3.在IntelliJ IDEA启动界面,顺次单击 Configure > Settings 。4.单击 Plugins,而后在搜寻栏输出spring Assistant。最初单击 Install 装置插件。5.单击 Restart IDE。 步骤四:创立Spring Boot我的项目本步骤次要介绍应用Spring Assistant插件来搭建简略的Spring Boot我的项目。1.在IntelliJ IDEA启动界面,单击 Create New Project。2.在左侧单击 Spring Assistant,而后单击 Next。 步骤五:打包并上传我的项目到ECS服务器1.打包我的项目。 a. 单击IDEA右上角Maven。 b. 顺次双击 demo>Lifecycle>package,开始打包。执行后果如下,图中标记地位为打包后jar包的门路。2.关上终端工具。 Windows:关上命令窗口。MAC:关上命令行终端Terminal。Windows用户请查看零碎中是否装置有SSH工具。查看办法: a. 在终端中输出命令ssh -V。ssh -V如果显示SSH版本则示意已装置,如下图所示。 ...

November 16, 2020 · 1 min · jiezi

关于spring-boot-编程思想:使用Spring-Boot创建docker-image

简介在很久很久以前,咱们是怎么创立Spring Boot的docker image呢?最最通用的方法就是将Spring boot的应用程序打包成一个fat jar,而后写一个docker file,将这个fat jar制作成为一个docker image而后运行。 明天咱们来体验一下Spring Boot 2.3.3 带来的疾速创立docker image的性能。 传统做法和它的毛病当初咱们创立一个非常简单的Spring Boot程序: @SpringBootApplication@RestControllerpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @GetMapping("/getInfo") public String getInfo() { return "www.flydean.com"; }}默认状况下,咱们build进去的是一个fat jar:springboot-with-docker-0.0.1-SNAPSHOT.jar 咱们解压看一下它的内容: Spring boot的fat jar分为三个局部,第一局部就是BOOT-INF, 外面的class目录放的是咱们本人编写的class文件。而lib目录寄存的是我的项目依赖的其余jar包。 第二局部是META-INF,外面定义了jar包的属性信息。 第三局部是Spring Boot的类加载器,fat jar包的启动是通过Spring Boot的jarLauncher来创立LaunchedURLClassLoader,通过它来加载lib上面的jar包,最初以一个新线程启动利用的Main函数。 这里不多讲Spring Boot的启动。 咱们看一下,如果想要用这个fat jar来创立docker image应该怎么写: FROM openjdk:8-jdk-alpineEXPOSE 8080ARG JAR_FILE=target/springboot-with-docker-0.0.1-SNAPSHOT.jarADD ${JAR_FILE} app.jarENTRYPOINT ["java","-jar","/app.jar"]这样写有两个问题。 第一个问题:咱们是用的far jar,在应用far jar的过程中会有肯定的性能问题,必定要比解压过后的性能要低,尤其是在容器环境中运行的状况下,可能会更加突出。 第二个问题:咱们晓得docker的image是按layer来构建的,按layer构建的益处就是能够缩小image构建的工夫和重用之前的layer。 然而如果应用的是fat jar包,即便咱们只批改了咱们本人的代码,也会导致整个fat jar从新更新,从而影响docker image的构建速度。 ...

October 16, 2020 · 2 min · jiezi

关于spring-boot-编程思想:Spring-Boot-Spring-MVC-Spring的区别

背景:明天刚学习了Spring Boot,总结一下明天学习的常识以及后面相干的常识. 什么是Spring Boot ?1.是简化代码,进步代码复用性,总结来的利用的初始搭建以及开发过程,应用了一些高效的形式进行配置(properties和yml文件,先后顺序加载) 创立独立的Spring援用程序main办法启动,嵌入Tomcat不必war文件,简化maven配置,主动配置Spring增加对应的性能starter自动化配置. Spring Boot,Spring MVC,Spring 的区别?1.Spring Boot次要的特色是依赖注入.所有的模块不是依赖注入就是IOC管制翻转.当咱们失当的应用DI和IOC时,就能够开发松耦合. 利用松耦合能够更容易单元测试.2.Spring MVC提供了一种分离式办法来开发Web利用.通过使用像 DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简略的概念,开发 Web 利用将会变的非常简单。3.Spring和Spring MVC的问题是须要配置端详的参数.4.Spring Boot通过一个主动配置和启动的项来解决目前的问题.为跟快的构建我的项目就绪应用程序,Spring Boot提供了一些非功能性特色. Spring Boot的外围注解1.@SpringBootConfiguration : 组合了@Configuration 注解,实现配置文件的性能.2.@EnableAutoConfiguration:关上主动配置性能,也能够敞开某个主动配置的选项,如敞开数据主动配置性能.3.3、@ComponentScan:Spring组件扫描。 springboot罕用的starter有哪些?1、spring-boot-starter-web (嵌入tomcat和web开发须要servlet与jsp反对)2、spring-boot-starter-data-jpa (数据库反对)3、spring-boot-starter-data-redis (redis数据库反对)4、spring-boot-starter-data-solr (solr搜寻利用框架反对)5、mybatis-spring-boot-starter (第三方的mybatis集成starter) Spring Boot 配置加载程序?1、properties文件2、YAML文件3、零碎环境变量4、命令行参数 Spring Boot 有哪几种读取配置的形式?@PropertySource@Value@Environment@ConfigurationPropertie如何应用Spring Boot实现异样解决?SpringControllerAdvice提供了一种应用解决异样的十分有用的办法。通过实现一个 ControllerAdvice类,来解决控制器类抛出的所有异样。 残余的前期再补充吧!

September 27, 2020 · 1 min · jiezi

关于spring-boot-编程思想:Spring-Boot-教程Eureka-服务器

【注】本文译自: https://www.tutorialspoint.com/spring_boot/spring_boot_eureka_server.htm Eureka 服务器是一个利用,它蕴含所有客户端服务利用的信息。每个微服务都会注册到 Eureka 服务器并且 Eureka 服务器晓得所有客户端利用的端口和 IP 地址。Eureka 服务器也被称为发现服务器。 本文将带你学习如何搭建 Eureka 服务器。搭建 Eureka 服务器 Eureka 服务器与 Spring Cloud 打包公布。基于此,咱们须要开发 Eureka 服务器并将它运行于缺省的 8761 端口上。 拜访 Spring 初始化器主页 https://start.spring.io/ 并下载 Spring Boot 工程的 Eureka 服务器依赖。如下图所示: 工程下载之后,在主 Spring Boot 利用类文件中,咱们要加上 @EnableEurekaServer 注解。@EnableEurekaServer 注解可使你的 Spring Boot 利用用作 Eureka 服务器。 主 Spring Boot 利用类文件如下所示: package com.tutorialspoint.eurekaserver;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServerpublic class EurekaserverApplication { public static void main(String[] args) { SpringApplication.run(EurekaserverApplication.class, args); }} 确保你的构建配置文件中曾经退出了 Spring cloud Eureka 服务器依赖。 Maven 用户的依赖代码如下: ...

September 27, 2020 · 2 min · jiezi

关于spring-boot-编程思想:搭建-Restful-Web-服务

1. 了解 REST REST 全称是 Representational State Transfer,中文意思是表征性状态转移。它首次呈现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP标准的次要编写者之一。值得注意的是REST并没有一个明确的规范,而更像是一种设计的格调。如果一个架构合乎REST的约束条件和准则,咱们就称它为RESTful架构。 实践上REST架构格调并不是绑定在HTTP上,只不过目前HTTP是惟一与REST相干的实例。 1.1. REST 准则资源 可通过目录构造款式的 URIs 裸露表述 能够通过 JSON 或 XML 表白的数据对象或属性来传递音讯 应用对立的 HTTP 办法(例如:GET、POST、PUT 和 DELETE)无状态 客户端与服务端之间的交互在申请之间是无状态的,从客户端到服务端的每个申请都必须蕴含了解申请所必须的信息1.2. HTTP 办法 应用 HTTP 将 CRUD(create, retrieve, update, delete <创立、获取、更新、删除—增删改查>)操作映射为 HTTP 申请。如果依照HTTP办法的语义来裸露资源,那么接口将会领有安全性和幂等性的个性,例如GET和HEAD申请都是平安的, 无论申请多少次,都不会扭转服务器状态。而GET、HEAD、PUT和DELETE申请都是幂等的,无论对资源操作多少次, 后果总是一样的,前面的申请并不会产生比第一次更多的影响。 1.2.1. GET平安且幂等获取信息1.2.2. POST不平安且不幂等应用申请中提供的实体执行操作,可用于创立资源或更新资源1.2.3. PUT不平安但幂等应用申请中提供的实体执行操作,可用于创立资源或更新资源1.2.4. DELETE不平安但幂等删除资源 POST和PUT在创立资源的区别在于,所创立的资源的名称(URI)是否由客户端决定。 例如为我的博文减少一个java的分类,生成的门路就是分类名/categories/java,那么就能够采纳PUT办法。不过很多人间接把POST、GET、PUT、DELETE间接对应上CRUD,例如在一个典型的rails实现的RESTful利用中就是这么做的。 1.3. HTTP status codes 状态码批示 HTTP 申请的后果: 1XX:信息2XX:胜利3XX:转发4XX:客户端谬误5XX:服务端谬误1.4. 媒体类型 HTTP头中的 Accept 和 Content-Type 可用于形容HTTP申请中发送或申请的内容。如果客户端申请JSON响应,那么能够将 Accept 设为 application/json。相应地,如果发送的内容是XML,那么能够设置 Content-Type 为 application/xml 。 ...

September 27, 2020 · 3 min · jiezi

关于spring-boot-编程思想:Spring-Boot-demo系列七邮件服务

1 概述Spring Boot整合邮件服务,包含发送一般的文本邮件以及带附件的邮件。 2 邮箱抉择这里抉择的是QQ邮箱作为发送的邮箱,当然也能够抉择其余的邮箱,只是具体的配置不一样。 应用QQ邮箱的话,须要在集体设置中开启SMTP服务: 发送短信后实现验证即可,会有一个受权码,先复制下来保留。 3 具体实现3.1 依赖提供了starter: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency>gradle: implementation 'org.springframework.boot:spring-boot-starter-mail'3.2 邮件接口只有两个简略的接口,一个是发送纯文本的,一个是发送带附件的: public interface MailService { void sendSimpleMail(String to,String subject,String content); void sendAttachmentMail(String to, String subject, String content, Path file) throws MessagingException;}3.3 接口实现@Service@RequiredArgsConstructor(onConstructor = @__(@Autowired))public class MailServiceImpl implements MailService{ private final JavaMailSender sender; @Value("${spring.mail.username}") private String from; @Override public void sendSimpleMail(String to, String subject, String content) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(from); message.setTo(to); message.setSubject(subject); message.setText(content); sender.send(message); } @Override public void sendAttachmentMail(String to, String subject, String content, Path file) throws MessagingException { MimeMessage message = sender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message,true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content); helper.addAttachment(file.getFileName().toString(),new FileSystemResource(file)); sender.send(message); }}JavaMailSender是Spring Boot携带的邮件发送接口,注入后能够发送SimpleMailMessage以及MimeMessage类型的信息。 ...

September 18, 2020 · 2 min · jiezi

关于spring-boot-编程思想:Spring-Boot-demo系列五Docker部署

1 概述本文讲述了如何应用Docker部署Spring Boot利用,首先介绍了Docker的装置过程,接着介绍了Docker的一些基础知识,最初讲述了Dockerfile的编写以及部署过程。 2 环境服务器:aarch64 CentOS8JDK:OpenJDK 11Docker:19.03.93 Docker装置(已装置了Docker能够跳过该局部) 因为大部分的教程都是针对x86架构的服务器的,这里笔者的服务器为aarch64架构,因而记录一下Docker的装置过程。 Docker装置办法次要有两种,一种是通过官网的脚本主动装置,一种是通过yum手动装置。 3.1 主动装置curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun或 curl -sSL https://get.daocloud.io/docker | sh默认装置的是最新版本的,x86的个别都能够,但如果呈现像笔者这样的谬误: 表明containerd.io的版本过低,应用yum install containerd.io装置的话: 能够看到是1.2.0版本,并不合乎装置的最低要求,解决这种问题有两个方法: 手动下载rpm包装置装置没那么新版本的Docker因而采纳手动装置的办法,这里抉择的是第一种办法,手动下载rpm包进行装置。 3.2 手动装置3.2.1 下载rpm包能够戳这里下载rpm包: 抉择好版本即可,笔者抉择的是: containerd.io-1.2.13-3.2.el7.aarch64.rpmdocker-ce-19.03.9-3.el7.aarch64.rpmdocker-ce-cli-19.03.9-3.el7.aarch64.rpm3.2.2 装置上传到服务器后,装置即可: yum install \containerd.io-1.2.13-3.2.el7.aarch64.rpm \docker-ce-19.03.9-3.el7.aarch64.rpm \docker-ce-cli-19.03.9-3.el7.aarch64.rpm \-y3.3 测试先开启服务: systemctl start docker版本查看: docker version 运行Hello World: docker run hello-world 4 打包新建一个Demo工程,启动类如下: @SpringBootApplication@RestControllerpublic class DemoApplication { @GetMapping("/test") public String test() { return "success"; } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}接着应用Maven/Gradle打成JAR包: ...

September 15, 2020 · 1 min · jiezi

关于spring-boot-编程思想:SpringBoot-全局异常处理

为什么会有这篇文章前后端拆散零碎,应用SpringBoot搭建后端。心愿申请后果能够依照HttpStatus返回。搜寻了不少对于SpringBoot的全局异样解决,大部分都是返回200,再在音讯体中退出code,感觉这样解决不符合规范,所以有了以下内容。 步骤创立异样类创立全局异样解决异样应用下面创立的异样类抛出代码异样类 BizException该异样类应用最简略构造,仅有状态码和自定义信息,可依据本人须要拓展。 import org.springframework.http.HttpStatus;/** * 错误处理类 */public class BizException extends RuntimeException { private HttpStatus status; private String message; public BizException(HttpStatus status, String message) { super(message); this.status = status; this.message = message; } public BizException(HttpStatus status) { this(status, status.getReasonPhrase()); } public HttpStatus getStatus() { return status; } @Override public String getMessage() { return message; }}全局异样解决 GlobalExceptionHandler该类会依据抛出类型,主动进入对应解决类。 import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;import java.util.HashMap;import java.util.Map;/** * 全局异样解决 */@ControllerAdvicepublic class GlobalExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); @ExceptionHandler(value = BizException.class) @ResponseBody public ResponseEntity<Map<String, Object>> bizExceptionHandler(HttpServletRequest req, BizException e) { Map<String, Object> map = new HashMap<>(); map.put("message", e.getMessage()); return new ResponseEntity<>(map, e.getStatus()); } @ExceptionHandler(value = Exception.class) @ResponseBody public ResponseEntity<Map<String, Object>> exceptionHandler(HttpServletRequest req, Exception e) { Map<String, Object> map = new HashMap<>(); map.put("message", e.getMessage()); return new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR); }}在任意想要的中央抛出BizException异样 ...

September 8, 2020 · 1 min · jiezi

关于spring-boot-编程思想:Spring-Boot快速入门之五构建系统

【注】本文译自:https://www.tutorialspoint.com/spring_boot/spring_boot_build_systems.htm 对于 Spring Boot,抉择构建零碎是一项重要工作。咱们举荐应用 Maven 或 Gradle,因为它们对于依赖治理有良好的反对。Spring对于其余构建零碎反对得不是很好。 依赖治理Spring Boot 团队在每次公布时都提供一反对 Spring Boot 版本的依赖列表。你不须要在构建配置文件中提供依赖的版本。Spring Boot 依据公布主动配置依赖版本。记住你更新 Spring Boot 版本时,会自动更新相干依赖。 留神:如果你想指定依赖的版本,能够在配置文件中指定。然而,Spring Boot 团队强烈推荐没必要指定依赖版本。 Maven 依赖对于 Maven 配置,咱们该当继承 Spring Boot 启动器父项目管理 Spring Boot 启动器依赖。咱们的 pom.xml 如下所示: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> </parent> 咱们利用指定 Spring Boot 父启动器依赖的版本号。之后对于其余启动器依赖,咱们就没必要再指定 Spring Boot 版本号了。示例如下: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> Gradle 依赖咱们能够在 build.gradle 文件中间接引入 Spring Boot 启动器依赖。没必要象Maven 一样指定Spring Boot 父启动器依赖,如下所示: buildscript { ext { springBootVersion = '1.5.8.RELEASE' ...

August 10, 2020 · 1 min · jiezi

关于spring-boot-编程思想:spring-boot综合项目1

软件原型设计html css javascript imagesjavaScript的框架 jquery BootStrap 框架能够兼容所有前端开发框架响应式布局--能够兼容所有设施的布局形式咱们在做后端编程业务的时候,能够间接应用bootstrap去间接的生成前端页面,不须要本人去生成,然而要学会如何去应用零碎架构的剖析与设计如何了解架构设计(所有的架构设计必须以业务为前提)第一:架构模式(cs/bs)第二:单体架构,散布架构,微服务架构第三:部署架构(web服务器,数据库服务器)第四:零碎整体分层架构(基础设施,操作系统,中间件,应用软件,接入层)第五:软件应用的分层架构(体现层,申请解决层,业务层,数据层) 设计思路客户端向服务端发动申请,activity/doFindActivity会作为管制层的办法名,业务层拜访的是具体的对象,不写接口spring boot 我的项目了解首先咱们在排除了前端须要做的页面之后,能够分心做后端业务咱们能够先依据数据库的列表名 去增加咱们的goods属性,通过get post办法去申明属性而后咱们通过.dao层与数据库交互,能够通过注解与数据库进行简略的调用查问,而后并且将后果用list封装接着是service层,定义一个接口类service 将查问到的数据后果用list封装而后通过其实现类,来实现对查问的重写,重写查问这个办法,并且最初返回给 数据层调用这个查询方法最初是管制层通过映射拜访门路,通过service层调用查问的办法,并且将其用list封装,通过model保留到作用域,并且最初传递给页面,

August 5, 2020 · 1 min · jiezi

关于spring-boot-编程思想:spring-boot2

spring boot 整合spring mvc利用MVC是软件工程中的一种软件架构模式,基于此模式把软件系统分为三个根本局部:模型(Model).视图(View).和控制器(Controller)。目标是通过这样的设计使得程序结构更加简洁, 直观,升高问题的复杂度。 基于“高内聚,低耦合” 过滤器是将申请达到管制层之前进行一个筛选 spring mvc是spring框架中基于mvc设计思维实现的一个用于解决web申请的模块。 thymeleaf模板thymeleaf是一个用于web和独立java环境的模板引擎,可能解决html,xml,javascript,css甚至纯文本,能轻易的与spring mvc等web框架进行集成作为web利用的模板引擎,最大的特点就是可能间接在浏览器中关上并且正确的显示模板页面,而不须要启动整个web利用(真正的做到了前后端的拆散)spring mvc的初始配置增加相干的依赖,编辑pom.xml,增加spring web依赖,thymeleaf依赖,d

August 3, 2020 · 1 min · jiezi

关于spring-boot-编程思想:spring-boot2

spring boot 整合spring mvc利用MVC是软件工程中的一种软件架构模式,基于此模式把软件系统分为三个根本局部:模型(Model).视图(View).和控制器(Controller)。目标是通过这样的设计使得程序结构更加简洁, 直观,升高问题的复杂度。 基于“高内聚,低耦合” 过滤器是将申请达到管制层之前进行一个筛选 spring mvc是spring框架中基于mvc设计思维实现的一个用于解决web申请的模块。 thymeleaf模板thymeleaf是一个用于web和独立java环境的模板引擎,可能解决html,xml,javascript,css甚至纯文本,能轻易的与spring mvc等web框架进行集成作为web利用的模板引擎,最大的特点就是可能间接在浏览器中关上并且正确的显示模板页面,而不须要启动整个web利用(真正的做到了前后端的拆散)spring mvc的初始配置增加相干的依赖,编辑pom.xml,增加spring web依赖,thymeleaf依赖,d

August 3, 2020 · 1 min · jiezi

关于spring-boot-编程思想:Spring-Boot快速入门之二快速开始

【注】本文译自:https://www.tutorialspoint.com/spring_boot/spring_boot_quick_start.htm 本文将教你如何利用 Maven 和 Gradle创立Spring Boot 利用. 先决条件要创立 Spring Boot 利用,你的零碎至多须要装置以下软件: Java 7Maven 3.2Gradle 2.5Spring Boot CLISpring Boot CLI 是一个命令行工具,容许咱们运行 Groovy 脚本。应用Spring Boot命令行工作接口是创立Spring Boot利用的便捷形式。你能够在命令窗口下进行创立、运行和测试。 本节解释了手工装置Spring Boot CLI的步骤。要获取进一步帮忙,可参考如下链接:https://docs.spring.io/springboot/ docs/current-SNAPSHOT/reference/htmlsingle/#getting-started-installing-springboot 。你也能够从Spring软件仓库下载Spring CLI的部署包:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#getting-started-manual-cli-installation。 要手工装置,你要用到上面两个文件夹: spring-boot-cli-2.0.0.BUILD-SNAPSHOT-bin.zipspring-boot-cli-2.0.0.BUILD-SNAPSHOT-bin.tar.gz下载后,解压文件并依照install.txt文件中的步骤进行操作。留神不须要任何环境设置。 在Windows零碎,在命令窗口切换到Spring Boot CLI bin 目录并运行命令 spring –-version 以确保正确装置了 spring CLI。执行命令后,你能够看到如下所示的 spring CLI 版本信息: 应用Groovy运行Hello World创立一个简略的 groovy 文件,蕴含 Rest 端点脚本并应用运行spring boot CLI运行groovy 文件。代码如下: @Controller class Example { @RequestMapping("/") @ResponseBody public String hello() { "Hello Spring Boot" ...

August 3, 2020 · 1 min · jiezi

不懂SpringApplication生命周期事件那就等于不会Spring-Boot嘛

学习方法之少废话:吹牛、装逼、叫大哥。作者:A哥(YourBatman)公众号:BAT的乌托邦(ID:BAT-utopia)文末是否有彩蛋:有 前言各位小伙伴大家好,我是A哥。本文属总结性文章,对总览Spring Boot生命周期很是重要,建议点在看、转发“造福”更多小伙伴。 我最近不是在写Spring Cloud深度剖析的相关专栏麽,最近有收到小伙伴发过来一些问题,通过这段时间收集到的反馈,总结了一下有一个问题非常集中:那便是对Spring Boot应用SpringApplication的生命周期、事件的理解。有句话我不是经常挂嘴边说的麽,你对Spring Framework有多了解决定了你对Spring Boot有多了解,你对Spring Boot的了解深度又会制约你去了解Spring Cloud,一环扣一环。因此此问题反馈比较集中是在清理之中的~ 为何在Spring Boot中生命周期事件机制如此重要?缘由很简单:Spring Cloud父容器是由该生命周期事件机制来驱动的,而它仅仅是一个典型代表。Spring Cloud构建在Spring Boot之上,它在此基础上构建并添加了一些“Cloud”功能。应用程序事件ApplicationEvent以及监听ApplicationListener是Spring Framework提供的扩展点,Spring Boot对此扩展点利用得非常充分和深入,并且还衍生出了非常多“子”事件类型,甚至自成体系。从ApplicationEvent衍生出来的子事件类型非常多,例如JobExecutionEvent、RSocketServerInitializedEvent、AuditApplicationEvent... 本文并不会对每个子事件分别介绍(也并无必要),而是集中火力主攻Spring Boot最为重要的一套事件机制:SpringApplication生命周期的事件体系。 正文本文将以SpringApplication的启动流程/生命周期各时期发出的Event事件为主线,结合每个生命周期内完成的大事记介绍,真正实现一文让你总览Spring Boot的全貌,这对你深入理解Spring Boot,以及整合进Spring Cloud都将非常重要。 为表诚意,本文一开始便把SpringApplication生命周期事件流程图附上,然后再精细化讲解各个事件的详情。 话外音:赶时间的小伙伴可以拿图走人????,但不建议白嫖哟生命周期事件流程图 版本说明:由于不同版本、类路径下存在不同包时结果会存在差异,不指明版本的文章都是不够负责任的。因此对导包/版本情况作出如下说明: Spring Boot:2.2.2.RELEASE。有且仅导入spring-boot-starter-web和spring-boot-starter-actuatorSpring Cloud:Hoxton.SR1。有且仅导入spring-cloud-context(注意:并非spring-cloud-starter,并不含有spring-cloud-commons哦)总的来说:本例导包是非常非常“干净”的,这样在流程上才更有说服力嘛~ SpringApplicationEvent它是和SpringApplication生命周期有关的所有事件的父类,@since 1.0.0。 public abstract class SpringApplicationEvent extends ApplicationEvent { private final String[] args; public SpringApplicationEvent(SpringApplication application, String[] args) { super(application); this.args = args; } public SpringApplication getSpringApplication() { return (SpringApplication) getSource(); } public final String[] getArgs() { return this.args; }}它是抽象类,扩展自Spring Framwork的ApplicationEvent,确保了事件和应用实体SpringApplication产生关联(当然还有String[] args)。它有如下实现子类(7个): ...

July 7, 2020 · 2 min · jiezi

Spring-Boot-文件操作上传浏览和删除

视频演示:https://www.bilibili.com/video/BV1rv411B7fs/ 一起来完成以下步骤:该工程演示Spring Boot如何上传、展示和删除文件 页面引擎采用Thymeleaf后端使用Spring Boot文件上传使用Form提交方式(而不是Ajax方式或VUE前后端分离) FileControlle.javapackage com.deepincoding.fileuploadformpage;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.core.io.Resource;import org.springframework.core.io.UrlResource;import org.springframework.http.HttpHeaders;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.util.FileSystemUtils;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;import java.io.IOException;import java.net.MalformedURLException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.StandardCopyOption;import java.util.List;import java.util.stream.Collectors;@Controllerpublic class FileController { //上传文件路径 @Value("${file.base.director}") private String fileBaseDirector; private Path fileBasePath; @Autowired private void createDirectories(){ try { Files.createDirectories(Paths.get(fileBaseDirector)); } catch (IOException e) { e.printStackTrace(); } this.fileBasePath = Path.of(fileBaseDirector); } /** * 首页 * @return */ @GetMapping("/") public String index(){ return "index"; } /** * 上传页面 * @return */ @GetMapping("/upload") public String upload(){ return "upload"; } /** * 获取文件列表 * @return * @throws IOException */ @GetMapping("/files") public String files(Model model) throws IOException { List<FileObject> filesAll = Files.walk(fileBasePath,1) .filter(path -> !path.equals(fileBasePath)) .map(path -> { String url = MvcUriComponentsBuilder.fromMethodName(FileController.class,"loadFile",path.getFileName().toString()).build().toString(); FileObject fileObject = new FileObject(path.getFileName().toString(),url); return fileObject; }).collect(Collectors.toList()); model.addAttribute("files",filesAll); return "files"; } /** * 删除文件 * @param fileName * @return */ @GetMapping("/delete/{fileName}") public String deleteFile(@PathVariable String fileName){ Path deletePath = fileBasePath.resolve(fileName); Boolean isDelete = Boolean.FALSE; try { isDelete = FileSystemUtils.deleteRecursively(deletePath); } catch (IOException e) { e.printStackTrace(); } return "redirect:/files"; } /** * 上传文件事件 * @param file * @return */ @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file){ String fileName = StringUtils.cleanPath(file.getOriginalFilename()); Path path = Path.of(fileBaseDirector + fileName); try { Files.copy(file.getInputStream(),path,StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { e.printStackTrace(); } return "redirect:/files"; }}

June 25, 2020 · 1 min · jiezi

干掉Maven-Spring-Boot正式拥抱-Gradle

前不久,Spring Boot发布了 2.3.0 版本,此版本对 Spring Boot 进行了相当重大的更改,并且这是使用 Gradle 而非 Maven 构建项目的第一个版本。关于 2.3.0 版本的新特性,本篇不做任何介绍。本文需要讲的是为什么要切换为Gradle而非Maven。 为什么要切换Spring Boot 团队考虑由 Maven 切换到 Gradle 的主要原因为了减少构建项目所需的时间。在开发和测试过程中,等待构建完成所花费的时间增加了修复错误和实现新功能所花费的时间。 为了解决这个问题,团队曾尝试利用 Maven 对并行构建的支持。由于 Spring Boot 构建的复杂性,特别是对 Invoker 插件的使用,尝试失败。通过将构建分为四个部分来解决 CI 问题。首先构建项目的主要核心,然后并行构建三个独立的部分。但 CI 的构建仍需要一个小时或更长时间。此外,由于针对的是模块化 CI 构建,因此并没有使得开发人员本地构建效率有所改变。 Spring Boot 团队在其他利用 Gradle 作为构建工具的 Spring 项目中看到了 Gradle 的增量和并行构建以及在第三方项目中看到了 Gradle 的构建缓存的好处。希望通过使用 Gradle 为 Spring Boot 构建获得类似的好处。 Gradle 具有非常灵活的构建模型,并且可以定义每个任务的输入和输出及其相互依赖性。这种构建模型的好处是,它允许任务并行运行,同时也可以增量、缓存或完全跳过。换句话说,Gradle 可以最小化的执行必要的 CI 任务。虽然可以使用了 Gradle Enterprise 的 Maven 支持,我们也可以享受构建缓存和跳过的好处。但是要充分享受这四个方面的好处,必须尝试切换到 Gradle。 如何切换Gradle 配置过于灵活,导致它的构建比基于 Maven 构建更难以维护和理解。例如: 同一个构建结果,可以通过不同的配置实现。如果切换到 Gradle,需要避免这种情况。从目前发布的四个 Spring Boot 2.3 里程碑版本,在核心团队或贡献者中,还没有发现任何重大的构建问题。 ...

June 24, 2020 · 1 min · jiezi

springbootRabbitMQ详解

RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。 消息中间件在互联网公司的使用中越来越多,刚才还看到新闻阿里将RocketMQ捐献给了apache,当然了今天的主角还是讲RabbitMQ。消息中间件最主要的作用是解耦,中间件最标准的用法是生产者生产消息传送到队列,消费者从队列中拿取消息并处理,生产者不用关心是谁来消费,消费者不用关心谁在生产消息,从而达到解耦的目的。在分布式的系统中,消息队列也会被用在很多其它的方面,比如:分布式事务的支持,RPC的调用等等。 以前一直使用的是ActiveMQ,在实际的生产使用中也出现了一些小问题,在网络查阅了很多的资料后,决定尝试使用RabbitMQ来替换ActiveMQ,RabbitMQ的高可用性、高性能、灵活性等一些特点吸引了我们,查阅了一些资料整理出此文。 RabbitMQ介绍RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。RabbitMQ主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时,消费者无法快速消费,那么需要一个中间层。保存这个数据。 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。 RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。 相关概念通常我们谈到队列服务, 会有三个概念: 发消息者、队列、收消息者,RabbitMQ 在这个基本概念之上, 多做了一层抽象, 在发消息者和 队列之间, 加入了交换器 (Exchange). 这样发消息者和队列就没有直接联系, 转而变成发消息者把消息给交换器, 交换器根据调度策略再把消息再给队列。 左侧 P 代表 生产者,也就是往 RabbitMQ 发消息的程序。中间即是 RabbitMQ,_其中包括了 交换机 和 队列。_右侧 C 代表 消费者,也就是往 RabbitMQ 拿消息的程序。那么,_其中比较重要的概念有 4 个,分别为:虚拟主机,交换机,队列,和绑定。_ 虚拟主机:一个虚拟主机持有一组交换机、队列和绑定。为什么需要多个虚拟主机呢?很简单,RabbitMQ当中,_用户只能在虚拟主机的粒度进行权限控制。_ 因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个RabbitMQ服务器都有一个默认的虚拟主机“/”。交换机:_Exchange 用于转发消息,但是它不会做存储_ ,如果没有 Queue bind 到 Exchange 的话,它会直接丢弃掉 Producer 发送过来的消息。 这里有一个比较重要的概念:路由键 。消息到交换机的时候,交互机会转发到对应的队列中,那么究竟转发到哪个队列,就要根据该路由键。绑定:也就是交换机需要和队列相绑定,这其中如上图所示,是多对多的关系。交换机(Exchange)交换机的功能主要是接收消息并且转发到绑定的队列,交换机不存储消息,在启用ack模式后,交换机找不到队列会返回错误。交换机有四种类型:Direct, topic, Headers and Fanout Direct:direct 类型的行为是"先匹配, 再投送". 即在绑定时设定一个 routing_key, 消息的routing_key 匹配时, 才会被交换器投送到绑定的队列中去.Topic:按规则转发消息(最灵活)Headers:设置header attribute参数类型的交换机Fanout:转发消息到所有绑定队列Direct Exchange Direct Exchange是RabbitMQ默认的交换机模式,也是最简单的模式,根据key全文匹配去寻找队列。 ...

June 13, 2020 · 4 min · jiezi