初学SpringBoot
什么是SpringBoot
微服务架构风格(microservice architectural style)的出现:把应用程序构建为一套服务。
事实是,服务可以独立部署和扩展,每个服务提供了一个坚实的模块边界,甚至不同的服务可以用不同的编程语言编写。它们可以被不同的团队管理。
coc:约定大于配置,也称作按约定编程,是一种软件设计规范,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。
Spingboot给对象赋值
-
自动注入
- 类上声明@Compoent
- 属性上@AutoWore("");
-
yaml赋值
- yaml文件中写入类
- 类上声明@ConfigurationProperties( prefix = "yaml的类名");
-
properties
- 类上声明@PropertiesSource
- 逐个在属性上@Value("${属性名})
JSR303校验:
-
判断是否符合格式
-
类上方@Validated
-
类属性上@Email是判断是否符合邮箱格式
自动装配原理
-
SpringBoot启动会加载大量的自动配置类
-
我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
-
我们在来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在其中,
我们就不需要在手动配置了)
-
给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
-
xxxAutoConfiguration:自动配置类;给容器中添加组件
-
xxxProperties:封装配置文件中的相关属性
静态资源访问:
在springboot,我们可以使用一下 方式处理静态资源
1. webjarslocalhost:8080/webjars
2. public ,static,resourcelocalhost:8080/
优先级:resource>static(默认)>public
设定首页:
index首页放在静态资源区会自动扫面到
图标定制在新版本中被取消了,可以用link标签
<link rel="shortcut" href="">
Thymeleaf模板引擎
使用步骤:
- 1.pom.xml中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
-
2.中添加导入约束
<html lang="en" xmlns:th="http://www.thymeleaf.org">
-
3.使用thymeleaf语法获取参数
<!-- >获取参数 --> <div th:text = "${msg}"></div> <!-- 获取不转义参数 --> <div th:utext = "${msg}"></div> <!-- 循环遍历数组 --> <h3 th:each="user:${users}" th:text="${user}"></h3> <!-- 不推荐使用 --> <h3 th:each="user:${users}" >[[${user}]]</h3> <!-- link 引入资源标签 src前面加上th: 路径用@{/} /是指resource根目录下--> <link th:href="@{/static/login.css}"> <!-- a标签给controller传值 controller层: @ReQuestMapping("/production/{proid}") public String product(@PathVariable(name = "proid")int proid,){ } --> <a th:href="@{'/prodction/'+${production.id}}" th:text="${production.title}">XXX</a>
页面改变之后前端未发生变化
配置文件中加入
service.themeleaf.cache=false
@Bean
public ViewResolver myViewResolver(){
return new MyViewResolver();
}
public static class MyViewResolver implements ViewResolver{
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return null;
}
}
自定义一个视图解析器
1.java目录下新建一个包config新建myMvcConfig实现类
2.类上声明@configuration,并实现WebMvcConfigurer接口
3.自定义一个静态类实现viewResoler接口,重写resolveViewName方法
4.@Bean声明一个bean标签,实现就试图截器器的接口类
5.return 视图截器器
设定主页时** 😗*
在myMvcConfig实现类中重写一个addViewControllers(ViewControllerRegistry registry)方法
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/",setViewName("index");
registry.addViewController("/index.html",setViewName("index");
}
页面登录成功重定向,隐藏传递参数
控制器类中返回的值时String时,return "redirect:/main.html";
在视图webmvc配置类中添加视图解析
registry.addViewController("/main.html",setViewName("html的页面名称");
SpringBoot解决@ResponseBody中文乱码问题
在@RequestMapping中设置格式
@RequestMapping(value = "/XXX/xxx", produces = "application/json; charset=utf-8")
登录拦截设置
1)新建一个HandlerInterceptor的实现类,重写preHandle方法,判断session中是否有值
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录之后,应该有用户的session
Object loginUser = request.getSession().getAttribute("username");
if(loginUser == null){
request.setAttribute("msg","没有权限,请先登录");
//下方错误待处理
request.getRequestDispatcher("/toLogin").forward(request,response);
return false;
}else {
return true;
}
}
2)webmvc配置类中添加拦截器,重写addInterceptors方法和addResourceHandlers方法
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/toLogin","/userlogin","/registered","/css/*","/js/**","/font/**","/image/**","/layui.js");
}
Thymeleaf 中前端代码组件化
在相应的div中加入一个属性,th:fragmeng="唯一标识名"
在对应的html中加入div,并添加属性th:insert="~{标识符}"
SpringBoot** 整合 jdbc (在构建项目时引入 jdbc 的 **** API **** 和 **** mysql Driver **)
- 在配置文件(application.yml)中声明spring.datasource.username / password / url / driver-class-name,
在url后面加入useUnicode=true&characterEncoding=utf-8,
如果出现时区报错了,就在url后面加入&serverTimezone=UTC
-
在Controller类中自动注入jdbcTheplate
-
首先sql语句,使用jdactheplate中的query / update进行数据操作
SpringBoot整合Durid
(在构建项目时引入jdbc 的 API 和 mysql Driver )
使用步骤
1)在pom文件中加入druid依赖和log4j依赖
<!-- druid 依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
<!-- log4j 依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2)在配置文件中声明datasource类型为druid,并赋值一些属性
数据源基本配置
# 数据源基本配置
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/duid
# 声明数据源类型
type: com.alibaba.druid.pool.DruidDataSource
# 数据源其他配置
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,去掉后监控界面sql无法统计,'wall'用于防火墙
# stat:监控统计 wall:防止sql注入 log4j:日志记录
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
3)在config包下新建配置类(JDBCController)
/**
*@return 返回监控注册的servlet对象
* @author SimpleWu
*/
//再类上方声明@configuration
//写方法返回Druid
@Bean
@Configurationproperties( prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
//配置监控服务器
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
// 添加IP白名单
servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
// 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
servletRegistrationBean.addInitParameter("deny", "127.0.0.1");
// 添加控制台管理用户 名称固定不可出错
servletRegistrationBean.addInitParameter("loginUsername", "SimpleWu");
servletRegistrationBean.addInitParameter("loginPassword", "123456");
// 是否能够重置数据
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
/**@return 返回过滤器配置对象
*/
* 配置服务过滤器
*
*
@Bean
public FilterRegistrationBean statFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
// 添加过滤规则
filterRegistrationBean.addUrlPatterns("/*");
// 忽略过滤格式
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*,");
return filterRegistrationBean;
}
springboot 整合 mybatis
使用步骤
-
导入mybatis spring boot starter依赖
-
在配置文件(application.yml)中声明spring.datasource.username / password / url / driver-class-name,
再声明mybatis.type-aliases-package=com.kuang.pojo,mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
-
新建pojo包新建mysql类新建mapper包下mapper类,(类上声明@Mapper/在springboot05MybatisApplication上声明注解@MapperScan(com.kuang.mapper&
quot;),并在类上声明@Repository持节类注解,在类中声明方法
-
在resource下新建包mybatis.mapper
-
在controller中调用service使用
SpringBoot 整合SpringSecurity(安全框架)
作用:省去拦截器过滤器的繁琐,直接使用框架重写继承类方法
"这个登录并不是自己写的登录页面,而是security生成的登录页面
使用步骤
1)pom文件引入thymeleaf和springsecurity依赖
2)在config中新建SecurityConfig,在类上方加入@EnableWebSecurity
3)类继承 WebSecurityConfigurerAdapter,并重写void configure(HttpSecurity http)方法
//在该方法中授权,首页可以任何人访问,功能页只有有对应的权限才能访问
http.authorizeRequests()
.antMatchers("/").permitALl()
.antMatcher("/level1/**").hasRoler("vip1")
.antMatcher("/level2/**").hasRoler("vip2")
.antMatcher("/level3/**").hasRoler("vip3")
//没有权限会默认到登录页面
//定制登录页 默认后面属性为username,password,不同时需要自己设定,后面的action同理
http.formLogin().loginPage("toLogin").usernameParamter("user").passwordParamter("pwd").loginProcessingUrl("login");
//防止网站工具 get,post
//关闭csrf功能,登录失败存在的原因
http.csrf().disable();
//注销.开启了注销功能,跳到首页
http.logout().logoutSuccessUrl("/");
//开启记住我 cookie默认保存两周 自定义的记住我
http.rememberMe().rememberMeparameter("remember");
4)类中重写void configure(AuthenricationManagerBuilder auth) 方法,对不同用户进行授权
//对不同用户进行认证,并将密码新建加密方式
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoding())
.withUser("kuangshen").password(new BCryptPasswordEncoding().encode("123456")).role("vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoding().encode("123456")).role("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoding().encode("123456")).role("vip1")
5)在依赖中加入thymeleaf和security的整合包依赖,只要在页面上导入命名空间
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"
就可以在html中进行权限判断,以此显示不同的页面
<!-- security-thymeleaf整个包 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
sec:authorize="hasRole('vip'1)"是否有相应的权限,反之前加!
sec:authentication="name"获取登录的名字
sec:authorize="isAuthenticated()"是否已经登录,反之前加!
shrio 快速使用
Apache Shiro 是 Java 的一个安全框架。
-
Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;
-
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
-
Session Management :会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;
-
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
-
Web Support:Web 支持,可以非常容易的集成到 Web 环境;
-
Caching:缓存,比如用户登录后,其用户信息、拥有的角色 / 权限不必每次去查,这样可以提高效率;
-
Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
-
Testing:提供测试支持;
-
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
-
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

