spring官网:https://spring.io/
https://mp.weixin.qq.com/mp/homepage?__biz=Mzg2NTAzMTExNg==&hid=1&sn=3247dca1433a891523d9e4176c90c499
该笔记记录的是SpringBoot2,更新的SpringBoot3版本需要参考最新官方文档
文章目录- SpringBoot基础(二)
- 7、连接数据库
- 7.0 SpringData
- 7.1 整合JDBC
- 7.2 整合Druid
- 7.3 整合Mybatis
- 使用例
- 8、信息安全
- 8.1 spring Security
- 8.1.1 环境搭建
- 8.1.2 认证和授权
- 8.1.3 权限控制和注销
- 8.1.4 记住我功能
- 8.1.5 定制登录页
- SecurityConfig完整代码
- 8.2 Shiro
- 8.2.0 Shiro外部架构
- 8.2.1 使用例
- 8.2.2 springboot整合shiro
- 实现登录拦截
- 实现用户认证
- 整合Mybatis
- 请求授权实现
- 整合thymeleaf
- 9、Swagger
- 前后端分离
- 9.1 springboor集成Swagger
- 9.2 配置swagger
- 9.3 Swagger配置扫描接口
- 9.4 API文档的分组和接口注释
- 小结
- 10、任务
- 10.1 异步任务
- 10.2 邮件任务
- 10.3 定时任务
- 11、Redis
- 11.1 使用例
- 11.2 自定义RedisTemplate
- 12、分布式(待完善)
- 12.1 分布式(待完善)
- 前置内容
- Dubbo概念
- zookeeper
- 安装dubbo-admin
- 12.2 分布式Dubbo+Zookeeper+SpringBoot
- 步骤
- 步骤
对于数据访问层,无论是 SQL 还是 NoSQL,Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。
SpringData官网:https://spring.io/projects/spring-data
数据库相关启动器:https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter
7.1 整合JDBC创建一个springboot项目,引入JDBC相关依赖
自动生成的pom.xml依赖
org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-web mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-test test
编写application.yml配置文件连接数据库
spring:
datasource:
username: root
password: 密码
#?serverTimezone=UTC用于解决时区报错
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
springboot底层会处理这些配置内容。接下来可以直接使用jdbc
@SpringBootTest
public class SpringbootDataJdbcTest {
//注入数据源。配置文件完成后,底层会构造出dataSource对象
@Resource
DataSource dataSource;
@Test
public void contextLoads() throws SQLException{
//查看默认的数据源
System.out.println(dataSource.getClass());
//获取连接
Connection connection = dataSource.getConnection();
System.out.println(connection);
//关闭连接
connection.close();
}
}
注:项目创建后会生成一个总测试类,自己写的测试类要和这个总测试类处于同级目录
输出
由输出可以看到,默认配置的数据源是class com.zaxxer.hikari.HikariDataSource。
数据源的自动配置写在DataSourceAutoConfiguration类中,打开它的源码,源码中有一处默认数据源配置相关的内部类
@Configuration(
proxyBeanMethods = false
)
@Conditional({DataSourceAutoConfiguration.PooledDataSourceCondition.class})
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import({Hikari.class, Tomcat.class, Dbcp2.class, OracleUcp.class, Generic.class, DataSourceJmxConfiguration.class})
protected static class PooledDataSourceConfiguration {
protected PooledDataSourceConfiguration() {
}
}
源码中通过@Import注解导入了Hikari.class,即前面打印的默认配置数据源。
可以在配置文件中设置spring.datasources.type的值来配置数据源类型(mysql、oracle…)。
JDBCTemplate
目的和MyBatis差不多,都是为了简化数据库相关的代码书写。JDBCTemplate也是springboot底层的一个默认配置。
相关配置类是JdbcTemplateConfiguration。
常用方法:
- excute:执行sql语句
- update、batchUpdate:前者执行增删改语句,后者执行批处理相关语句
- query、queryForXXX:执行查询语句
- call:执行存储过程、函数相关的语句
使用例
编写一个Controller,注入 jdbcTemplate,编写测试方法进行访问测试.
@RestController
@RequestMapping("/jdbc")
public class JdbcController {
//使用默认配置的JdbcTemplate
@Autowired
JdbcTemplate jdbcTemplate;
//查
//List 中的一个 Map 对应数据库的一行数据
//Map 中的 key 对应数据库的字段名,value 对应数据库的字段值
@GetMapping("/list")
public List
测试
7.2 整合Druid开源仓库:https://github.com/alibaba/druid
Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。Druid能够提供强大的监控和扩展功能。
com.alibaba.druid.pool.DruidDataSource 基本配置参数:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8
添加依赖
com.alibaba druid 1.2.8
在配置文件中修改数据源类型
spring:
datasource:
username: root
password: 密码
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源
利用之前写好的SpringbootDataJdbcTest测试类打印查看当前的默认数据源
根据官方提供的参数,在配置文件中进行设置。
spring:
datasource:
username: root
password: 密码
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源
#以下属性Spring Boot 默认不注入,需要自己配置
#druid 数据源专有配置
initialSize: 5 #连接池初始化大小
minIdle: 5 #最小连接池数量
maxActive: 20 #最大连接数
maxWait: 60000 #最大等待时间
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters。stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入 log4j 依赖即可
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
导入Log4j依赖
log4j log4j 1.2.17
配置文件中写好的Druid参数需要手动绑定属性,再添加到容器中。
创建一个config.DruidConfig类进行绑定
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix="spring.datasource")
@Bean
public DataSource druidDataSource(){
return (DataSource) new DruidDataSource();
}
}
测试类
@SpringBootTest
public class SpringbootDataDruidTest {
@Autowired
DataSource dataSource;
@Test
public void contextLoads() throws SQLException{
System.out.println(dataSource.getClass());
Connection connection = dataSource.getConnection();
System.out.println(connection);
DruidDataSource druidDataSource=(DruidDataSource) dataSource;
System.out.println("druidDateSource 数据源的最大连接数:"+druidDataSource.getMaxActive());
System.out.println("druidDateSource 数据源的初始化连接数:"+druidDataSource.getInitialSize());
connection.close();
}
}
输出
配置Druid数据源监控
Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看。
在DruidConfig类中添加以下方法来设置 Druid 的后台管理页面,如账号、密码。
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid
Map filterMap=new LinkedHashMap<>();
filterMap.put("/user/add","authc");
filterMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
//......
}
编写一个登录页面templates/login.html
在MyController中添加相关方法
@RequestMapping("/toLogin")
public String toLogin() {
return "login";
}
在ShiroConfig的getShiroFilterFactoryBean()方法中设置登录的请求
@Bean(name="shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(
@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager);
Map filterMap=new LinkedHashMap<>();
filterMap.put("/user/add","authc");
filterMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录请求
bean.setLoginUrl("/toLogin");
return bean;
}
实现用户认证
在MyController中添加登录请求相关方法
@RequestMapping("/login")
public String login(String username,String password,Model model){
//获取当前的用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
subject.login(token); //登录
return "index";
}
catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误");
return "login";
}
catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}
修改login.html中的内容
在UserRealm中修改认证方法
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>授权doGetAuthenticationInfo");
//用户名,密码。这里先不从数据库中取
String name="root";
String password="123456";
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
if(!userToken.getUsername().equals(name)){
return null; //用户名错误
}
//密码认证
return new SimpleAuthenticationInfo("",password,"");
}
整合Mybatis
导入依赖
org.projectlombok lombok mysql mysql-connector-java log4j log4j 1.2.17 com.alibaba druid 1.1.12 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.3
编写application.yml,进行如下配置
spring:
datasource:
username: root
password: 密码
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源
#以下属性Spring Boot 默认不注入,需要自己配置
#druid 数据源专有配置
initialSize: 5 #连接池初始化大小
minIdle: 5 #最小连接池数量
maxActive: 20 #最大连接数
maxWait: 60000 #最大等待时间
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters。stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入 log4j 依赖即可
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
在application.properties中配置mybatis相关选项
mybatis.type-aliases-package=com.infinite.shirosptingboot.pojo
mybatis.mapper-locations=classpath:mapper
@Scheduled(cron="0/2 * * * * ?") //每2秒执行一次
public void hello(){
System.out.println("hello ,schedule test");
}
}
cron表达式
cron在线生成器
11、Redishttps://spring.io/projects/spring-data-redis
新建一个springboot项目,导入lombok、springbootdevtools、springConfigurationProcessor、springWeb这几个基础依赖,再导入一个SpringDataRedis(Access+Driver)依赖
注:springboot2.x后,原本使用的jedis被替换成了lettuce
jedis:采用直连方式,多线程操作的情况下不安全,若要避免,需要用到jedis pool连接池。更像BIO模式
lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况,可以减少线程数据。更像NIO模式
源码
相关自动配置类RedisAutoConfiguration、配置类RedisProperties
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
) //若自己实现了一个redisTemplate,则可以替换掉这个默认的模板
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate
11.1 使用例
依赖
org.springframework.boot spring-boot-starter-data-redis
完善配置文件内容
#配置redis spring.redis.host=127.0.0.1 spring.redis.port=6379
编写一个测试类
@SpringBootTest
class Springboot08RedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//redisTemplate 可以操作不同的数据类型
//opsForValue 操作字符串
//opsForList 操作list
//其他redis中的数据类型同理
//除了基本操作,还可以执行事务和基本的CRUD
// 获取redis的连接对象(不常用)
//RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//connection.flushDb();
//connection.flushAll();
redisTemplate.opsForValue().set("myKey","infinite");
System.out.println(redisTemplate.opsForValue().get("myKey"));
}
}
注:本地要先开启redis服务
11.2 自定义RedisTemplate进入RedisTemplate源码,会发现有几个RedisSerializer属性,这些属性是RedisTemplate的序列化配置
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (this.defaultSerializer == null) {
// JdkSerializationRedisSerializer 表示默认选择jdk序列化
this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}
//......
}
假如要实现用json序列化,可以自己实现一个RedisTemplate,内部具体实现可以参考RedisAutoConfiguration的源码
创建config.RedisConfig
@Configuration
public class RedisConfig {
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
编写实体类pojo.User
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
private String name;
private int age;
}
编写测试方法
@Test
public void test() throws JsonProcessingException {
User user=new User("infinite",20);
//进行json序列化,redis中存入json字符串。推荐使用json传输数据
String jsonUser = new ObjectMapper().writeValueAsString(user);
redisTemplate.opsForValue().set("user",jsonUser);
System.out.println(redisTemplate.opsForValue().get("user"));
}
假如想要在redis中直接存入对象,则要将对象序列化,即User类要实现Serializable接口。
需求:自定义一个序列化方式
修改RedisConfig代码
//固定模板,完成后就不用再改动了
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
//为了开发使用方便,一般直接使用
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(factory);
//Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//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);
return template;
}
}
为了防止命名冲突,测试类中的redisTemplate需要通过@Qualifier()注解进行标识
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate;
实际开发中,为了提高代码复用性,可以将项目中redis的常见操作进行抽象集成,整合到自定义的RedisUtil工具类中(和之前写jdbc、mybatis同理)。哪个类需要redis操作时,通过@Autowired装配这个工具类即可
可参考的自定义Redis工具类
12、分布式(待完善)分布式系统的定义:分布式系统时若干独立计算机的集合,这些计算机对于用户来说就像单个系统。
分布式系统中的计算机之间通过网络进行通信,目的是利用更多的机器,处理更多的数据
著有当单个结点的处理能力无法满足日益增长的计算、存储任务,且硬件提升的成本高、应用程序难以进一步优化的时候,才需要考虑分布式系统。
12.1 分布式(待完善) 前置内容背景
https://dubbo.apache.org/zh/index.html
背景相关的内容可以查看https://dubbo.apache.org/zh/docsv2.7/user/preface/background/
RPC
RPC(Remote Procedure Call):远程过程调用,是一种进程间的通信方式,本质是一种思想而非规范。RPC允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不是程序员显式编码这个远程调用的细节,即调用本地和调用远程两种方式的代码基本是相同的。
例:现有两台服务器A、B,一个应用部署在A上,A现在想要调用B服务器上应用提供的函数/方法,由于不再一个内存空间中,A不能直接进行调用,需要通过网络来表达调用的予以和传输调用的数据。
为什么要用到RPC?假设有一个业务,它无法在一个进程内(或一台计算机内)通过本地调用的方式完成,比如不同系统(组织)之间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用,RPC实现的就是要项调用本地的函数一样去调用远程的函数。
https://www.jianshu.com/p/2accc2840a1b
RPC的两个核心模块:通讯、序列化(方便数据传输)
Dubbo概念Dubbo是一款高性能、轻量级的开源java RPC框架。它提供了三大核心功能:面向接口的远程方法调用、只能容错和负载均衡、服务自动注册和实现
https://dubbo.apache.org/zh/docs/concepts/service-discovery/
- Provider(服务提供者): 向服务提供方暴露服务,服务提供者在启动时,向注册中心注册自己提供的服务。
- Consumer(服务消费者): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务。消费者从提供者的地址列表中,基于软负载均衡算法,选择一台提供者进行调用,如果调用失败就换一台。
- Registry(注册中心): 返回服务提供者的地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- Monitor(监控中心): 服务消费者和提供者,让内存中累计调用次数和调用时间,每分钟发送一次统计数据到监控中心
充当注册中心的一个开源项目
使用:
-
下载项目压缩包并解压
-
执行bin/zkServer.cmd,发现闪退。可以在zkServer.cmd添加pause以排错
-
修改conf/zoo.cfg配置文件(没有的话就复制同目录下的zoo_sample.cfg),重新以管理员模式运行bin/zkServer.cmd,以及bin.zkCli.cmd
修改zoo.cfg中的dataDir、dataLogDirdataDir=C:TOOLSapache-zookeeper-3.8.0data dataLogDir=C:TOOLSapache-zookeeper-3.8.0log
可能出现的问题
1.ZooKeeper audit is disabled 修改zkServer.cmd ,call %JAVA%中添加"-Dzookeeper.audit.enable=true"
客户端下测试
ls /:列出zookeeper根下保存的所有节点
create -e /indinite : 创建一个节点,后面如果跟一个值可以设置存放的内容
get /infinite: 获取/infinite节点的信息
安装dubbo-admin这是一个springboot项目,作为监控管理后台,查看注册了哪些服务
去github上下载源码并解压
进入项目,解压lib中的jar包,修改dubbo-adminsrcmainresourcesapplication.properties文件中指定的zookeeper地址(默认为本地)
dubbo.registry.address=zookeeper://127.0.0.1:2181
打包项目
C:TOOLSdubbo-admin-0.2.0>mvn clean package -D maven.test.skip=true
可能会打包失败,可以参考https://blog.csdn.net/qq_43612538/article/details/103548650
最终打包成dubbo-admin-0.0.1-SNAPSHOT.jar
先启动zookeeper的service端,再启动这个的jar包
12.2 分布式Dubbo+Zookeeper+SpringBoot新建一个空项目
新建一个provider-server模块(spring),进入这个模块,端口配置为server.port=8001
新建接口service.TicketService
public interface TicketService {
public String getTicket();
}
实现接口
public class TicketServiceImpl implements TicketService{
@Override
public String getTicket(){
return "infinite";
}
}
新建一个consumer-server模块(spring),进入这个模块,端口配置为server.port=8002
创建service.UserService类
导入依赖(两个模块分别导入)
org.apache.dubbo dubbo-spring-boot-starter 3.0.7 com.github.sgroschupf zkclient 0.1 org.apache.curator curator-framework 4.0.1 org.apache.curator curator-recipes 4.0.1 org.apache.zookeeper zookeeper 3.4.13 org.slf4j slf4j-log4j12
完善provider-server的配置文件
server.port=8001 #服务应用名 dubbo.application.name=provider-server #注册中心地址 dubbo.registry.address=zookeeper://127.0.0.1:2181 #哪些服务需要注册 dubbo.scan.base-packages=com.infinite.service
给TicketServiceImpl添加dubbo的@DubboService注解,启动时可以被扫描到并注册
@DubboService
public class TicketServiceImpl implements TicketService{
@Override
public String getTicket(){
return "infinite";
}
}
给主启动类添加@EnableDubbo注解
启动zookeeper的服务端,再启动provider-server,测试是否注册成功
完善consumer-server的配置
server.port=8002 # 消费者去哪里拿服务。需要暴露自己的名字 dubbo.application.name=consumer-server # 注册中心的地址 dubbo.registry.address=zookeeper://127.0.0.1:2181
在service目录下复制一份provider-server的TicketService接口。
完善UserService
@DubboService
public class UserService {
@DubboReference //引用,获取provider-server提供的类
TicketService ticketService; //同目录下复制了同一份接口,用于引用
public void butTicket(){
String ticket=ticketService.getTicket();
System.out.println("在注册中心拿到==>"+ticket);
}
}
编写测试
步骤
前提:开启zookeeper服务
- 提供者提供服务
- 导入依赖
- 配置注册中心的地址,以及服务发现名、要扫描的包
- 在想要被注册的服务上,增加一个注解@DubboService
- 消费者如何消费
- 导入依赖
- 配置注册中心的地址,配置自己的服务名
- 从远程注入服务@DubboReference
新建一个provider-server模块(spring),进入这个模块,端口配置为server.port=8001
新建接口service.TicketService
public interface TicketService {
public String getTicket();
}
实现接口
public class TicketServiceImpl implements TicketService{
@Override
public String getTicket(){
return "infinite";
}
}
新建一个consumer-server模块(spring),进入这个模块,端口配置为server.port=8002
创建service.UserService类
导入依赖(两个模块分别导入)
org.apache.dubbo dubbo-spring-boot-starter 3.0.7 com.github.sgroschupf zkclient 0.1 org.apache.curator curator-framework 4.0.1 org.apache.curator curator-recipes 4.0.1 org.apache.zookeeper zookeeper 3.4.13 org.slf4j slf4j-log4j12
完善provider-server的配置文件
server.port=8001 #服务应用名 dubbo.application.name=provider-server #注册中心地址 dubbo.registry.address=zookeeper://127.0.0.1:2181 #哪些服务需要注册 dubbo.scan.base-packages=com.infinite.service
给TicketServiceImpl添加dubbo的@DubboService注解,启动时可以被扫描到并注册
@DubboService
public class TicketServiceImpl implements TicketService{
@Override
public String getTicket(){
return "infinite";
}
}
给主启动类添加@EnableDubbo注解
启动zookeeper的服务端,再启动provider-server,测试是否注册成功
完善consumer-server的配置
server.port=8002 # 消费者去哪里拿服务。需要暴露自己的名字 dubbo.application.name=consumer-server # 注册中心的地址 dubbo.registry.address=zookeeper://127.0.0.1:2181
在service目录下复制一份provider-server的TicketService接口。
完善UserService
@DubboService
public class UserService {
@DubboReference //引用,获取provider-server提供的类
TicketService ticketService; //同目录下复制了同一份接口,用于引用
public void butTicket(){
String ticket=ticketService.getTicket();
System.out.println("在注册中心拿到==>"+ticket);
}
}
编写测试
步骤
前提:开启zookeeper服务
- 提供者提供服务
- 导入依赖
- 配置注册中心的地址,以及服务发现名、要扫描的包
- 在想要被注册的服务上,增加一个注解@DubboService
- 消费者如何消费
- 导入依赖
- 配置注册中心的地址,配置自己的服务名
- 从远程注入服务@DubboReference



