【6】3-SpringBoot 操作数据库
SpringBoot操作数据库
1.整合JDBC
SpringData简介
-
对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。
-
Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。
-
Sping Data 官网:https://spring.io/projects/spring-data
-
数据库相关的启动器 :弹簧启动参考文档 (spring.io)
整合JDBC
- 导入测试数据库
- 新建一个项目测试:springboot-data-jdbc; 引入相应的模块!基础模块
- 项目建好之后,发现自动帮我们导入了如下的启动器:
- 编写yaml配置文件连接数据库;
- 配置完这一些东西后,就可以直接去使用了!因为SpringBoot已经默认帮我们进行了自动配置;去测试类测试一下:
- 结果:可以看到他默认给我们配置的数据源为: class com.zaxxer.hikari.HikariDataSource,我们并没有手动配置。
- 来全局搜索一下,找到数据源的所有自动配置都在:DataSourceAutoConfiguration文件:
- 这里导入的类都在 DataSourceConfiguration 配置类下,可以看出 Spring Boot 2.6.3默认使用 HikariDataSource 数据源,而以前版本,如 Spring Boot 1.5默认使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源;
- HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;
- 可以使用 spring.datasource.type 指定自定义的数据源类型,值为要使用的连接池实现的完全限定名。
- 关于数据源不做过多介绍,有了数据库连接,显然就可以CRUD操作数据库了。但是仍需要先了解一个对象——
JdbcTemplate
。
JdbcTemplate
- 有了数据源(com.zaxxer.hikari.HikariDataSource),然后可以拿到数据库连接 (java.sql.Connection),有了连接,就可以使用原生的 JDBC 语句来操作数据库;
- 即使不使用第三方第数据库操作框架,如 MyBatis等,Spring 本身也对原生的JDBC 做了轻量级的封装,即
JdbcTemplate
。 - 数据库操作的所有 CRUD 方法都在 JdbcTemplate 中。
- Spring Boot不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用。
- JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的JdbcTemplateConfiguration类。
JdbcTemplate主要提供以下几类方法:
- execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
- update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate 方法用于执行批处理相关语句;
- query方法及queryForXXX方法:用于执行查询相关语句;
- call方法:用于执行存储过程、函数相关语句。
测试案例
- 编写一个Controller,注入jdbcTemplate,编写测试方法进行访问测试;
至此,CURD的基本操作,使用 JDBC 就搞定了。
2.整合Druid
Druid 简介
- Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。
- Druid是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等DB池的优点,同时加入了日志监控。
- Druid可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的DB连接池。
- Spring Boot 2.0 以上默认使用Hikari数据源,可以说Hikari与Driud都是当前Java Web上最优秀的数据源,我们来重点介绍Spring Boot如何集成Druid数据源,如何实现数据库监控。
- Github地址:https://github.com/alibaba/druid
com.alibaba.druid.pool.DruidDataSource 基本配置参数如下:
配置 | 缺省值 | 说明 |
---|---|---|
name | 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。如果没有配置,将会生成一个名字,格式是:"DataSource-" + System.identityHashCode(this). | |
url | 连接数据库的url,不同数据库不一样。例如: mysql: jdbc:mysql://10.20.153.104:3306/druid2 oracle: jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
username | 连接数据库的用户名 | |
password | 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。 | |
driverClassName | 根据url自动识别 | 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName |
initalSize | 0 | 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时 |
maxActive | 8 | 最大连接池数量 |
maxIdle | 8 | 已经不再使用,配置了也没效果 |
minIdle | 最小连接池数量 | |
maxWait | 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 | |
poolPreparedStatements | false | 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 |
maxOpenPreparedStatements | -1 | 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 |
validationQuery | 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。 | |
validationQueryTimeout | 单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法。 | |
testOnBorrow | true | 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 |
testOnReturn | false | 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 |
testWhileIdle | false | 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 |
timeBetweenEvictionRunsMillis | 1分钟 (1.0.14) | 有两个含义: 1) Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接 2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明。 |
numTestsPerEvictionRun | 不再使用,一个DruidDataSource只支持一个EvictionRun | |
numTestsPerEvictionRun | 30分钟 (1.0.14) | 连接保持空闲而不被驱逐的最长时间 |
connectionInitSqls | 物理连接初始化的时候执行的sql | |
exceptionSorter | 根据dbType自动识别 | 当数据库抛出一些不可恢复的异常时,抛弃连接 |
filters | 属性类型是字符串,通过别名的方式配置扩展插件,常用 的插件有:监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall | |
proxyFilters | 类型是List,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系 |
配置数据源
- 添加上Druid数据源依赖。
- 切换数据源;之前已经说过 Spring Boot 2.0 以上默认使用com.zaxxer.hikari.HikariDataSource数据源,但可以通过spring.datasource.type指定数据源。
- 数据源切换之后,在测试类中注入DataSource,然后获取到它,输出一看便知是否成功切换;
- 切换成功!既然切换成功,就可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等设置项;可以查看源码。
- 导入Log4j的依赖
- 为DruidDataSource 绑定全局配置文件中的参数,再添加到容器中,而不再使用Spring Boot的自动生成了;需要自己添加DruidDataSource组件到容器中,并绑定属性;
- 去测试类中测试一下;看是否成功!
- 输出结果:可见配置参数已经生效!
配置 Druid 数据源监控
- Druid 数据源具有监控的功能,并提供了一个web界面方便用户查看,类似安装路由器时,人家也提 供了一个默认的web页面。
- 所以第一步需要设置 Druid 的后台管理页面,比如登录账号、密码等;配置后台管理;
- 配置完毕后,访问: http://localhost:8080/druid/login.html
- 进入之后
- 配置Druid web监控filter过滤器
平时在工作中,按需求进行配置即可,主要用作监控!
3.整合MyBatis
- 官方文档:http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/
- Maven仓库地址:Maven Repository: org.mybatis.spring.boot » mybatis-spring-boot-starter » 2.2.1 (mvnrepository.com)
整合测试
- 导入MyBatis所需要的依赖
- 配置数据库连接信息
- 测试数据库是否连接成功!
- 创建实体类,导入
Lombok
!
- 创建mapper目录以及对应的Mapper接口——
DepartmentMapper.java
!
- 对应的Mapper映射文件——
DepartmentMapper.xml
- maven配置资源过滤问题
既然已经提供了MyBatis 的映射配置文件,自然要告诉spring boot这些文件的位置。
- 编写部门的DepartmentController进行测试!
- 启动项目访问进行测试!
增加一个员工类再测试下,为之后做准备。
- 新建一个pojo类Employee;
- 新建一个EmployeeMapper接口
- 编写EmployeeMapper.xml配置文件
- 编写EmployeeController类进行测试。
测试结果完成!!!
4.SpringSecurity权限控制
1.安全简介
在 Web 开发中,安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题,就可能陷入一个两难的境地:一方面,应用存在严重的安全漏洞,无法满足用户的要求,并可能造成用户的隐私数据被攻击者窃取;另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,因而需要更多的开发时间,影响应用的发布进程。因此,从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中。
-
市面上存在比较有名的:Shiro,Spring Security !
-
这里需要阐述一下的是,每一个框架的出现都是为了解决某一问题而产生了,那么Spring Security框架的出现是为了解决什么问题呢?
-
首先我们看下它的官网介绍:Spring Security官网地址
-
Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它实际上是保护基于spring的应用程序的标准。
-
Spring Security是一个框架,侧重于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring安全性的真正强大之处在于它可以轻松地扩展以满足定制需求。
-
从官网的介绍中可以知道这是一个权限框架。想我们之前做项目是没有使用框架是怎么控制权限的?对于权限 一般会细分为功能权限,访问权限,和菜单权限。代码会写的非常的繁琐,冗余。
怎么解决之前写权限代码繁琐,冗余的问题,一些主流框架就应运而生而Spring Scecurity就是其中的一种。
-
Spring 是一个非常流行和成功的 Java 应用开发框架。Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
-
对于上面提到的两种应用情景,Spring Security 框架都有很好的支持。在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等。在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。
2.实战测试
1.实验环境搭建
- 新建一个初始的springboot项目web模块,thymeleaf模块
- 导入静态资源
- controller跳转!
- 测试实验环境是否OK!
2.认识SpringSecurity
Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!
记住几个类:
- WebSecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
“认证”(Authentication)
-
身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
-
身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
“授权” (Authorization)
-
授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
-
这个概念是通用的,而不是只在Spring Security 中存在。
3.认证和授权
目前,我们的测试环境,是谁都可以访问的,只要使用 Spring Security 增加上认证和授权的功能。
- 引入 Spring Security 模块
- 编写 Spring Security 配置类
-
查看个人项目中的版本,找到对应的帮助文档:Spring Security Reference
- 编写基础配置类
- 定制请求的授权规则
- 测试一下:发现除了首页都进不去了!因为目前没有登录的角色,因为请求需要登录的角色拥有对应的权限才可以!
- 在configure()方法中加入以下配置,开启自动配置的登录功能!
- 测试一下:发现,没有权限的时候,会跳转到登录的页面!
- 查看刚才登录页的注释信息;
- 可以定义认证规则,重写configure(AuthenticationManagerBuilder auth)方法。
- 测试,使用这些账号登录进行测试!发现会报错!
- 原因:要将前端传过来的密码进行某种方式加密,否则就无法登录,修改代码。
- 测试,发现,登录成功,并且每个角色只能访问自己认证下的规则!
4.权限控制和注销
图标库网站:https://semantic-ui.com/
- 开启自动配置的注销的功能
- 在前端,增加一个注销的按钮,index.html 导航栏中。
- 去测试一下,登录成功后点击注销,发现注销完毕会跳转到登录页面!
- 但是,当我们想让他注销成功后,依旧可以跳转到首页,该怎么处理呢?
- 测试,注销完毕后,发现跳转到首页,OK!
- 现在又来一个需求:用户没有登录的时候,导航栏上只显示登录按钮,用户登录之后,导航栏可以显示登录的用户信息及注销按钮!还有就是,比如subei这个用户,它只有 vip2,vip3功能,那么登录则只显示这两个功能,而vip1的功能菜单不显示!这个就是真实的网站情况了!该如何做呢?
需要结合thymeleaf中的一些功能
-
sec:authorize="isAuthenticated()":是否认证登录!来显示不同的页面。
-
Maven依赖:
- 修改前端页面
- 导入命名空间
- 修改导航栏,增加认证判断
- 重启测试,可以登录试试看,登录成功后确实,显示了我们想要的页面;
- 如果注销404了,就是因为它默认防止csrf跨站请求伪造,因为会产生安全问题,可以将请求改为post表单提交,或者在spring security中关闭csrf功能;还可以试试:在配置中增加
http.csrf().disable();
- 继续将下面的角色功能块认证完成!
- 测试一下!
权限控制和注销搞定!
5.记住我
现在的情况:只要登录之后,关闭浏览器,再登录,就会让我们重新登录,但是很多网站的情况,就是有一个记住密码的功能,这个该如何实现呢?很简单
- 开启记住我功能
- 再次启动项目测试一下,发现登录页多了一个记住我功能,登录之后关闭浏览器,然后重新打开浏览器访问,发现用户依旧存在!
思考:如何实现的呢?其实非常简单
- 可以查看浏览器的cookie
- 点击注销的时候,可以发现,spring security 帮我们自动删除了这个cookie。
- 结论:登录成功后,将cookie发送给浏览器保存,以后登录带上这个cookie,只要通过检查就可以免登录了。如果点击注销,则会删除这个cookie,具体的原理参考JavaWeb阶段!
6.定制登录页
现在这个登录页面都是spring security 默认的,怎么样可以使用自己写的Login界面呢?
- 在刚才的登录页配置后面指定 loginpage
- 然后前端也需要指向我们自己定义的 login请求
- 要登录,则需要将这些信息发送到哪里,我们也需要配置,login.html 配置提交请求及方式,方式必须为post:
- 在 loginPage()源码中的注释上有写明:
4、这个请求提交上来,我们还需要验证处理,怎么做呢?我们可以查看formLogin()方法的源码!我们配置接收登录的用户名和密码的参数!
5、在登录页增加记住我的多选框
6、后端验证处理!
- 测试,OK
完整配置代码
5.整合Shiro
1.Shiro简介
1.什么是Shiro?
- Apache Shiro 是一个Java 的安全(权限)框架。
- Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在Java EE环
境。 - Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等。
- 下载地址:http://shiro.apache.org/
2.有哪些功能?
- Authentication:身份认证、登录,验证用户是不是拥有相应的身份;
- Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限,即判断用户能否进行什么操作,如:验证某个用户是否拥有某个角色,或者细粒度的验证某个用户对某个资源是否具有某个权限!
- Session Manager:会话管理,即用户登录后就是第一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通的JavaSE环境,也可以是Web环境;
- Cryptography:加密,保护数据的安全性,如密码加密存储到数据库中,而不是明文存储;
- Web Support:Web支持,可以非常容易的集成到Web环境;
- Caching:缓存,比如用户登录后,其用户信息,拥有的角色、权限不必每次去查,这样可以提高效率
- Concurrency:Shiro支持多线程应用的并发验证,即,如在一个线程中开启另一个线程,能把权限自动的传播过去
- Testing:提供测试支持;
- Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
- Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
3.Shiro架构(外部)
- 从外部来看Shiro,即从应用程序角度来观察如何使用shiro完成工作:
- subject: 应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject, Subject代表了当前的用户,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫,机器人等,与Subject的所有交互都会委托给SecurityManager;Subject其 实是一个门面,SecurityManageer 才是实际的执行者
- SecurityManager:安全管理器,即所有与安全有关的操作都会与SercurityManager交互,并且它 管理着所有的Subject,可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于 SpringMVC的DispatcherServlet的角色
- Realm:Shiro从Realm获取安全数据(如用户,角色,权限),就是说SecurityManager 要验证 用户身份,那么它需要从Realm 获取相应的用户进行比较,来确定用户的身份是否合法;也需要从 Realm得到用户相应的角色、权限,进行验证用户的操作是否能够进行,可以把Realm看成 DataSource;
4.Shiro架构(内部)
- Subject:任何可以与应用交互的 ‘用户’;
- Security Manager:相当于SpringMVC中的DispatcherServlet;是Shiro的心脏,所有具体的交互 都通过Security Manager进行控制,它管理者所有的Subject,且负责进行认证,授权,会话,及缓存的管理。
- Authenticator:负责Subject认证,是一个扩展点,可以自定义实现;可以使用认证策略(Authentication Strategy),即什么情况下算用户认证通过了;
- Authorizer:授权器,即访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的那些功能;
- Realm:可以有一个或者多个的realm,可以认为是安全实体数据源,即用于获取安全实体的,可以用JDBC实现,也可以是内存实现等等,由用户提供;所以一般在应用中都需要实现自己的realm。
- SessionManager:管理Session生命周期的组件,而Shiro并不仅仅可以用在Web环境,也可以用在普通的JavaSE环境中。
- CacheManager:缓存控制器,来管理如用户,角色,权限等缓存的;因为这些数据基本上很少改变,放到缓存中后可以提高访问的性能;
- Cryptography:密码模块,Shiro 提高了一些常见的加密组件用于密码加密,解密等。
2.Hello,Shiro
- 查看官网文档:http://shiro.apache.org/tutorial.html
- 官方的quickstart:https://github.com/apache/shiro/tree/master/samples/quickstart/
1.快速实践
- 创建一个
maven父工程
,用于学习Shiro,删掉不必要的东西。 - 创建一个普通的Maven子工程:shiro-01-helloworld。
- 根据官方文档,导入Shiro的依赖。
- 编写Shiro配置——log4j.properties。
- shiro.ini
- 编写自己的QuickStrat
-
测试运行一下。
-
发现,执行完毕什么都没有,可能是maven依赖中的作用域问题,我们需要将scope作用域删掉,
默认是在test,然后重启,那么我们的quickstart就结束了,默认的日志消息!
- OK!
2.代码解释
- 导入了一堆包!
- 类的描述
- 通过工厂模式创建SecurityManager的实例对象。
- 获取当前的Subject
- session的操作
- 用户认证功能
- 角色检查
- 权限检查,粗粒度
- 权限检查,细粒度
- 注销操作
- 退出系统
System.exit(0)
;
OK,一个简单的Shiro程序体验结束!!!
3.集成shiro
1.准备工作
- 搭建一个SpringBoot项目、选中web模块即可!
- 导入Maven依赖
thymeleaf
- 编写一个页面 index.html——
templates
📂
- 编写controller进行访问测试。
- 访问测试!
2.整合Shiro
回顾核心API:
- Subject:用户主体
- SecurityManager:安全管理器
- Realm:Shiro 连接数据
步骤:
- 导入Shiro 和 spring整合的依赖。
- 编写Shiro 配置类——
config包
- 创建一个realm对象,需要自定义一个realm的类,用来编写一些查询的方法,或者认证与授权的逻辑。
- 将这个类注册到我们的Bean中!——
ShiroConfig
- 创建
DefaultWebSecurityManager
- 创建
ShiroFilterFactoryBean
完整的配置:
3.页面拦截实现
- 编写两个页面、在templates目录下新建一个user目录
add.html、update.html
- 编写跳转到页面的controller
- 在index页面上,增加跳转链接
- 测试页面跳转是否OK
- 准备添加Shiro的内置过滤器
- 再起启动测试,访问链接进行测试!拦截OK!但是发现,点击后会跳转到一个Login.jsp页面,这 个不是我们想要的效果,我们需要自己定义一个Login页面!
- 编写一个个人的Login.html页面
- 编写跳转的controller
- 在shiro中配置一下!
ShiroFilterFactoryBean() 方法下面
- 再次测试,成功的跳转到了我们指定的Login页面!
- 优化一下,使用通配符来操作!
- 测试一下!
4.登录认证操作
- 编写登录的controller
- 在前端修改对应的信息输出或者请求!登录页面增加一个msg提示:
- 给表单增加一个提交地址:
- 测试一下:
- 在UserRealm中编写用户认证的判断逻辑:
- 测试一下!
5.整合数据库
- 导入Mybatis相关依赖
- 编写配置文件-连接配置——
application.yml
- 编写mybatis的配置——
application.properties
- 编写实体类,引入Lombok
- 编写Mapper接口
- 编写Mapper配置文件
- 编写UserService 层
- 测试一下,保证能够从数据库中查询出来。
- 改造UserRealm,连接到数据库进行真实的操作!
- 测试成功!
思考:密码比对原理探究
- 这个Shiro,是怎么帮我们实现密码自动比对的呢?
- 去 realm的父类
AuthorizingRealm
的父类AuthenticatingRealm
中找一个方法; - 核心:
getCredentialsMatcher
() 翻译过来:获取证书匹配器; - 去看这个接口
CredentialsMatcher
有很多的实现类,MD5盐值加密;
- 去 realm的父类
密码一般都不能使用明文保存?
- 需要加密处理;思路分析
- 如何把一个字符串加密为MD5;
- 替换当前的Realm 的 CredentialsMatcher 属性,直接使用
Md5CredentialsMatcher
对象, 并设置加密算法;
6.用户授权操作
使用shiro的过滤器来拦截请求即可!
- 在
ShiroFilterFactoryBean
中添加一个过滤器:
- 再次启动测试一下,访问add,发现以下错误!未授权错误!
- 注意:当我们实现权限拦截后,shiro会自动跳转到未授权的页面,但没有这个页面,所有401了;
- 配置一个未授权的提示的页面,增加一个controller提示;
- 然后再 shiroFilterFactoryBean 中配置一个未授权的请求页面!
- 测试,现在没有授权,可以跳转到我们指定的位置了!
7.用户授权操作
- 在UserRealm 中添加授权的逻辑,增加授权的字符串!
- 再次登录测试,发现登录的用户是可以进行访问add 页面了!授权成功!
问题,我们现在完全是硬编码,无论是谁登录上来,都可以实现授权通过,但是真实的业务情况应该 是,每个用户拥有自己的一些权限,从而进行操作,所以说,权限,应该在用户的数据库中,正常的情 况下,应该数据库中是由一个权限表的,我们需要联表查询,但是这里为了大家操作理解方便一些,我 们直接在数据库表中增加一个字段来进行操作!
- 修改实体类,增加一个字段
- 给数据库中的用户增加一些权限
- 在过滤器中,将update请求也进行权限拦截下
- 启动测试,登录不同的账户,进行测试一下!测试完美通过OK!
8.整合Thymeleaf
根据权限展示不同的前端页面
- 添加Maven的依赖;
- 配置一个shiro的Dialect ,在shiro的配置中增加一个Bean
- 修改前端的配置
- 测试一下,可以发现,现在首页什么都没有了,因为我们没有登录,我们可以尝试登录下,来判断这个Shiro的效果!登录后,可以看到不同的用户,有不同的效果,现在就已经接近完美了~!但还有问题!
- 在用户登录后应该把信息放到Session中,我们完善下!在执行认证逻辑时候,加入session。
- 前端从session中获取,然后用来判断是否显示登录。
- 测试一下!
6.集成Swagger
1.Swagger简介
前后端分离
- 前端 -> 前端控制层、视图层;
- 后端 -> 后端控制层、服务层、数据访问层;
- 前后端通过API进行交互;
- 前后端相对独立且松耦合。
产生的问题
- 前后端集成,前端或者后端无法做到“及时协商,尽早解决”,最终导致问题集中爆发。
解决方案
- 首先定义schema[计划的提纲],并实时跟踪最新的API,降低集成风险。
- 早些年:指定word计划文档;
- 前后端分离:
- 前端测试后端接口:postman
- 后端提供接口,需要实时更新最新的消息及改动!
Swagger
- 号称世界上最流行的API框架;
- Restful API文档在线自动生成器 => API 文档 与API 定义同步更新。
- 直接运行,在线测试API;
- 支持多种语言(如:Java,PHP等);
- 官网:https://swagger.io/
2.SpringBoot集成Swagger
SpringBoot集成Swagger => springfox,两个jar包
- Springfox -> swagger2;
- swagger -> springmvc。
使用Swagger
- 要求:JDK1.8 + 否则swagger2无法运行。
步骤:
- 编写HelloController,测试确保运行成功!
- 要使用Swagger,我们需要编写一个配置类-SwaggerConfig来配置 Swagger
- 由于spring boot版本问题,如果启动项目报错空指针异常,将spring boot降级为2.5.5版本即可。访问测试:http://localhost:8080/swagger-ui.html,可以看到swagger的界面。
- 注:
3.0的jar访问不了,降级2.9.2就可以了
。
3.配置Swagger
- Swagger实例Bean是Docket,所以通过配置Docket实例来配置Swaggger。
- 可以通过apiInfo()属性配置文档信息;
- Docket实例关联上apiInfo()
- 重启项目,访问测试 http://localhost:8080/swagger-ui.html 效果如下:
4.配置扫描端口
- 构建Docket时通过select()方法配置怎么扫描接口。
- 除此之外,还可以配置接口扫描过滤:
- 可选值还有:
5.配置Swagger开关
- 通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了。
- 如何动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示?
- 在配置文件配置swaggerFlag的值,在dev、prod、stag的配置文件中配置,然后在swaggerConfig里面获取这个值,这样不管环境怎么变都不影响代码!
- 在项目中增加一个dev的配置文件查看效果!
6.配置API分组
- 如果没有配置分组,默认是default。通过groupName()方法即可配置分组:
- 重启项目查看分组
- 如何配置多个分组?配置多个分组只需要配置多个docket即可:
- 重启项目查看。
7.实体配置
- 新建一个实体类
- 只要这个实体在请求接口的返回值上(即使是泛型),都能映射到实体项中:
- 重启查看测试:
注:并不是因为@ApiModel这个注解让实体显示在这里了,而是只要出现在接口方法的返回值上的实体都会显示在这里,而@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的。
-
@ApiModel为类添加注释;
-
@ApiModelProperty为类属性添加注释;
8.常用注解
Swagger的所有注解定义在io.swagger.annotations包下!
- 下面列一些经常用到的,未列举出来的可以另行查阅说明:
Swagger注解 | 简单说明 |
---|---|
@Api(tags = "xxx模块说明") | 作用在模块类上 |
@ApiOperation("xxx接口说明") | 作用在接口方法上 |
@ApiModel("xxxPOJO说明") | 作用在模型类上:如VO、BO |
@ApiModelProperty(value = "xxx属性说明",hidden = true) | 作用在类方法和属性上,hidden设置为true可以隐藏该属性 |
@ApiParam("xxx参数说明") | 作用在参数、方法和字段上,类似@ApiModelProperty |
- 也可以给请求的接口配置一些注释:
这样的话,可以给一些比较难理解的属性或者接口,增加一些配置信息,让人更容易阅读!
-
相较于传统的Postman或Curl方式测试接口,使用swagger简直就是傻瓜式操作,不需要额外说明文档(写得好本身就是文档)而且更不容易出错,只需要录入数据然后点击Execute,如果再配合自动化框架,可以说基本就不需要人为操作了。
-
Swagger是个优秀的工具,现在国内已经有很多的中小型互联网公司都在使用它,相较于传统的要先出Word接口文档再测试的方式,显然这样也更符合现在的快速迭代开发行情。当然了,提醒下大家在正式环境要记得关闭Swagger,一来出于安全考虑二来也可以节省运行时内存。
9.其他皮肤
可以导入不同的包实现不同的皮肤定义:
- bootstrap-ui 访问 http://localhost:8080/doc.html
- Layui-ui 访问 http://localhost:8080/docs.html
- mg-ui 访问 http://localhost:8080/document.html
7.异步、定时、邮件任务
1.异步任务
-
新建一个空spring boot项目,创建一个service包
-
创建一个类AsyncService
异步处理还是非常常用的,比如我们在网站上发送邮件,后台会去发送邮件,此时前台会造成响应不动,直到邮件发送完毕,响应才会成功,所以我们一般会采用多线程的方式去处理这些任务。
编写方法,假装正在处理数据,使用线程设置一些延时,模拟同步等待的情况;
-
编写controller包
-
编写AsyncController类,去写一个Controller测试一下
问题:我们如果想让用户直接得到消息,就在后台使用多线程的方式进行处理即可,但是每次都需要自己手动去编写多线程的实现的话,太麻烦了,我们只需要用一个简单的办法,在我们的方法上加一个简单的注解即可,如下:
- 给hello方法添加@Async注解;
- SpringBoot就会自己开一个线程池,进行调用!但是要让这个注解生效,还需要在主程序上添加一个注解@EnableAsync,开启异步注解功能;
- 重启测试,网页瞬间响应,后台代码依旧执行!
2.邮件任务
邮件发送,在日常开发中,使用非常的多,Springboot也帮我们做了支持!!!
- 邮件发送需要引入spring-boot-start-mail
- SpringBoot 自动配置MailSenderAutoConfiguration
- 定义MailProperties内容,配置在application.yml中
- 自动装配JavaMailSender
- 测试邮件发送
测试:
- 引入pom依赖
- 看它引入的依赖,可以看到 jakarta.mail
- 查看自动配置类:MailSenderAutoConfiguration
- 这个类中存在bean,JavaMailSenderImpl。
- 然后去看下配置文件
- 配置文件:
- 获取授权码:在QQ邮箱中的设置->账户->开启pop3和smtp服务。
- Spring单元测试
- 查看邮箱,邮件接收成功!
在后期开发中,只需要使用Thymeleaf进行前后端结合即可开发自己网站邮件收发功能了!
3.定时任务
项目开发中经常需要执行一些定时任务,比如需要在每天凌晨的时候,分析一次前一天的日志信息,Spring为我们提供了异步执行任务调度的方式,提供了两个接口。
- TaskExecutor接口
- TaskScheduler接口
两个注解:
- @EnableScheduling
- @Scheduled
cron表达式:
字段 | 允许值 | 允许的特殊字符 |
---|---|---|
秒 | 0-59 | ,-*/ |
分 | 0-59 | ,-*/ |
小时 | 0-23 | ,-*/ |
日期 | 1-31 | ,-*?/L W C |
月份 | 1-12 | ,-*/ |
星期 | 0-7 或 SUN-SAT 0,7是SUN | ,-*?/L C # |
特殊字符 | 代表含义 |
---|---|
, | 枚举 |
- | 区间 |
* | 任意 |
/ | 步长 |
? | 日/星期冲突匹配 |
L | 最后 |
W | 工作日 |
C | 和calendar联系后计算过的值 |
# | 星期,4#2,第二个星期三 |
测试步骤:
- 创建一个ScheduledService
- 里面存在一个hello方法,他需要定时执行,怎么处理呢?
- 这里写完定时任务之后,需要
在主程序上增加@EnableScheduling开启定时任务功能
。
- 详细了解下cron表达式:http://www.bejson.com/othertools/cron/
- 常用的表达式:
8.富文本编辑器
1.简介
思考:我们平时在博客园,或者CSDN等平台进行写作的时候,有同学思考过他们的编辑器是怎么实现的吗?
- 在博客园后台的选项设置中,可以看到一个文本编辑器的选项:
-
其实这个就是富文本编辑器,市面上有许多非常成熟的富文本编辑器,比如:
-
Editor.md——功能非常丰富的编辑器,左端编辑,右端预览,非常方便,完全免费
-
wangEditor——基于javascript和css开发的 Web富文本编辑器, 轻量、简洁、界面美观、易用、开源免费。
-
TinyMCE——TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器,由JavaScript写成。它对IE6+和Firefox1.5+都有着非常良好的支持。功能齐全,界面美观,就是文档是英文的,对开发人员英文水平有一定要求。
-
百度ueditor——UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,功能齐全,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码,缺点是已经没有更新了
-
kindeditor——界面经典。
-
Textbox——Textbox是一款极简但功能强大的在线文本编辑器,支持桌面设备和移动设备。主要功能包含内置的图像处理和存储、文件拖放、拼写检查和自动更正。此外,该工具还实现了屏幕阅读器等辅助技术,并符合WAI-ARIA可访问性标准。
-
CKEditor——国外的,界面美观。
-
quill——功能强大,还可以编辑公式等
-
simditor——界面美观,功能较全。
-
summernote——UI好看,精美
-
jodit——功能齐全
-
froala Editor——界面非常好看,功能非常强大,非常好用(非免费)
总之,目前可用的富文本编辑器有很多......这只是其中的一部分。
2.Editor.md
- 这里使用的就是
Editor.md
,作为一个资深码农,Mardown必然是我们程序猿最喜欢的格式,看下面,就爱上了!
-
可以在官网下载它:https://pandao.github.io/editor.md/ , 得到它的压缩包!
-
解压以后,在
examples
目录下面,可以看到他的很多案例使用!学习,其实就是看人家怎么写的,然后进行模仿就好了! -
可以将整个解压的文件导入至我们的项目,将一些无用的测试和案例删掉即可!
3.基础工程搭建
数据库设计
article:文章表
字段 | 备注 | |
---|---|---|
id | int | 文章的唯一ID |
author | varchar | 作者 |
title | varchar | 标题 |
content | longtext | 文章的内容 |
建表SQL:
基础项目搭建
- 建一个SpringBoot项目配置。
- 实体类:
3、mapper接口:
- 既然已经提供了 myBatis 的映射配置文件,自然要告诉 spring boot 这些文件的位置
- 编写一个Controller测试下,是否ok;
4.文章编辑整合
-
导入 editor.md 资源 ,删除多余文件。
-
编辑文章页面 editor.html、需要引入jQuery;
- 编写Controller,进行跳转,以及保存文章
图片上传问题
- 前端js中添加配置
- 后端请求,接收保存这个图片, 需要导入 FastJson 的依赖!
3、解决文件回显显示的问题,设置虚拟目录映射!在我们自己拓展的MvcConfig中进行配置即可!
表情包问题
- 自己手动下载,emoji 表情包,放到图片路径下:
- 修改editormd.js文件
5.文章展示
- Controller 中增加方法
- 编写页面 article.html
- 重启项目,访问进行测试!大功告成!
9.整合Dubbo+Zookeeper
1.分布式理论
什么是分布式系统?
- 在《分布式系统原理与范型》一书中有如下定义:“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”;
- 分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
分布式系统(distributed system)是建立在网络之上的软件系统。
- 首先需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。
- 因为,分布式系统要解决的问题本身就是和单机系统一样的,而由于分布式系统多节点、通过网络通信的拓扑结构,会引入很多单机系统没有的问题,为了解决这些问题又会引入更多的机制、协议,带来更多的问题。
- DUBBO官网:https://dubbo.apache.org/zh/
- 随着互联网的飞速发展,Web应用的规模不断扩大,最终我们发现传统的垂直架构(单体)已经无法应对。分布式服务架构和流计算架构势在必行,迫切需要一个治理体系来保证架构的有序演进。
单体架构
- 当流量很低时,只有一个应用,所有的特性都部署在一起,减少部署节点和成本。此时,数据访问框架(ORM)是简化 CRUD 工作量的关键。
- 适用于小型网站,小型管理系统,将所有功能都部署到一个功能里,简单易用。
- 缺点:
- 1、性能扩展比较难
- 2、协同开发问题
- 3、不利于升级维护
垂直架构
- 当流量变大时,添加单体应用实例并不能很好地加速访问,提高效率的一种方法是将单体应用拆分成离散的应用程序。此时,用于加速前端页面开发的Web框架(MVC)是关键。
- 通过切分业务来实现各个模块独立部署,降低了维护和部署的难度,团队各司其职更易管理,性能扩展
也更方便,更有针对性。 - 缺点: 公用模块无法重复利用,开发性的浪费
分布式服务架构
- 当垂直应用越来越多时,应用之间的交互是不可避免的,一些核心业务被提取出来,作为独立的服务,逐渐形成一个稳定的服务中心,这样前端应用就可以更好地响应多变的市场需求。迅速地。此时,用于业务重用和集成的分布式服务框架(RPC)是关键。
流计算架构
- 当服务越来越多时,容量评估变得困难,而且小规模的服务也经常造成资源浪费。为了解决这些问题,需要增加调度中心,根据流量对集群容量进行管理,提高集群的利用率。这时,用来提高机器利用率的资源调度和治理中心(SOA)是关键。
2.什么是RPC?
RPC【Remote Procedure Call】是指远程过程调用,像调用本地方法一样调用远程方法,是一种进程间通信方式,他是一种技术的思想,而不是规范。
它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
- 也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。
- 为什么要用RPC呢?
- 就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。RPC就是要像调用本地的函数一样去调远程函数;
- 服务消费方(client)调用以本地调用方式调用服务;
- client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
- client stub找到服务地址,并将消息发送到服务端;
- server stub收到消息后进行解码;
- server stub根据解码结果调用本地的服务;
- 本地服务执行并将结果返回给server stub;
- server stub将返回结果打包成消息并发送至消费方;
- client stub接收到消息,并进行解码;
- 服务消费方得到最终结果。
RPC两个核心模块:通讯,序列化。
3.什么是dubbo?
Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
- dubbo官网
- 了解Dubbo的特性;
- 查看官方文档
- 服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
- 调用关系说明
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
Dubbo的基本要求
- 在大规模服务出现之前,应用程序可能只是通过 RMI 或 Hessian 暴露或引用远程服务,通过配置服务 URL 进行调用,通过 F5 等硬件完成负载均衡。
- 当服务越来越多,配置服务URL变得非常困难,F5硬件负载均衡器的单点压力也越来越大。此时,需要一个服务注册中心来动态注册和发现服务,使服务的位置透明化。通过在消费者端获取服务提供者地址列表,可以实现软负载均衡和Failover,减少对F5硬件负载均衡器的依赖和部分成本。
- 当事情进一步发展时,服务依赖变得如此复杂,以至于它甚至无法告诉之前启动哪些应用程序,甚至架构师也无法完全描述应用程序架构关系。这时就需要自动绘制应用程序的依赖关系图,帮助架构师理清关系。
- 然后,流量变得更重,服务的容量问题暴露出来,需要多少台机器来支持这个服务?什么时候应该加机器?要解决这些问题,首先要将每天的服务调用量和响应时间量作为容量规划的参考。二、动态调整权重,增加一台在线机器的权重,并记录响应时间的变化,直到达到阈值,记录此时的访问次数,然后将此访问次数乘以总机器数计算反过来的能力。
更多参考:网页。
4.Dubbo环境搭建
- 点进dubbo官方文档,推荐我们使用Zookeeper注册中心!
- 什么是zookeeper呢?可以查看官方文档!
window下安装zookeeper
- 参考教程:菜鸟教程
可能遇到问题:闪退!
- 解决方案:编辑zkServer.cmd文件末尾添加
pause
。这样运行出错就不会退出,会提示错误信息,方便找到原因。
报错:
错误: 找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain
- 下载编译后的二进制的包,就好了。地址:https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz
- 将conf目录下的zoo_sample.cfg文件,复制一份,重命名为zoo.cfg:
- 在安装目录下面新建一个空的 data 文件夹和 log 文件夹:
- 修改 zoo.cfg 配置文件,将 dataDir=/tmp/zookeeper 修改成 zookeeper 安装目录所在的 data 文件夹,再添加一条添加数据日志的配置(需要根据自己的安装路径修改)。
- 修改完成后再次双击 zkServer.cmd 启动程序:
Zookeeper启动失败:Unexpected exception, exiting abnormally java.net.BindException: Address alr
- 这是2181端口被占用导致的,需要结束占用2181端口的进程。
- 进去命令提示符之后,输入“netstat -aon | findstr 2181”命令,按回车键,如下图所示:
- 打开任务管理器,显示进程的pid之后,找到pid为19236的进程,点击结束进程。
- 结束进程之后,再次运行项目,就正常运行了。
- 测试,双击zkCli.cmd 启动客户端。
ls /
:列出zookeeper根下保存的所有节点。create –e /subei 123
:创建一个subei节点,值为123。get /subei
:获取/subei节点的值。
5.window下安装dubbo-admin
- dubbo本身并不是一个服务软件。它其实就是一个jar包,能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。
- 但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序dubbo-admin,不过这个监控即使不装也不影响使用。
- 下载dubbo-admin
- 解压进入目录
- 修改 dubbo-admin-master-0.2.0\dubbo-admin\src\main\resources\application.properties 指定zookeeper地址
- 在项目目录下打包dubbo-admin
- 过程有点慢,需要耐心等待!直到成功!
- 执行dubbo-admin\target下的dubbo-admin-0.0.1-SNAPSHOT.jar
- 注意:zookeeper的服务一定要打开!
- 执行完毕,去访问一下 http://localhost:7001/,这时候需要输入登录账户和密码,都是默认的
root-root
;登录成功后,查看界面。
安装完成!
新版实现
-
下载代码:
git clone https://github.com/apache/dubbo-admin.git
-
在
dubbo-admin-server/src/main/resources/application.properties
中指定注册中心地址 -
构建
mvn clean package -Dmaven.test.skip=true
-
启动
mvn --projects dubbo-admin-server spring-boot:run
或者cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar
-
访问
http://localhost:8080
不太稳定,启动失败!!!
6.框架搭建
- 启动zookeeper!
- 双击 zkServer.cmd 启动程序!
- IDEA创建一个空项目;
- 创建一个模块,实现服务提供者:provider-server,选择web依赖即可;
- 项目创建完毕,写一个服务,比如卖票的服务;
编写接口:
编写实现类:
- 创建一个模块,实现服务消费者:consumer-server,选择web依赖即可
- 项目创建完毕,写一个服务,比如用户的服务; 编写service
7.服务提供者
- 将服务提供者注册到注册中心,需要整合Dubbo和zookeeper,所以需要导包。
- 从dubbo官网进入github,看下方的帮助文档,找到dubbo-springboot,找到依赖包。
- zookeeper的包我们去maven仓库下载,zkclient;
- zookeeper及其依赖包,解决日志冲突,还需要剔除日志依赖;
- 在springboot配置文件中配置dubbo相关属性!
- 在service的实现类中配置服务注解,发布服务!注意导包问题。
逻辑理解:应用启动起来,dubbo就会扫描指定的包下带有@component注解的服务,将它发布在指定的注册中心中!
8.消费者
- 导入依赖,和之前的依赖一样;
- 配置参数
- 本来正常步骤是需要将服务提供者的接口打包,然后用pom文件导入,这里使用简单的方式,直接将服务的接口拿过来,路径必须保证正确,即和服务提供者相同;
- 完善消费者的服务类
- 测试类
- 启动测试
- 开启zookeeper
- 打开dubbo-admin实现监控【可以不用做】
- 开启服务者
- 消费者消费测试
SpingBoot + dubbo + zookeeper实现分布式开发的应用,其实就是一个服务拆分的思想!!!
🎉🎉结束🎉🎉
__EOF__

本文链接:https://www.cnblogs.com/The1Yu/p/15968959.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