-
Subject :主体,代表了当前 "用户",这个用户不一定是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫,机器人等;即一个抽象概念;所有 Subject 都绑定到 SecurityManager,与 Subject 的所有交互都会委托给 SecurityManager;可以把 Subject 认为是一个门面;SecurityManager 才是实际的执行者;
-
SecurityManager :安全管理器;即所有与安全有关的操作都会与 SecurityManager 交互;且它管理着所有 Subject;可以看出它是 Shiro 的核心,它负责与后边介绍的其他组件进行交互,如果学习过 SpringMVC,你可以把它看成 DispatcherServlet 前端控制器;
-
Realm :域,Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色 / 权限进行验证用户是否能进行操作;可以把 Realm 看成 DataSource,即安全数据源。
记住一点, Shiro 不会去维护用户、维护权限;这些需要我们自己去设计 / 提供;然后通过相应的接口注入给 Shiro 即可。
Shiro的优点:
简单的身份认证, 支持多种数据源
对角色的简单的授权, 支持细粒度的授权(方法级)
支持一级缓存,以提升应用程序的性能;
内置的基于 POJO 企业会话管理, 适用于 Web 以及非 Web 的环境
非常简单的加密 API
不跟任何的框架或者容器捆绑, 可以独立运行
Shiro 架构 核心组件:
-
Authenticator:管理登陆登出
-
Authorizer:授权器赋予主体有那些权限
-
session Manager:shiro自己实现session管理器
-
session DAO:提供了session的增删改插
-
Cache Manager:缓冲管理器
-
Raelms:和数据库交互的桥梁
shiro认证过程:
创建SecurityManager --> 主体提交认证 --> SecurityManager认证–> Authenticator认证–> Realm验证
shiro 授权过程:
创建SecurityManager -->主体授权 --> securityManager授权 --> Authorizer授权 --> Realm获取权限数据
1)导入依赖
<!-- shiro 依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
2)config先新建类Shiro类
@Configuration
public class ShiroController {
//创建ShiroFilterFactoryBean关联DefaultWebSecurityManager
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("SecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro的内置过滤器
/*
anon:无需认证就可访问
authc:必须认证了才能访问
user:必须拥有 记住我 功能才可以访问
perms:拥有对某个资源的权限才能访问
role:拥有某个角色权限才能访问
*/
Map<String,String> filterMap = new LinkedHashMap<>();
filterMap.put("/toLook","authc");
bean.setFilterChainDefinitionMap(filterMap);
bean.setLoginUrl("/toLogin");
return bean;
}
//创建DefaultWebSecurityManager关联UserRealm
@Bean(name = "SecurityManager")
public DefaultWebSecurityManager dafaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
3)同时在config下新建UserReal
//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserinfoService userinfoService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权");
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("认证");
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
List<Userinfo> userinfos = userinfoService.selectByUsername(userToken.getUsername());
if(userinfos.isEmpty()){
return null;
}
Userinfo userinfo = userinfos.get(0);
//密码认证
return new SimpleAuthenticationInfo("",userinfo.getPassword(),"");
}
}
Swagger 的使用
前端测试框架
前些年前后端交互性太差,没有及时交流,当前端进行数据修改时,后端改动较大
最流行Api:swagger
使用步骤(** Swagger2 **** 中 2.X.X 依赖)**
1)新建Springboot web项目
2)导入依赖
- swagger2
- ul
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
- 在config包下新建SwaggerConfig
@Configuration
@EnableSwagger2 //开启swagger
public class SwaggerConfig {
}
4)/swagger-ui.html已经新访问页面
使用步骤( swagger2 3.0.0 依赖)
1.新建springboot-web项目
2.导入依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
3.在config包下新建SwaggerConfig
@Configuration
@EnableWebMvc
public class SwaggerConfig {
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.SWAGGER_2) //指定api类型为swagger2
.apiInfo(apiInfo()) //定义api文档配置信息
.select().apis(RequestHandlerSelectors.basePackage("com.my.controller")) //指定需要扫描的controller包
.paths(PathSelectors.any()) //所有 xxxController都需要生成
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("Swagger接口API文档") //文档页标题
.contact(new Contact("郭远","www.baidu.com","123456@qq.com")) //联系人信息
.description("api文档的描述")
.version("1.0") //文档版本号
.termsOfServiceUrl("https://www.shixin.com") //网站地址
.build();
}
}
4.在/swagger-ui/index.html访问
分组问题
通过创建多个Docket实现
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("A");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("B");
}
api 注释
-
Api@Api 用在类上,说明该类的作用。
-
ApiModel@ApiModel 用在类上,表示对类进行说明,用于实体类中的参数接收说明。
-
ApiModelProperty@ApiModelProperty() 用于字段,表示对 model 属性的说明。
-
ApiParam@ApiParam 用于 Controller 中方法的参数说明。
-
ApiOperation@ApiOperation 用在 Controller 里的方法上,说明方法的作用,每一个接口的定义。
-
ApiResponse 和 ApiResponses@ApiResponse 用于方法上,说明接口响应的一些信息
-
ApiImplicitParam 和 ApiImplicitParams用于方法上,为单独的请求参数进行说明。
常见的处理方式
异步处理
在启动类上,加入@EnableAsync
在Service的方法上加入@Async
邮箱处理
使用步骤:
1)加入邮箱依赖
<!-- 邮箱依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2)在service中调用
@Autowired
JavaMailSenderImpl mailSender;
//一个简单的邮件发送
@Test
void t1(){
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("测试文件");
mailMessage.setText("测试内容,无需回复!");
mailMessage.setTo("2576709493@qq.com");
mailMessage.setFrom("xiaoyuyunnote@163.com");
mailSender.send(mailMessage);
}
//一个复杂的的邮件发送
@Test
void t2() throws MessagingException {
MimeMessage mailMessage = mailSender.createMimeMessage();
//组件
MimeMessageHelper helper = new MimeMessageHelper(mailMessage, true);
helper.setSubject("测试文件");
// true表示启用html格式
helper.setText("<p style='color:red'>测试发送附件</p>",true);
//附件
helper.addAttachment("1.jpg",new File("C:\\Users\\gy\\Pictures\\Camera Roll\\home1.jpg"));
helper.setTo("2576709493@qq.com");
helper.setFrom("xiaoyuyunnote@163.com");
mailSender.send(mailMessage);
}
异步处理
使用步骤
1)在启动类上加入@EnableScheduling
2)在service类中使用,方法上声明@Scheduled("")
cron表达式,六个值 (秒,分,时,日,月,星期)
- :: 表示匹配该域的任意值。比如Minutes域使用*,就表示每分钟都会触发。
-
-:表示范围。比如Minutes域使用 10-20,就表示从10分钟到20分钟每分钟都会触发一次。
-
,:表示列出枚举值。比如Minutes域使用1,3,就表示1分钟和3分钟都会触发一次。
-
/ : 表示间隔时间触发(开始时间/时间间隔)。例如在Minutes域使用 5/10,就表示从第5分钟开始,每隔10分钟触发一次。
-
? : 表示不指定值。简单理解就是忽略该字段的值,直接根据另一个字段的值触发执行。
-
表示该月第n个星期x(x#n),仅用星期域。如:星期:6#3,表示该月的第三个星期五。
-
L : 表示最后,是单词"last"的缩写(最后一天或最后一个星期几);仅出现在日和星期的域中。用在日则表示该月的最后一天,用在星期则表示该月的最后一个星期。如:星期域上的值为5L,则表示该月最后一个星期的星期四。在使用'L'时,不要指定列表','或范围'-',否则易导致出现意料之外的结果。
-
W: 仅用在日的域中,表示距离当月给定日期最近的工作日(周一到周五),是单词"weekday"的缩写。
Dubbo+Zookeeper集成分布式项目
Dubbo是一款由阿里巴巴开发的远程服务调用框架(RPC),其可以透明化的调用远程服务,就像调用本地服务一样简单。截至目前,Dubbo发布了基于Spring Boot构建的版本,版本号为0.2.0,这使得其与Spring Boot项目整合变得更为简单方便。而Zookeeper在这里充当的是服务注册中心的角色,我们将各个微服务提供的服务通过Dubbo注册到Zookeeper中,然后服务消费者通过Dubbo从Zookeeper中获取相应服务并消费。
.png)
使用步骤
1)启动 zookeeper 注册中心:
在搭建项目之前需要启动 Zookeeper 服务,Zookeeper官方下载地址:http://zookeeper.apache.org/releases.html#download
下载后解压,将config目录下的zoo_sample.cfg 重命名为 zoo.cfg (Zookeeper配置文件,默认端口为2181,可根据实际进行修改)。然后双击bin目录下的zkServer.cmd启动即可。
(个人感觉每次运行项目都要启动 zookeeper,麻烦,看这篇文章设置开机自启:Windows下把ZooKeeper注册成为Windows服务,实现开机自启动)
2)构建项目
新建maven或者springboot项目
3)环境配置
privider-server 接口提供者
1.导入依赖
<!--导入依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<!--zkclient-->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<!--解决日志冲突-->
<!--引入zookeeper-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<!--解决 java.lang.NoClassDefFoundError: org/apache/curator/framework/recipes/cache/TreeCacheListener-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.配置文件
# 服务端口
server.port=8001
# 注册服务应用名字
dubbo.application.name=provider-server
# 注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
# 哪些服务需要被注册
dubbo.scan.base-packages=com.xiao.service
3.写service层
在实现类中加入dubbo中的@service注解,加入@Component
4.启动项目(该项目必须是配置好log4j配置文件的,否则会报错)
consumer-server 接口消费者
1.导入依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<!--zkclient-->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<!--解决日志冲突-->
<!--引入zookeeper-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<!--解决 java.lang.NoClassDefFoundError: org/apache/curator/framework/recipes/cache/TreeCacheListener-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.配置文件
# 服务端口
server.port=8002
# 消费者取哪里拿服务需要暴露自己的名字
dubbo.application.name=consumer-server
# 注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
3.log4j.properties配置文件
4.写service层,
写下和接口提供者service相同的接口层
在实现类中,使用Duboo中的@Reference注解自动注入service类
4) dubbo-admin 管理控制台部署
1.修改 dubbo.properties文件 如下:
2**.**把 dubbo-admin 打包成 jar 包然后 java -jar 运行 jar包 即可
3.访问 http://localhost:7001/ 进入管理界面:
5).启动运行 privider-server 和 consumer-server
1.先启动 privider-server
2.查看 dubbo-admin 可以看到 privider-server 已把业务层接口发布到注册中心
3.测试消费者是否远程调用到了接口: