分布式开发:后端提供结口+前端接受信息渲染!
单体开发:后端提供数据+前端获取数据渲染!
整体来说,从开发流程,单体和分布式本质上没有区别,只是技术和思想上略有不同!
分布式开发的本质:网络是不可靠的!服务之间的通信,服务崩了怎么办,客户端怎么访问,服务的注册与发现!
精通Swagger
了解Swagger:
-
- 号称世界上最流行的API框架
- Restful api 自动生成文档,和代码对应
- 直接运行测试接口,不用下载postman
- 支持多种语言:(java,php等)
- 官网:https://swagger.io/
集成Swagger:
- 导入依赖
- 编写配置,开启注解 @EnableSwagger2 // 开启swagger2
- 测试
1 <dependency> 2 <groupId>io.springfox</groupId> 3 <artifactId>springfox-swagger2</artifactId> 4 <version>2.7.0</version> 5 </dependency> 6 <!-- https://mvnrepository.com/artifact/com.github.xiaoymin/swagger-bootstrap-ui --> 7 <dependency> 8 <groupId>com.github.xiaoymin</groupId> 9 <artifactId>swagger-bootstrap-ui</artifactId> 10 <version>1.9.3</version> 11 </dependency> 12 13 <!-- 原生ui --> 14 <!--<dependency> 15 <groupId>io.springfox</groupId> 16 <artifactId>springfox-swagger-ui</artifactId> 17 <version>2.7.0</version> 18 </dependency>-->
1 package com.coding.config; 2 3 import lombok.var; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.core.env.Environment; 7 import org.springframework.core.env.Profiles; 8 import springfox.documentation.RequestHandler; 9 import springfox.documentation.builders.PathSelectors; 10 import springfox.documentation.builders.RequestHandlerSelectors; 11 import springfox.documentation.service.ApiInfo; 12 import springfox.documentation.service.Contact; 13 import springfox.documentation.service.VendorExtension; 14 import springfox.documentation.spi.DocumentationType; 15 import springfox.documentation.spring.web.plugins.Docket; 16 17 import java.util.ArrayList; 18 19 @Configuration 20 public class SwaggerConfig { 21 22 // 编写多个bean 满足不同的接口测试需求 23 @Bean 24 public Docket docket3(){ 25 26 return new Docket(DocumentationType.SWAGGER_2).groupName("group3"); 27 } 28 29 @Bean 30 public Docket docket2(){ 31 32 return new Docket(DocumentationType.SWAGGER_2).groupName("group2"); 33 } 34 35 @Bean 36 public Docket docket1(){ 37 38 return new Docket(DocumentationType.SWAGGER_2).groupName("group1"); 39 } 40 41 @Bean 42 public Docket docket(Environment environment){ 43 Profiles of = Profiles.of("dev","test"); 44 boolean b = environment.acceptsProfiles(of); 45 46 return new Docket(DocumentationType.SWAGGER_2) 47 .groupName("group") 48 .apiInfo(apiInfo()) 49 .enable(b) // 判断 50 .select() 51 .apis(RequestHandlerSelectors.basePackage("com.coding.controller")) // 扫描此包下的接口 52 .paths(PathSelectors.ant("/**")) // 测试此路径下的方法 53 .build(); 54 } 55 56 Contact contact = new Contact("Vin","https://home.cnblogs.com/u/ShallowPen/","[email protected]"); 57 /*String title, 58 String description, 59 String version, 60 String termsOfServiceUrl, 61 String contactName, 62 String license, 63 String licenseUrl*/ 64 private ApiInfo apiInfo(){ 65 return new ApiInfo( 66 "接口文档信息", 67 "所有的测试地址", 68 "v1.0", 69 "https://home.cnblogs.com/u/ShallowPen/", 70 contact, 71 "Apache 2.0", 72 "http://www.apache.org/licenses/LICENSE-2.0", 73 new ArrayList<>() 74 ); 75 } 76 77 }
异步任务
- 在业务方法中,加上@Async注解
- 开启注解的支持 @EnableAsync // 开启异步处理
1 package com.coding.service; 2 3 import org.springframework.scheduling.annotation.Async; 4 import org.springframework.stereotype.Service; 5 6 import java.util.concurrent.TimeUnit; 7 8 @Service 9 public class AsyncService { 10 11 12 // 加入 @Async 进行异步处理,秒级处理 13 @Async // 告诉Spring这是一个异步方法!默认使用了线程池,效率很好! 14 public void hello(){ 15 try { 16 TimeUnit.SECONDS.sleep(3); // 加入延时代码进行测试 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 System.out.println("数据处理..."); 21 } 22 }
定时任务
- 在业务代码上加入注解 @Scheduled(cron = "0 * * * * 0-7")
- 开启注解支持 @EnableScheduling // 开启定时任务支持
工作中一定会用到定时任务,每天发送一个日志信息,Spring也提供了对应的支持!
Cron表达式
- * 表示任意时间
- - 表示区间 // 6-7
- L 表示最后
- ? 表示 天/星期冲突匹配
- W 表示工作日
- # 表示星期 // 4#2,第二个星期三
常用例子:
(1)0/2 * * * * ? 表示每2秒 执行任务
(1)0 0/2 * * * ? 表示每2分钟 执行任务
(1)0 0 2 1 * ? 表示在每月的1日的凌晨2点调整任务
(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
(6)0 0 12 ? * WED 表示每个星期三中午12点
(7)0 0 12 * * ? 每天中午12点触发
(8)0 15 10 ? * * 每天上午10:15触发
(9)0 15 10 * * ? 每天上午10:15触发
(10)0 15 10 * * ? 每天上午10:15触发
(11)0 15 10 * * ? 2005 2005年的每天上午10:15触发
(12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
(13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
(14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
(15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
(18)0 15 10 15 * ? 每月15日上午10:15触发
(19)0 15 10 L * ? 每月最后一日的上午10:15触发
(20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
(22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
测试一下
1 package com.coding.service; 2 3 import org.springframework.scheduling.annotation.Scheduled; 4 import org.springframework.stereotype.Service; 5 6 @Service 7 public class ScheduledService { 8 // 秒 分 时 日 月 星期 9 @Scheduled(cron = "0/2 * * * * ? ") 10 public void hello(){ 11 System.out.println("hello。。。。。。。。"); 12 } 13 }
邮件任务
- 导入maven依赖
- 配置文件
- 测试使用
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-mail</artifactId> 4 </dependency>
分析源码 MailSenderAutoConfiguration ,通过导入的组件发现配置类
1 @Bean 2 @ConditionalOnMissingBean(JavaMailSender.class) 3 JavaMailSenderImpl mailSender(MailProperties properties) { 4 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 5 applyProperties(properties, sender); 6 return sender; 7 }
配置properties文件
1 # 发件人的信息(一般是公司的账号 2 [email protected] 3 spring.mail.password=PHTQALPJHAHWMBSQ 4 spring.mail.host=smtp.163.com 5 6 # QQ比较特殊,需要配置ssl 安全连接, 如果是其他的邮箱不用配置 7 spring.mail.properties.mail.smtp.ssl.enable=true
编写测试代码
1 package com.coding; 2 3 import org.junit.jupiter.api.Test; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.boot.test.context.SpringBootTest; 6 import org.springframework.mail.SimpleMailMessage; 7 import org.springframework.mail.javamail.JavaMailSenderImpl; 8 import org.springframework.mail.javamail.MimeMessageHelper; 9 10 import javax.mail.MessagingException; 11 import javax.mail.internet.MimeMessage; 12 13 @SpringBootTest 14 class Day0325SwaggerApplicationTests { 15 16 @Autowired 17 JavaMailSenderImpl javaMailSender; 18 19 @Test 20 void sayMail(){ 21 // 发送简单的邮件消息 22 SimpleMailMessage message = new SimpleMailMessage(); 23 message.setSubject("明天不上课");// 邮件主题 24 message.setText("好好学习");// 邮件内容 25 message.setTo("[email protected]");// 收件人 26 message.setFrom("[email protected]");// 发件人 27 javaMailSender.send(message); 28 } 29 30 // 复杂邮件测试 31 @Test 32 void sayMail2() throws MessagingException { 33 MimeMessage mimeMessage = javaMailSender.createMimeMessage(); 34 MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true); 35 helper.setSubject("复杂邮件测试"); 36 helper.setText("<h1 style='color:red'>我是红色的</h1>",true); 37 helper.setTo("[email protected]"); 38 helper.setFrom("[email protected]"); 39 javaMailSender.send(mimeMessage); 40 } 41 }