单体开发进阶

分布式开发:后端提供结口+前端接受信息渲染!

单体开发:后端提供数据+前端获取数据渲染!

整体来说,从开发流程,单体和分布式本质上没有区别,只是技术和思想上略有不同!

分布式开发的本质:网络是不可靠的!服务之间的通信,服务崩了怎么办,客户端怎么访问,服务的注册与发现!

 

精通Swagger

  了解Swagger:

    • 号称世界上最流行的API框架
    • Restful api 自动生成文档,和代码对应
    • 直接运行测试接口,不用下载postman
    • 支持多种语言:(java,php等)
    • 官网:https://swagger.io/

  集成Swagger:

  1. 导入依赖
  2. 编写配置,开启注解 @EnableSwagger2 // 开启swagger2
  3. 测试
 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/","1577525597@qq.com");
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 }

 

异步任务

  1. 在业务方法中,加上@Async注解
  2. 开启注解的支持 @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 }

 

定时任务

  1. 在业务代码上加入注解  @Scheduled(cron = "0 * * * * 0-7")
  2. 开启注解支持 @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 }

 

邮件任务

  1. 导入maven依赖
  2. 配置文件
  3. 测试使用
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 spring.mail.username=13766668888@163.com 
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("1683333666@qq.com");// 收件人
26         message.setFrom("13766668888@163.com");// 发件人
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("1683333666@qq.com");
38         helper.setFrom("13766668888@163.com");
39         javaMailSender.send(mimeMessage);
40     }
41 }

 

posted @ 2020-03-30 00:16  执笔人生  阅读(317)  评论(0编辑  收藏  举报