参考文档路径:https://www.yuque.com/atguigu/springboot
1.概述
【springBoot】
Spring Boot 就是一个javaweb的开发框架,其的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件。
【微服务架构】
微服务架构是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。它可以把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议。
围绕业务领域组件来创建应用,这些应用可独立地进行开发、管理和迭代。在分散的组件中使用云架构和平台式部署、管理和服务功能,使产品交付变得更加简单。
2.初识springboot
2.1 第一个 demo
【方式一】
选择完成后点击generate 创建并下载该项目,即可到idea中导入。
【方式二】
打开 IDEA,选择 Spring Initializr 创建项目。
【测试启动】
直接写一个controller,并在主函数中直接启动
【修改端口号】
在 application.properties 中添加以下代码
#更改项目端口号
server.port=8033
【彩蛋】
在 resources 下新建一个 banner.txt 文件,即可替换运行时的 spring logo
2.2 阅读源码
【自动装配】
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
如果我们需要使用什么功能,就只需要导入对应的启动器(启动器会自动去导入依赖);比如spring-boot-starter-web就会自动导入web环境所有依赖。
主程序
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
-
@SpringBootApplication
-
@SpringBootConfiguration >> springboot的配置
- @Configuration >> spring配置类( 代替 springConfig.xml )
**结论:**这个主程序也只是spring的一个组件,底层也是spring的配置 -
@EnableAutoConfiguration >> 自动装配的配置
-
@AutoConfigurationPackage >> 自动配置包
- @Import({Registrar.class}) >> 导入注册器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OTXsDm7H-1661850777128)(F:\study\note\img\image-20220816171849213.png)] -
@Import({AutoConfigurationImportSelector.class}) >> 自动配置导入选择(核心) 结论:springboot 所有的自动配置都是在启动的时候扫描并加载,所有的自动配置类都在 spring.factories(在spring-boot-autoconfigure 的 jar 包中)这里面,但不是全部都生效。要导入对应的启动器,自动装配才能生效。 -
@ComponentScan >> 扫描当前主启动类同级的包 -
main
- init加载初始化
- 推断应用程序是否是web
- 加载所有可用初始化器
- 设置所有可用程序监听器
- 推断并设置main方法的定义类,找到运行的主类
- 开始执行run方法
- 监听器初始化、启动
- 装配环境参数
- 打印banner
- 上下文相关配置处理
3.配置文件
springboot 适用一个全局的配置文件,文件名称是固定的。
- application.properties
- application.yaml
3.1 配置文件优先级
【配置文件位置】
- file:./config/ 根目录下的config文件夹下创建
- file:./ 根目录下直接创建
- classpath:/config/ 资源包下的config文件夹下创建
- classpath:/ 资源包下直接创建(默认)
注:优先级1最高,4最低
【同优先级设置多套环境】
方式一:
方式二:
通过 --- 分隔多个配置文件
spring:
profiles:
active: test
server:
port: 8080
---
spring:
profiles: test
server:
port: 8088
3.2 yaml语法结构
key: value
student1:
name: zheng
age: 19
student2: {name: zheng,age: 18}
arr1:
- num1
- num2
arr2: [num1,num2]
defaults: &defaults
num1: 11
num2: 22
a:
database: mya
<<: *defaults
b:
database: myb
<<: *defaults
【举例】:适用 yaml 配置一个实体类
说明:@ConfigurationProperties :默认从全局配置文件中获取值
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String myname;
private int myage;
private Dog mydog;
}
说明:${random.int} 是一个文件占位符,设置一个随机数,甚至可以是uuid
person:
myname: zheng
myage: ${random.int}
mydog: {dname: 旺财,dage: 4}
【举一反三】
当有一个类似于 springConfig 的配置类时间,即可通过 yaml 的方式进行配置
3.3 JSR303校验
使用前,需导入对应的启动器
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>1.0.0.Alpha2</version>
</dependency>
补充:
【举例】
@Component
@ConfigurationProperties(prefix = "login")
@Validated
public class Login {
private String userName;
@Length(min = 6, max = 19, message = "密码长度是6-18位")
private String userPass;
}
login:
user-name: zheng
user-pass: 123
3.4 自动装配原理
Springboot项目,都会有一个父项目管理依赖,父项目中定义了几乎所有常见依赖的版本(可自定义更改)。通过启动器spring-boot-starter,会按需加载该场景所需的依赖,然后导入到容器中。
而每一个starter中间接导入了autoconfigure依赖,它定义了所有依赖的默认配置。这些默认配置最终映射到某个名为 xxxProperties的类上。
总结
- springboot 启动会加载大量的自动配置类
- 我们只需要看我们需要的功能有没有在springboot默认写好的配置类中
- 再看自动配置类中装配了哪些组件
- 给容器中自动配置类添加组件时,会从properties(yaml)类中获取某些属性
4.springboot web开发
4.1 静态资源导入
-
存放于resources下的 resources、static、public(按优先级从高到低排列)文件夹中的静态资源,访问路径为http://localhost:8080/xxx 即可直接访问文件夹下资源。 -
若添加yaml配置 -
配置yaml
spring:
mvc:
static-path-pattern: /diy/**
则访问路径为http://localhost:8080/diy/xxx
【首页及图标配置】
直接把首页 index.html 及图标 favicon.ico 放在某一个静态资源文件下即可生效。(注意命名规范)
4.2 模板引擎 Thymeleaf
【使用步骤 】
- 使用前,需导入对应的启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 并且在需要使用模板引擎的页面导入该头文件
<html xmlns:th="http://www.https://www.thymeleaf.org"> - 在templates下创建一个html页面即可使用。
原理:模板引擎会解析字符串,加前缀 classpath:/templates/ ,及后缀 .html ,然后返回templates包中对应名称的html。注意的是该controller类注解只能是普通的组件,不能是@RestController。
【举个例子】
<!DOCTYPE html>
<html xmlns:th="http://www.https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>home页面</title>
<style>
.box{
color: #fc011a;
font-size: 40px;
margin-top: 100px;
text-align: center;
}
</style>
</head>
<body>
<div class="box">home</div>
<div th:text="${msg}"></div> //转义文本
<div th:utext="${msg}"></div> //不转义文本
</body>
</html>
@RequestMapping("/homepage")
public String homepage(Model model){
model.addAttribute("msg","<a href='https://www.baidu.com/'>百度一下</a>");
return "home";
}
4.3 装配扩展SpringMVC
4.4 拓展-国际化
* 要提前将设置中 Editor > File Encodings 设置为utf-8
- 创建一组对应语言的properties配置文件(父文件名为xxx,则对应的中文文件名为xxx_zh_CN)
- 配置路径
spring:
messages:
basename: i18n.login
encoding: UTF-8
- 通过链接携带参数,访问后台并传回页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" th:href="@{/style.css}">
</head>
<body>
<div class="header" th:text="#{login.welcom}">welcome to my web!</div>
<div class="links">
<a th:href="@{/index.html(lang='zh_CN')}">中文</a>
|
<a th:href="@{/index.html(lang='en_US')}">English</a>
</div>
</body>
</html>
- 自定义一个拦截器,并注入到配置中
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String lang = request.getParameter("lang");
Locale locale = Locale.getDefault();
if(!StringUtils.isEmpty(lang)){
String[] s = lang.split("_");
locale = new Locale(s[0], s[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { }
}
@Configuration
public class MyMvcConfig {
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
4.5 拦截器
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if(loginUser != null){
return true;
}
request.setAttribute("msg","请先登录");
request.getRequestDispatcher("/").forward(request,response);
return false;
}
}
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");
}
}
4.6 跨域
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Bean
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").
allowedOrigins("http://localhost:8080/").
allowedMethods("*").
allowedHeaders("*").
allowCredentials(true).
exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L);
}
};
}
}
5.spring Data
5.1 JDBC
- 导入 JDBC 和 mysql 启动器配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- 配置数据源
spring:
datasource:
username: root
password: 123
url: jdbc:mysql://localhost:3306/batisdb?useUnicode=true&characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
- 通过模板即可获取数据
@RestController
public class jdbcController {
@Autowired
JdbcTemplate jdbcTemplate;
@RequestMapping("/userList")
public List<Map<String,Object>> sqUser(){
String sql="select * from user";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
return maps;
}
}
Hikari DataSource
默认情况下使用该数据源,号称是 Java Web 当前速度最快的数据源
5.2 Druid
描述:是阿里巴巴开源平台下的一个数据库连接池(数据源),加入了日志监控。
特点:Druid可以很好的监控DB连接池和SQL的执行情况,天生就是针对监控而生的DB连接池。
- 导包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.11</version>
</dependency>
- 配置(通过 type 切换数据源)
spring:
datasource:
username: root
password: 123
url: jdbc:mysql://localhost:3306/batisdb?useUnicode=true&characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
filters: stat
- 通过配置类导入
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
HashMap<String, String> init = new HashMap<>();
init.put("loginUsername","admin");
init.put("loginPassword","123456");
init.put("allow","http://localhost:8080/");
bean.setInitParameters(init);
return bean;
}
}
5.3 整合Mybatis
- 添加 mybatis 启动器配置
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
- 配置别名及mapper位置
mybatis:
type-aliases-package: com.zheng.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
- 编写程序(注意注解)
【user类省略…】
@Mapper
@Repository
public interface UserMapper {
List<User> getAllUsers();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zheng.mapper.UsersMapper">
<select id="getUserList" resultType="Users">
select * from users
</select>
</mapper>
@Autowired
UserMapper userMapper;
@RequestMapping("/users")
public List<User> myUser(){
List<User> allUsers = userMapper.getAllUsers();
return allUsers;
}
5.4 Spring Security
安全问题 ==> 认证(authentication)、授权(authorization) [ 代替 拦截器、过滤器 实现功能 ]
SpringSecurity是针对spring项目的安全框架,也是spring boot底层安全模块的默认选型,它可以实现强大的web安全控制。
- 添加启动类
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
- 编码
WebSecurityConfigurerAdapter :自定义 security 策略AuthenticationManagerBuilder :自定义认证策略- @EnableWebSecurity:开启webSecurity模式
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
http.formLogin().loginPage("/toLogin");
http.logout().logoutSuccessUrl("/");
http.rememberMe();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("youke").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
.and()
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3");
}
}
5.5 Shiro
- Apache Shiro 是一个java的安全框架
【】核心方法
- 获取对象:Subject currentUser = SecurityUtils.getSubject();
- 获取session:currentUser.getSession();
- 判断用户是否认证:currentUser.isAuthenticated();
- 获取用户认证:currentUser.getPrincipal();
- 获取用户拥有角色:currentUser.hasRole(“参数”);
- 获取用户权限:currentUser.isPermitted(“…”);
- 注销用户:currentUser.logout();
【】三大对象
-
Subject 当前用户 -
SecurityManager 安全管理(管理用户) -
Realm 连接数据
- 导入jar包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.9.1</version>
</dependency>
- 编码
【代码注释】
拦截 === 添加shiro的内置过滤器 anon(无需认证即可访问) authc(认证才能访问) user(有 记住我 功能才能访问) perms(拥有对某个资源的权限才能访问) role(拥有某个角色权限才能访问)
授权与认证:shiro中用户的授权、认证需要放在realm中,即请求都在config中进行过滤,但是真正的权限操作需要在realm中进行,它会将config类和realm类联动起来
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("用户授权=====");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
User currentUser = (User)subject.getPrincipal();
info.addStringPermission(currentUser.getPerms());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
ArrayList<User> users = new ArrayList<>();
users.add(new User("admin", "123456", "user:add"));
users.add(new User("zheng", "123456", ""));
User LoginUser = null;
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
String username = token.getUsername();
System.out.println("用户认证====="+username);
for (User user : users) {
if (user.getName().equals(username))LoginUser=user;
}
if (LoginUser==null)return null;
return new SimpleAuthenticationInfo(LoginUser,LoginUser.getPass(),"");
}
}
配置类
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFactory(@Qualifier("securityManager") DefaultWebSecurityManager manager){
ShiroFilterFactoryBean shiroFactory = new ShiroFilterFactoryBean();
shiroFactory.setSecurityManager(manager);
Map<String, String> map = new LinkedHashMap<>();
map.put("/toPage1","anon");
map.put("/toPage2","authc");
map.put("/toPage3","perms[user:add]");
shiroFactory.setFilterChainDefinitionMap(map);
shiroFactory.setLoginUrl("/toLogin");
return shiroFactory;
}
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(userRealm);
return manager;
}
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
处理请求:前端参数的获取需要我们在controller中进行,所以我们需要在controller中写一个获取前端参数,调用shiro进行用户认证
@RequestMapping("/login")
public String login(String username, String password, Model model){
System.out.println("用户登录——"+username);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
subject.login(token);
return "index";
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误!");
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误!");
}
return "login";
}
@RequestMapping("/logout")
public String logout(Model model){
SecurityUtils.getSubject().logout();
model.addAttribute("msg","请重新登录!");
return "login";
}
5.6 jwt
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
@Component
@ConfigurationProperties(prefix = "markerhub.jwt")
public class JwtUtil {
private String secret;
private long expireHour;
private String header;
public String generateToken(long id){
Date now = new Date();
Date expireDate = new Date( now.getTime()+(expireHour*1000*60*60) );
return Jwts.builder()
.setHeaderParam("typ","JWT")
.setSubject(id+"")
.setIssuedAt(now)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS512,secret)
.compact();
}
public Claims getClaimByToken(String token){
try {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}catch (Exception e){
return null;
}
}
public boolean isTokenExpired(Date expiration){
return expiration.before(new Date());
}
}
6. Swagger
- 导包
<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>
需要加上这个配置
- 编码
【代码注释】
RequestHandlerSelectors:配置要扫描的接口
- any() 全部扫描
- none() 全部不扫描
- basePackage(“com.zheng.controller”) 指定要扫描的包
- withClassAnnotation(PostMapping.class) 扫描类上的注解,参数是一个注解的反射对象
- withMethodAnnotation() 扫描方法上的注解,参数是一个注解的反射对象
配置文件:(基本信息;分组;启动阀;选择扫描条件及过滤)
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docketPost(Environment environment){
boolean flag = environment.acceptsProfiles(Profiles.of("dev"));
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("post")
.enable(flag)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(PostMapping.class))
.build();
}
@Bean
public Docket docketGet(Environment environment){
boolean flag = environment.acceptsProfiles(Profiles.of("dev"));
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("get")
.enable(flag)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
.build();
}
private ApiInfo apiInfo(){
return new ApiInfo("Api 文档",
"Api 文档",
"v1.0",
"urn:tos",
new Contact("", "", ""),
"返回首页",
"http://localhost:8081",
new ArrayList());
}
}
- 配置
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
- 注解
@Api(tags = “登录及注销”) //用于类上
@ApiOperation(“处理登录请求api”) //用于方法上
7.任务
7.1 异步
@EnableAsync(开启异步注解)
@Async(异步方法上添加)
在异步方法上加注解@Async ,并在main方法上加@EnableAsync 注解开启异步注解。
7.2 定时
@EnableScheduling(开启定时功能的注解)
@Scheduled(什么时候执行)
cron表达式
在service中编写一个需要设置定时的方法,为该方法添加@Scheduled z注解,并且为该注解传入cron参数。最后在main方法上加@EnableScheduling 注解开启定时功能的注解。
@Scheduled(cron = "0/10 * * * * ?")
public void timeTest(){
System.out.println("启动...");
}
7.3 发送邮件
导入启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置
spring:
mail:
username: 2655244515@qq.com
password: fgbmxpydemynebhj
host: smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable: true
编码
@Autowired
JavaMailSender mailSender;
@Test
void contextLoads1() {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("heading...");
mailMessage.setText("正文正文...");
mailMessage.setTo("lxt4132@sina.com");
mailMessage.setFrom("2655244515@qq.com");
mailSender.send(mailMessage);
}
@Test
void contextLoads2() throws MessagingException {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
helper.setSubject("headin。。。");
helper.setText("你好","<span style='color:red;'>你好啊</span>");
helper.addAttachment("a.png",new File("B:\\bg\\a.png"));
helper.setTo("lxt4132@sina.com");
helper.setFrom("2655244515@qq.com");
mailSender.send(mimeMessage);
}
8.分布式
分布式定义:分布式系统就是若干个独立计算机的集合,这些计算机对用户而言就像单个相关系统。它是通过网络进行通信、为完成共同的任务而协调工作的计算机节点组成的系统。
RPC(远程过程调用):是一种进程间的通信方式,它允许程序调用另一个地址空间的过程或函数,而不用程序员显式的编码这个远程调用的细节。即使得程序员本地调用和远程调用的代码基本相同。
RPC核心:通讯、序列化。
RPC与HTTP的区别:RPC是一种技术思想,而非一种规范和协议。
8.1 Dubbo
- dubbo是一款高性能、轻量级的开源java RPC框架
- 它提供三大核心能力:
- 面向接口的远程方法调用
- 智能容错和负载均衡
- 服务自动注册和发现
8.2 zookeeper
- zookeeper是一个分布式应用程序协调服务,提供服务的注册与发现
下载及安装:https://www.runoob.com/w3cnote/zookeeper-setup.html
【dubbo+zookeeper开发】
- 导入依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.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>
- 配置
server.port=8081
dubbo.application.name=provider-server
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.scan.base-packages=com.zheng.service
- 定义一个接口并实现,然后通过注解将服务暴露服务
@Service
@Component
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello() {
return null;
}
}
- 客户端也需要如上同样的依赖、配置及接口
@Service
public class UserService {
@Reference
DemoService demoService;
public void getTiket(){
System.out.println("客户端:"+demoService.sayHello());
}
}
* 注意:后续dubbo版本更新后,注解需要改变
|