一、swagger

1、spring boot集成swagger

创建一个新spring项目,添加web依赖,编写一个hello程序,保证项目初始化正常
1、导入swagger依赖版本2.9.2,spring boot版本调整为2.5.6

 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency>

2、config目录中配置swagger

package com.jjl.swagger.config;import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration
@EnableSwagger2
public class SwaggerConfig {}

3、启动测试,访问:http://localhost:8080/swagger-ui.html

2、swagger基本信息配置

swagger的bean实例docket

package com.jjl.swagger.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;@Configuration
@EnableSwagger2
public class SwaggerConfig {//配置swagger的Docket实例//用docket()对象接管默认配置信息@Beanpublic Docket docket(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());}//配置Swagger信息=apiInfoprivate ApiInfo apiInfo(){Contact contact = new Contact("蒋樊","https://blog.csdn.net/qq_43427354","http:test@qq.com");return new ApiInfo("蒋樊SwaggerAPI文档","不忘初心","1.0","https://www.baidu.com/",contact,"Apache 2.0","http://www.apache.org/licenses/LICENSE-2.0",new ArrayList());}
}

重启测试

3、swagger配置扫描接口

@Bean
public Docket docket(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()//RequestHandlerSelectors,配置要扫描的方式//.basePackage:指定要扫描的包basePackage("com.jjl.swagger.controller")//.any():扫描全部//.none:都不扫描//.withClassAnnotation(RestController.class):扫描有RestController注解的类//.withMethodAnnotation(GetMapping.class)扫描有GetMapping注解的方法.apis(RequestHandlerSelectors.basePackage("com.jjl.swagger.controller")).paths(PathSelectors.ant("/jjl/**"))//过滤的路径,只扫描/jjl下的所有接口.build();//
}

4、配置是否启动swagger,默认true


配置当生产环境时则启动swagger,当发布或者测试环境时自动关闭swagger
1、新建两个springboot配置文件,一个用于生产环境时调用,一个用于发布时或测试时调用,通过默认的配置文件去激活要使用的配置文件。

2、去swagger中获取当前的环境

5、创建多个分组,模拟多人开发

添加多个Docket即可

    @Beanpublic Docket docket1(){return new Docket(DocumentationType.SWAGGER_2).groupName("A组");}@Beanpublic Docket docket2(){return new Docket(DocumentationType.SWAGGER_2).groupName("B组");}@Beanpublic Docket docket3(){return new Docket(DocumentationType.SWAGGER_2).groupName("C组");}

6、添加注释

1、实体类注释

package com.jjl.swagger.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;@ApiModel("用户实体类")   //==@Api("用户实体类")
public class User {@ApiModelProperty("用户名")public String username;@ApiModelProperty("密码")public String password;
}

3、方法的注释

