首页
统计
关于
Search
1
Sealos3.0离线部署K8s集群
1,088 阅读
2
类的加载
744 阅读
3
Spring Cloud OAuth2.0
727 阅读
4
SpringBoot自动装配原理
692 阅读
5
集合不安全问题
589 阅读
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
登录
Search
标签搜索
Java
CSS
mysql
RabbitMQ
JavaScript
Redis
JVM
Mybatis-Plus
Camunda
多线程
CSS3
Python
Spring Cloud
注解和反射
Activiti
工作流
SpringBoot
Mybatis
Spring
html5
蘇阿細
累计撰写
391
篇文章
累计收到
4
条评论
首页
栏目
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
页面
统计
关于
搜索到
157
篇与
的结果
2020-12-31
Hystrix服务熔断
Hystrix服务熔断服务熔断:熔断机制是对应雪崩效应的一种微服务链路保护机制。当某个微服务不可用或响应时间太长,会进行服务的降级,进而熔断该节点微服务的调用,快速返回“错误的响应信息”,当该节点的调用恢复正常之后注册中心将其恢复至调用链路。Spring Cloud的熔断机制通过Hystrix实现,它会监控微服务间的调用状况,当失败的调用到一定阈值(缺省5秒内20次调用失败),就会启动熔断机制。具体实例:1、导入依赖<dependencies> <!--需要拿到实体类,配置api module--> <dependency> <groupId>com.sw</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!--actuator监控信息--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--Hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>1.4.7.RELEASE</version> </dependency> </dependencies>2、daopackage com.sw.springcloud.dao; import com.sw.springcloud.pojo.Dept; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:34 */ @Mapper @Repository public interface DeptDao { public boolean addDept(Dept dept); public Dept findDept(Long id); public List<Dept> findAll(); } 3、Service接口package com.sw.springcloud.service; import com.sw.springcloud.pojo.Dept; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:34 */ public interface DeptService { public boolean addDept(Dept dept); public Dept findDept(Long id); public List<Dept> findAll(); } Service实现:package com.sw.springcloud.service; import com.sw.springcloud.dao.DeptDao; import com.sw.springcloud.pojo.Dept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:42 */ @Service public class DeptServiceImpl implements DeptService{ @Autowired private DeptDao deptDao; @Override public boolean addDept(Dept dept) { return deptDao.addDept(dept); } @Override public Dept findDept(Long id) { return deptDao.findDept(id); } @Override public List<Dept> findAll() { return deptDao.findAll(); } } 4、controller注:hystrix熔断需开启注解@HystrixCommand(fallbackMethod = "hystrixGet"),且提供熔断后的备选方法package com.sw.springcloud.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.sw.springcloud.pojo.Dept; import com.sw.springcloud.service.DeptService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 21:44 * 提供RestFul服务 */ @RestController public class DeptController { @Autowired private DeptService deptService; @GetMapping("/dept/get/{id}") @HystrixCommand(fallbackMethod = "hystrixGet") public Dept get(@PathVariable("id")Long id){ Dept dept = deptService.findDept(id); if (dept==null){ throw new RuntimeException("不存在id为"+id+"的用户,或者信息无法找到"); } return dept; } //熔断后的备选方法 public Dept hystrixGet(@PathVariable("id")Long id){ Dept dept = deptService.findDept(id); return new Dept() .setDeptno(id) .setDname("不存在id为"+id+"的用户,或者信息无法找到,null-->@Hystrix") .setDb_source("No message in MySQL"); } } 5、SpringBoot启动类开启Hystrix注解支持package com.sw.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @Author suaxi * @Date 2020/12/28 21:49 */ @SpringBootApplication @EnableEurekaClient //服务启动后自动注册到Eureka中 @EnableDiscoveryClient //开启服务发现 @EnableCircuitBreaker //开启熔断器支持 public class DeptProviserHystrix_8088 { public static void main(String[] args) { SpringApplication.run(DeptProviserHystrix_8088.class,args); } } 6、appliction.yml配置(此处以单个节点配置为例,实际开发中的微服务节点不止一个)server: port: 8088 #mybatis配置 mybatis: type-aliases-package: com.sw.springcloud.pojo config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml #Spring配置 spring: application: name: springcloud-provider-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db01?useUnicode=true&character=UFT-8 username: root password: 123456 #配置Eureka,配置服务注册到哪里 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ instance: instance-id: springcloud-provider_dept-hystrix_8088 #修改Eureka默认描述信息 #info配置 info: app.name: springcloud-demo company.name: suaxi 当整个微服务调用出现问题时,前端反馈给用户的信息不是错误代码,而是熔断后的备选方法中定义的信息(即快速返回出现错误的响应信息)。用户正常查询信息:查询数据库中不存在的信息,即服务调用出现异常:
2020年12月31日
184 阅读
0 评论
0 点赞
2020-12-31
Feign负载均衡
Feign负载均衡Feign是声明式的web service客户端,Spring Cloud集成了Ribbon和Eureka,可以在使用Feign时提供负载均衡的http客户端。相较于Ribbon,Feign通过创建接口和注解使用,即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。具体实例:1、导入依赖<dependencies> <!--feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!--Ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!--Eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.7.RELEASE</version> </dependency> <dependency> <groupId>com.sw</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>2、Controllerpackage com.sw.springcloud.controller; import com.sw.springcloud.pojo.Dept; import com.sw.springcloud.service.DeptClientService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.List; /** * @Author suaxi * @Date 2020/12/28 22:16 */ @RestController public class DeptConsumerController { @Autowired private DeptClientService client; @RequestMapping(value = "/consumer/dept/add",produces = {"application/json;charset=UTF-8"}) public boolean add(Dept dept){ return this.client.addDept(dept); } @RequestMapping(value = "/consumer/dept/get/{id}",produces = {"application/json;charset=UTF-8"}) public Dept get(@PathVariable("id")Long id){ return this.client.findById(id); } @RequestMapping(value = "/consumer/dept/list",produces = {"application/json;charset=UTF-8"}) public List<Dept> list(){ return this.client.findAll(); } } 3、注册到Spring容器中package com.sw.springcloud.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; /** * @Author suaxi * @Date 2020/12/28 22:15 */ @Configuration public class ConfigBean { @Bean @LoadBalanced //注册Ribbon public RestTemplate getRestTemplate(){ return new RestTemplate(); } } 4、SpringBoot启动类开启Feign注解package com.sw.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; /** * @Author suaxi * @Date 2020/12/28 22:29 */ @SpringBootApplication @EnableEurekaClient @EnableFeignClients(basePackages = {"com.sw.springcloud"}) public class FeignDeptConsumer_80 { public static void main(String[] args) { SpringApplication.run(FeignDeptConsumer_80.class,args); } }
2020年12月31日
101 阅读
0 评论
0 点赞
2020-12-30
Ribbon
RibbonSpring Cloud Ribbon是基于NetFlix Ribbon实现的客户端负载均衡工具主要功能是提供客户端的软件负载均衡算法,将NetFlix的中间层服务连接在一起。在配置文件中列出LoadBalancer后面的所有机器,Ribbon会自动帮助你基于某些规则(轮询、随机数轮询、随机连接等)去连接这些服务。自定义算法:package com.sw.myrule; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import java.util.List; import java.util.concurrent.ThreadLocalRandom; /** * @Author suaxi * @Date 2020/12/29 16:44 */ public class MyRandomRule extends AbstractLoadBalancerRule { //自定义算法:每个服务访问5次之后,换下一个 private int total = 0; //被调用的次数 private int currentIndex = 0; //当前是谁在提供服务 public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null; while (server == null) { if (Thread.interrupted()) { return null; } List<Server> upList = lb.getReachableServers(); //获取活着的服务 List<Server> allList = lb.getAllServers(); //获取所有服务 int serverCount = allList.size(); if (serverCount == 0) { return null; } // int index = chooseRandomInt(serverCount); //生成区间随机数 // server = upList.get(index); //从活着的服务中,随机获取一个 if (total<5){ server = upList.get(currentIndex); total++; }else { total = 0; currentIndex++; if (currentIndex>upList.size()){ currentIndex = 0; //当提供服务的人的执行次数大于活着的服务数量时,重置为0 } server = upList.get(currentIndex); //从或者的服务中来获取指定的服务 } if (server == null) { Thread.yield(); continue; } if (server.isAlive()) { return (server); } server = null; Thread.yield(); } return server; } protected int chooseRandomInt(int serverCount) { return ThreadLocalRandom.current().nextInt(serverCount); } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { // TODO Auto-generated method stub } } 注册到Spring容器中package com.sw.myrule; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RoundRobinRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Author suaxi * @Date 2020/12/29 16:12 */ @Configuration public class TestRule { @Bean public IRule myRule(){ return new MyRandomRule(); } } package com.sw.springcloud.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; /** * @Author suaxi * @Date 2020/12/28 22:15 */ @Configuration public class ConfigBean { //配置负载均衡实现RestTemplate //IRule //RoundRobinRule 轮询 //RandomRule 随机数 //AvailabilityFilteringRule 先过滤不可用的服务,对剩下的进行轮询 //RetryRule 先按照轮询获取服务,如果获取服务失败,则会在指定的时间内进行重试 @Bean @LoadBalanced //注册Ribbon public RestTemplate getRestTemplate(){ return new RestTemplate(); } } 开启自定义Ribbon注解package com.sw.springcloud; import com.sw.myrule.TestRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; /** * @Author suaxi * @Date 2020/12/28 22:29 */ @SpringBootApplication @EnableEurekaClient //在微服务启动的时候加载自定义的Ribbon类 @RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = TestRule.class) public class DeptConsumer_80 { public static void main(String[] args) { SpringApplication.run(DeptConsumer_80.class,args); } }
2020年12月30日
78 阅读
0 评论
0 点赞
2020-12-28
Git
Git1、设置用户名、邮箱git config --global user.name "suaxi" #用户名 git config --global user.email xxx@qq.com #邮箱2、Git基本理论Git本地有三个工作区域:工作目录(Working Directory),暂存区(Stage/Index),资源区(Repository或Git Directory),另外还有远程仓库(Remote Directory)WorkSpace:工作区,平时存放代码的地方Index/Stage:暂存区(待提交更新区),临时存放改动过的文件,在提交进入repo之前,所有的更新都放在暂存区Repository:仓库区,安全存放数据的位置,这里有提交的所有历史版本,其中,HEAD指向提交到仓库的最新版本Remote:远程仓库,例如:GitHub、Gitee.git:存放git管理信息的目录,初始化仓库的时候自动创建Local Repo:本地仓库,存放在本地的版本库Stash:工作状态保存栈,用于保存/恢复WorkSpace中的临时状态3、搭建仓库1、初始化本地仓库#在需要创建仓库的文件夹执行 git init2、克隆远程仓库git clone https://github.com/xxx/xxx.git4、文件的四种状态Untracked:未跟踪,此文件在文件夹中,但并没有加入到git仓库,不参与版本控制,可以通过git add将状态变为stagedUnmodify:文件已经入库,未修改,版本库中的文件快照内容与文件夹完全一致。如果他被修改,状态变为Modified,如果使用git rm移除版本库,则变为Untracked文件Modified:文件已修改,但未进行其他操作。通过git add可以进入staged状态,也可以使用git checkout丢弃修改过的,返回到Unmodify状态,注:git checkout从库中取出文件,覆盖当前修改Staged:暂存状态,通过git commit可以将修改同步到库中,这时库中的文件与本地文件状态一致,状态为Unmodify。执行git reset HEAD filename可以取消暂存状态,此时文件状态为Modified查看文件状态#查看指定文件状态 git status filename #查看所有文件状态 git status #添加文件到暂存区 git add . #提交暂存区中的文件到本地仓库(必须加上注释) git commit -m "用户自定义的注释信息" 忽略文件IDEA新建项目时,会自动生成.gitignore文件,其中包含了项目打包或上传时需要忽略的文件#例: *.txt #忽略所有.txt结尾的文件 !test.txt #忽略test.txt除外的文件HELP.md target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/** !**/src/test/** ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ build/ ### VS Code ### .vscode/ 5、Git分支#查看所有分支 git branch -r #新建一个分支(心在完成后依然停留在当前的文件目录下) git branch branch-name #新建一个分支并切换到新建的分支目录下 git branch -b branch-name #和并指定分支到当前分支 git merge branch-name #删除分支(注意与新建并切换分支区分) git branch -d branch-name #删除远程分支 git push origin --delete branch-name git branch -dr https://github.com/xxx/branch-name
2020年12月28日
77 阅读
0 评论
0 点赞
2020-12-26
定时任务
定时任务1、SpringBoot启动类开启定时任务注解package com.sw; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling //开启定时任务 @SpringBootApplication public class Springboot09AsynctaskApplication { public static void main(String[] args) { SpringApplication.run(Springboot09AsynctaskApplication.class, args); } } 2、测试package com.sw.service; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; /** * @Author suaxi * @Date 2020/12/26 17:35 * 定时任务 */ @Service public class ScheduledService { /* cron:秒 分 时 日 月 周几 0/3 * * * * 0-7 周一到周日每三秒执行一次 0 0 21 26 12 ? 12月26日21时执行 */ @Scheduled(cron = "0/3 * * * * 0-7") public void hello(){ System.out.println("抽象!"); } } 注:定时任务需使用cron表达式来源:cron百度百科 0 0 2 1 * ? * 表示在每月的1日的凌晨2点调度任务 0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业 0 15 10 ? * 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 12 ? * WED 表示每个星期三中午12点 "0 0 12 * * ?" 每天中午12点触发 "0 15 10 ? * *" 每天上午10:15触发 "0 15 10 * * ?" 每天上午10:15触发 "0 15 10 * * ? *" 每天上午10:15触发 "0 15 10 * * ? 2005" 2005年的每天上午10:15触发 "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 "0 15 10 15 * ?" 每月15日上午10:15触发 "0 15 10 L * ?" 每月最后一日的上午10:15触发 "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
2020年12月26日
121 阅读
0 评论
0 点赞
2020-12-26
SpringBoot邮件发送
邮件发送1、application配置spring: mail: host: smtp.qq.com username: xxx@qq.com password: 123456 #qq邮箱需设置安全加密 properties.mail.smtp.ssl.enable: true注:1、host:邮件发送服务器2、username:邮箱地址3、password:密码4、使用QQ邮箱时,需设置安全加密2、Junit单元测试package com.sw; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import java.io.File; @SpringBootTest class Springboot09AsynctaskApplicationTests { @Autowired JavaMailSenderImpl mailSender; @Test void mailTest() { //简单邮件 SimpleMailMessage mailMessage = new SimpleMailMessage(); //标题 mailMessage.setSubject("Test"); //正文 mailMessage.setText("SpringBoot Mail Test"); //收件人 mailMessage.setTo("xxx@gmail.com"); //发件人 mailMessage.setFrom("xxx@qq.com"); mailSender.send(mailMessage); } @Test public void mailTest02() throws MessagingException { //复杂邮件测试 MimeMessage mimeMessage = mailSender.createMimeMessage(); //组装 MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); //正文 helper.setSubject("哈尼"); helper.setText("<p style='color:red'>这是一封SpringBoot-mail测试邮件</p>",true); //开启html支持 //附件 helper.addAttachment("hani.png",new File("xxx/hani.png")); //绝对路径 helper.setTo("568362762@qq.com"); helper.setFrom("281463547@qq.com"); mailSender.send(mimeMessage); } } 注:如需发送附件,需填写绝对路径的地址
2020年12月26日
113 阅读
0 评论
0 点赞
2020-12-26
异步任务
异步任务1、Servicepackage com.sw.service; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; /** * @Author suaxi * @Date 2020/12/26 15:57 */ @Service public class AsyncService { //告诉Spring这是一个异步任务 @Async public void hello(){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("数据正在加载..."); } } 2、Controllerpackage com.sw.controller; import com.sw.service.AsyncService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Author suaxi * @Date 2020/12/26 15:58 */ @RestController public class AsyncController { @Autowired private AsyncService asyncService; @RequestMapping("/test") public String hello(){ asyncService.hello(); return "Ok"; } } 3、SpringBoot启动类开启异步任务的注解package com.sw; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @EnableAsync //开启异步任务注解 @SpringBootApplication public class Springboot09AsynctaskApplication { public static void main(String[] args) { SpringApplication.run(Springboot09AsynctaskApplication.class, args); } } 当用户执行/test请求时,前端页面及时返回结果,同时异步任务延迟三秒在控制台打印输出结果
2020年12月26日
200 阅读
0 评论
0 点赞
2020-12-26
Swagger
SwaggerSwagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。1、导入依赖<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>2、SwaggerConfig配置package com.sw.swagger.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.ArrayList; /** * @Author suaxi * @Date 2020/12/26 11:03 */ @Configuration @EnableSwagger2 public class SwaggerConfig { //配置Swagger的Docket @Bean public Docket docket(Environment environment) { //配置哪种环境下需要启用Swagger Profiles profiles = Profiles.of("dev", "test"); //监听配置文件 boolean flag = environment.acceptsProfiles(profiles); //链式编程 return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(flag) //配置是否启动Swagger,默认为true,如需关闭须手动设置为false .select() //RequestHandlerSelectors 配置扫描接口的方式 //basePackage() 指定要扫描的包 //any() 扫描全部 //none() 不扫描 //withClassAnnotation(Controller.class) 扫描类注解(参数是一个注解的反射对象) //withMethodAnnotation(RequestMapping.class) 扫描方法上的注解 .apis(RequestHandlerSelectors.basePackage("com.sw.swagger.controller")) //paths() 过滤的路径 .paths(PathSelectors.ant("/**")) .build(); } //配置Swagger apiInfo private ApiInfo apiInfo(){ //作者信息 Contact contact = new Contact("suaix","http://wangchouchou.com","281463547@qq.com"); return new ApiInfo( "Swagger StudyDemo", "SwaggerStudy", "1.0", "http://wangchouchou.com", contact, "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList()); } } Docket配置//配置Swagger的Docket @Bean public Docket docket(Environment environment) { //配置哪种环境下需要启用Swagger Profiles profiles = Profiles.of("dev", "test"); //监听配置文件 boolean flag = environment.acceptsProfiles(profiles); //链式编程 return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(flag) //配置是否启动Swagger,默认为true,如需关闭须手动设置为false .select() //RequestHandlerSelectors 配置扫描接口的方式 //basePackage() 指定要扫描的包 //any() 扫描全部 //none() 不扫描 //withClassAnnotation(Controller.class) 扫描类注解(参数是一个注解的反射对象) //withMethodAnnotation(RequestMapping.class) 扫描方法上的注解 .apis(RequestHandlerSelectors.basePackage("com.sw.swagger.controller")) //paths() 过滤的路径 .paths(PathSelectors.ant("/**")) .build(); }配置什么环境下需要使用Swagger通过监听配置文件实现//配置那种环境下需要启用Swagger Profiles profiles = Profiles.of("dev", "test"); //监听配置文件 boolean flag = environment.acceptsProfiles(profiles); 3、配置文档分组.groupName("Demo")如何配置实现多个分组?配置多个Docket实例即可4、实体类package com.sw.swagger.pojo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /** * @Author suaxi * @Date 2020/12/26 14:39 */ //@Api("用户实体类") @ApiModel("用户实体类") public class User { @ApiModelProperty("用户名") public String username; @ApiModelProperty("密码") public String password; } 5、Controllerpackage com.sw.swagger.controller; import com.sw.swagger.pojo.User; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; /** * @Author suaxi * @Date 2020/12/26 10:59 */ @RestController public class HelloController { @ApiOperation("POST测试") @PostMapping("/hello") public String helloTest(@ApiParam("用户名") String username){ return "swagger-springboot"; } @ApiOperation("返回User对象") @PostMapping("/u") public User user(){ return new User(); } @ApiOperation("Hello控制类") @GetMapping("/h") public String hello(){ return "swagger-springboot"; } } 小结:1、通过Swagger可以给一些难以理解的属性或接口添加注释信息2、接口文档实时更新3、在线测试
2020年12月26日
301 阅读
1 评论
0 点赞
1
...
10
11
12
...
20