package com.jjl.swagger.controller;import com.jjl.swagger.pojo.User;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloConterller {@RequestMapping("/hello")public String hello(){return "hello swagger";}//只要我们的接口中存在实体类,就会被扫描到@PostMapping(value = "/user")public User user(){return new User();}@ApiOperation("hello传参username")@PostMapping(value = "/hello2")public String hello2(@ApiParam("传入用户名") String username){return "hello2"+username;}}

4、接口测试


二、异步任务

1、模拟后台程序处理业务时的延时

package com.jjl.service;import org.springframework.stereotype.Service;@Service
public class AsyncService {public void hello() throws InterruptedException {Thread.sleep(3000);System.out.println("数据正在处理……………………");}
}

调用延时任务

package com.jjl.controller;import com.jjl.service.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class AsyncController {@AutowiredAsyncService asyncService;@RequestMapping("/hello")public String hello() throws InterruptedException {asyncService.hello();return "ok";}
}

当调用这个延时任务时,前端页面会出现白屏等待

2、启用spring异步任务

启用spring异步任务之后,spring会继续处理延时任务,但是前端页面会跳过等待直接加载页面

在spring启动类上开启异步任务

测试目录

三、邮件发送

1、导入依赖

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

2、配置mail参数

spring.mail.username=17709966@qq.com
spring.mail.password=iurwbuhuclytfd
spring.mail.host=smtp.qq.com
# 开启安全验证
spring.mail.properties.mail.smtp.ssl.enable=true

4、测试简单邮件发送和带附件的邮件发送

package com.jjl;import com.jjl.config.SendMail;
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.MimeMailMessage;
import org.springframework.mail.javamail.MimeMessageHelper;import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;@SpringBootTest
class Springboot09TestApplicationTests {@AutowiredJavaMailSenderImpl mailSender;@Testvoid contextLoads() {//简单邮件发生测试SimpleMailMessage message = new SimpleMailMessage();message.setSubject("spring mail test");message.setText("邮件发送测试");message.setTo("2959351531@qq.com");message.setFrom("1770990966@qq.com");mailSender.send(message);}@Testvoid contextLoads2() throws MessagingException {//复杂邮件发生测试MimeMessage message = mailSender.createMimeMessage();//组装MimeMessageHelper helper = new MimeMessageHelper(message,true);helper.setSubject("spring复杂邮件测试");//true,支持htmlhelper.setText("<p style='color:red'>邮件测试</p>",true);//添加附件helper.addAttachment("1.jpg",new File("E:\\desktop_wallpaper\\2.jpg"));helper.setTo("2959351531@qq.com");helper.setFrom("1770990966@qq.com");mailSender.send(message);}
}

四、定时任务

TaskScheduler 任务调度者
TaskExecutor 任务执行者
@EnableScheduling //开启定时任务
@Scheduled //执行的时间

1、写一个定时任务的测试类

package com.jjl.service;import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;@Service
public class ScheduledService {//在特定的时间执行//cron表达式:cron = "秒 分 时 日 月 周几"//网上有很多cron表达式的写法"0/2 * * * * ?”每两秒执行一次@Scheduled(cron = "0 32 9 * * ?") //在每天的9点32分执行public void hello(){System.out.println("定时任务测试");}
}

2、在spring启动类中开启定时任务

3、cron表达式

五、集成redis

参考笔记

1、导入redis依赖

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

2、配置redis连接参数

3、测试连接

package com.jjl;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;@SpringBootTest
class Redis01SpringbootApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid contextLoads() {// opsForValue() 操作字符串 类似String//opsForList() 操作list 类似list/*//获取连接RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();connection.flushAll();connection.flushDb();*///往redis中放值redisTemplate.opsForValue().set("mykey","hello redis");//取值System.out.println(redisTemplate.opsForValue().get("mykey"));}}

4、序列化

为什么要序列化
1、当传入未序列化的实体类时,redis会报错
2、使用默认redis默认的Template时,向数据库中插入了一个中文字符串,虽然在 Java 端可以看到返回了中文,但是在 Redis 中查看是一串乱码。

可直接使用的redisTemplate模板

package com.jjl.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.net.UnknownHostException;@Configuration
public class RedisConfig {/***  编写自定义的 redisTemplate*  这是一个比较固定的模板*/@Bean@SuppressWarnings("all")public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {// 为了开发方便,直接使用<String, Object>RedisTemplate<String, Object> template = new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);// Json 配置序列化// 使用 jackson 解析任意的对象Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);// 使用 objectMapper 进行转义ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);// String 的序列化StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key 采用 String 的序列化方式template.setKeySerializer(stringRedisSerializer);// Hash 的 key 采用 String 的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value 采用 jackson 的序列化方式template.setValueSerializer(jackson2JsonRedisSerializer);// Hash 的 value 采用 jackson 的序列化方式template.setHashValueSerializer(jackson2JsonRedisSerializer);// 把所有的配置 set 进 templatetemplate.afterPropertiesSet();return template;}
}

测试

127.0.0.1:6379> keys *
1) "user"
127.0.0.1:6379>

5、redis工具类

在项目真实开发中,基本不会使用redis自带的redisTemplate
因此为了方便所以会自定义一个工具类

package com.zxy.demo.redis;import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;/*** Redis工具类* @author ZENG.XIAO.YAN* @date   2018年6月7日*/
@Component
public final class RedisUtil {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;// =============================common============================/*** 指定缓存失效时间* @param key 键* @param time 时间(秒)* @return*/public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据key 获取过期时间* @param key 键 不能为null* @return 时间(秒) 返回0代表为永久有效*/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断key是否存在* @param key 键* @return true 存在 false不存在*/public boolean hasKey(String key) {try {return redisTemplate.hasKey(key);} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除缓存* @param key 可以传一个值 或多个*/@SuppressWarnings("unchecked")public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete(CollectionUtils.arrayToList(key));}}}// ============================String=============================/*** 普通缓存获取* @param key 键* @return 值*/public Object get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通缓存放入* @param key 键* @param value 值* @return true成功 false失败*/public boolean set(String key, Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 普通缓存放入并设置时间* @param key 键* @param value 值* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public boolean set(String key, Object value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);} else {set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 递增* @param key 键* @param delta 要增加几(大于0)* @return*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 递减* @param key 键* @param delta 要减少几(小于0)* @return*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return redisTemplate.opsForValue().increment(key, -delta);}// ================================Map=================================/*** HashGet* @param key 键 不能为null* @param item 项 不能为null* @return 值*/public Object hget(String key, String item) {return redisTemplate.opsForHash().get(key, item);}/*** 获取hashKey对应的所有键值* @param key 键* @return 对应的多个键值*/public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);}/*** HashSet* @param key 键* @param map 对应多个键值* @return true 成功 false 失败*/public boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** HashSet 并设置时间* @param key 键* @param map 对应多个键值* @param time 时间(秒)* @return true成功 false失败*/public boolean hmset(String key, Map<String, Object> map, long time) {try {redisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建* @param key 键* @param item 项* @param value 值* @return true 成功 false失败*/public boolean hset(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建* @param key 键* @param item 项* @param value 值* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间* @return true 成功 false失败*/public boolean hset(String key, String item, Object value, long time) {try {redisTemplate.opsForHash().put(key, item, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除hash表中的值* @param key 键 不能为null* @param item 项 可以使多个 不能为null*/public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);}/*** 判断hash表中是否有该项的值* @param key 键 不能为null* @param item 项 不能为null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}/*** hash递增 如果不存在,就会创建一个 并把新增后的值返回* @param key 键* @param item 项* @param by 要增加几(大于0)* @return*/public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash递减* @param key 键* @param item 项* @param by 要减少记(小于0)* @return*/public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);}// ============================set=============================/*** 根据key获取Set中的所有值* @param key 键* @return*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {e.printStackTrace();return null;}}/*** 根据value从一个set中查询,是否存在* @param key 键* @param value 值* @return true 存在 false不存在*/public boolean sHasKey(String key, Object value) {try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {e.printStackTrace();return false;}}/*** 将数据放入set缓存* @param key 键* @param values 值 可以是多个* @return 成功个数*/public long sSet(String key, Object... values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 将set数据放入缓存* @param key 键* @param time 时间(秒)* @param values 值 可以是多个* @return 成功个数*/public long sSetAndTime(String key, long time, Object... values) {try {Long count = redisTemplate.opsForSet().add(key, values);if (time > 0)expire(key, time);return count;} catch (Exception e) {e.printStackTrace();return 0;}}/*** 获取set缓存的长度* @param key 键* @return*/public long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 移除值为value的* @param key 键* @param values 值 可以是多个* @return 移除的个数*/public long setRemove(String key, Object... values) {try {Long count = redisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {e.printStackTrace();return 0;}}// ===============================list=================================/*** 获取list缓存的内容* @param key 键* @param start 开始* @param end 结束 0 到 -1代表所有值* @return*/public List<Object> lGet(String key, long start, long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取list缓存的长度* @param key 键* @return*/public long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 通过索引 获取list中的值* @param key 键* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推* @return*/public Object lGetIndex(String key, long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 将list放入缓存* @param key 键* @param value 值* @param time 时间(秒)* @return*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存* @param key 键* @param value 值* @param time 时间(秒)* @return*/public boolean lSet(String key, Object value, long time) {try {redisTemplate.opsForList().rightPush(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存* @param key 键* @param value 值* @param time 时间(秒)* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存* * @param key 键* @param value 值* @param time 时间(秒)* @return*/public boolean lSet(String key, List<Object> value, long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据索引修改list中的某条数据* @param key 键* @param index 索引* @param value 值* @return*/public boolean lUpdateIndex(String key, long index, Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 移除N个值为value* @param key 键* @param count 移除多少个* @param value 值* @return 移除的个数*/public long lRemove(String key, long count, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}}
}

六、dubbo及Zookeeper安装测试

狂神说SpringBoot17:Dubbo和Zookeeper集成

1、源码下载

  • 下载:apache-zookeeper-3.8.0-bin.tar.gz
  • 下载:incubator-dubbo-ops-develop

2、解压运行

1、apache-zookeeper-3.8.0-bin.tar.gz
将apache-zookeeper-3.8.0-bin\conf的zoo_sample.cfg复制一个为zoo.cfg

并且在里面添加一行,修改它默认admin服务端口(8080):admin.serverPort=8088,因为dubbo-server启动时需要8080



测试:

zookeeper启动成功

2、incubator-dubbo-ops-develop
测试文档参考:Dubbo控制台


七、springboot整合分布式

1、开始zookeeper和dubbo-admin服务

2、创建一个springboot项目模拟分布式接口提供者

1、创建spring boot项目,导入一个web依赖

2、导入zookeeper和dubbo的依赖

<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.1.0</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-dependencies-zookeeper --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-dependencies-zookeeper</artifactId><version>3.1.0</version><type>pom</type></dependency><!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient --><dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version></dependency>

3、创建一个service接口

package com.jjl.service;public interface TicketService{public String getTicket();
}

4、创建一个serviceImpl接口实现接口

导入两个注解

  • import org.apache.dubbo.config.annotation.DubboService;
  • import org.springframework.stereotype.Component;
package com.jjl.service;import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;@DubboService // 被扫描并注册到注册中心
@Component //将接口放入容器中
public class TicketServiceImpl implements TicketService{@Overridepublic String getTicket() {return "远程调用测-服务端";}
}

5、配置application.properties
由于是本机模拟远程,需要启动两springboot项目,会涉及端口冲突,还有idea热部署问题

  • 修改springboot默认端口
  • 修改dubbo服务端口
  • 配置提供者这名字
  • 配置注册中心ip
server.port=8001# 服务应用名字
dubbo.application.name=prioder-server
# 注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
# 那些服务要被注册
dubbo.scan.base-packages=com.jjl.servicedubbo.protocol.name=dubbo
dubbo.protocol.port=20881
dubbo.protocol.host=192.168.58.44

6、启动项目,在dubbo-admin中查看服务是否被注册

3、创建一个springboot项目模拟分布式接口消费者

1、创建spring boot项目,导入一个web依赖

2、导入zookeeper和dubbo的依赖(与提供者依赖一样)

3、新建service目录,在目录中创建一个与提供者项目中一模一样的接口,因为消费者需要靠这个接口名称去注册中心寻址

4、创建一个模拟调用远程方法的类

注意导入的两个注解

  • import org.apache.dubbo.config.annotation.DubboReference;
  • import org.springframework.stereotype.Service;
package com.jjl.service;import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;@Service  //放在容器中
public class UserService {//拿到prioder里面的方法@DubboReference //远程调用TicketService ticketService;public void BuyTicket(){String ticket = ticketService.getTicket();System.out.println("通过远处调用在注册中心成功调取接口==> " + ticket);}
}

5、配置application.properties

  • 修改springboot端口

  • 配置消费者项目名称

  • 配置注册中心ip

    server.port=8090
    # 当前服务名字
    dubbo.application.name=consumer-server
    #注册中心地址
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    

6、编写测试类

package com.jjl;import com.jjl.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class ConsumerServerApplicationTests {@AutowiredUserService userService;@Testvoid contextLoads() {userService.BuyTicket();}}

7、处理ieda启动多个项目,报端口被占用问题


8、启动测试类,调用远程方法

9、查看dubbo

springBoot_swagger、异步任务、邮件发送、定时任务、集成redis、分布式(Dubbo、Zookeeper)相关推荐

  1. Redis分布式锁 Spring Schedule实现任务调度

    一看到标题就知道,这一篇博客又是总结分布式工作环境中集群产生的问题,个人觉得分布式没有那么难以理解,可能也是自己见识比较浅,对我来说,分布式只是一种后端业务演进时的一种工作方式,而真正实现这种工作方式 ...

  2. Java全能手册火了!Redis/Nginx/Dubbo/Spring全家桶啥都有!

    前言 本文是为了帮大家快速回顾了Java中知识点,这套面试手册涵盖了诸多Java技术栈的面试题和答案,相信可以帮助大家在最短的时间内用作面试复习,能达到事半功倍效果. 本来想将文件上传到github上 ...

  3. 利用Spring框架封装的JavaMail现实同步或异步邮件发送

    利用Spring框架封装的JavaMail现实同步或异步邮件发送 作者:张纪豪 J2EE简单地讲是在JDK上扩展了各类应用的标准规范,邮件处理便是其中一个重要的应用.它既然是规范,那么我们就可以通过J ...

  4. mysql自动备份发邮箱,定时任务自动备份数据库并邮件发送

    我原本是使用Vastar的第一个脚本方案来自动备份WordPress数据库并邮件发送的,不过后来因为更换服务器,不知道为什么造成了会二次备份并有错误提示.刚好Vastar又给了一个更简洁的方法,于是昨 ...

  5. Spring Boot最新版集成邮件发送功能大全

    Spring Boot最新版集成邮件发送功能大全 前言 一.开启SMTP服务并获取授权码 二.创建Spring Boot项目 1.配置邮箱基本信息: 2.简单邮件发送: 3.发送带附件的邮件: 5.使 ...

  6. SpringBoot整合定时任务和邮件发送(邮箱 信息轰炸 整蛊)

    SpringBoot整合定时任务和邮件发送(邮箱 信息轰炸 整蛊) 目录 SpringBoot整合定时任务和邮件发送(邮箱 信息轰炸 整蛊) 1.概述 2.最佳实践 2.1创建项目引入依赖(mail) ...

  7. node.js集成sendgrid邮件发送及其它功能

    1.简介 https://github.com/sendgrid/sendgrid-nodejs 这个是sendgrid官方的nodejs库,可以方便的集成sendgrid功能 2.分包 @ send ...

  8. python-flask(二)集成bootstrap、集成web表单、集成邮件发送

    文章目录 一.flask集成bootstrap 1. 什么是Bootstrap? 2. Flask中如何集成Bootstrap? 3. Flask-Bootstrap实现了什么? 二.Flask中集成 ...

  9. java发送s mime邮件_SpringBoot集成实现各种邮件发送

    JavaMail是提供给开发者处理电子邮件相关的编程接口.它是Sun发布的用来处理email的API.正常我们会用JavaMail相关api来写发送邮件的相关代码. 使用过Spring的众多开发者都知 ...

最新文章

  1. Hulu视频如何提升推荐多样性?
  2. 2018年强化学习领域十篇重要论文(附源码)
  3. Jquery 改变样式
  4. 【原创】QT在嵌入式系统中显示中文的方法
  5. 论文浅尝 | 用图网络做小样本学习
  6. 算法真的太重要了!CSDN用动画帮你快速 get 核心原理
  7. 收藏功能_六款多功能榻榻米,装完你家会大一半!超实用,收藏
  8. 如何使用十六进制颜色值
  9. xgboost的原理没你想像的那么难
  10. Dubbo负载均衡算法初步解析
  11. Arduino GPS 车速表(Arduino流体力学燃油效率计)(更新:2022.7.3)
  12. socks5 python_用Python写socks5服务器端
  13. length()、size()、sizeof()三者的区别
  14. 基于PHP+MySQL的服装购物商城系统#毕业设计
  15. 录制失败因为媒体服务失败_杨丽萍62岁被判人生失败,因为她一生无子女.........
  16. VMware 兼容性列表与产品互操作性列表使用收集(持续更新中...)
  17. java设计模式之状态机模式
  18. 基于FPGA的卷积神经网络实现(七)数据读写
  19. android 虹软人脸存储,用虹软Android SDK做人脸识别
  20. POJ - 1579 Function Run Fun

热门文章

  1. 进制的转换规则简单口诀
  2. 关于计算机的英语演讲稿三分钟,大学英语演讲稿3分钟
  3. 开火车的纸牌游戏-python版本
  4. 计算机win10+上锁,老司机应对win10系统给电脑屏幕上锁的方案
  5. 搅拌站ERP:砼车过磅流程
  6. java application 路径_java项目获取根路径(web项目和application项目的区分)
  7. JSP高校学生积分管理系统myeclipse开发mysql数据库bs框架java编程jdbc详细设计
  8. 知识变现海哥|如何运营一个培训类社群
  9. 蓝奏云文件真实地址分析
  10. 界面扩大缩小操作按钮_《微图4.0》软件功能界面说明1.0