去看看Dubbo+zookeeper
SpringSecurity:Shiro 看看!!!
往下了解的springCloud
现在了解:Springboot
注解说明
@RestController: 注解在类上面的,表示类里面的函数都返回字符串---> @ResponseBody;
@SpringBootApplication: 程序主入口,注解的那个类本身就是spring的组件;
@SpringBootConfiguration: Spring的配置;
@Value: 给对应的属性赋值 ---> @Value("旺财") private String name;
@Component/@Autowired: 添加进容器(注入pojo类)/注入容器(对象);
@PropertySource/@value: 指定pojo所要加载的配置文件/@value("${name}"): 取出配置文件中所对应的值,并附上;
@Validated/@Email: 指定校对对应的pojo类,声明在类上面/添加在属性上面,指定属性必须是email格式;
@RequestParam/@PathVariable: 解析/user/?id=123中的id /解析/user/{
username}/blog 中的username
启动器
<dependency>
<groupId>org.spring.framework.bootgroupId>
<artifactId>spring-boot-start-webartifactId>
dependency>
**结论:**springboot所有的自动配置都是在启动的时候扫描加载:Spring.factories所有的配置都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有了对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!
SpringApplication类主要做的四件事情
关于SpringBoot谈谈你的理解
给一个pojo对象添加上一个``@Component` 相当于将这个对象注入到容器中
在别的类中直接 @Autowired
就可以将那个对象注入了。
@PropertySource/@value
@Validated/@Email
JSR303校验
@RequestParam/@PathVariable
@RequestParam和@PathVariable都能够完成类似的功能——因为本质上,它们都是用户的输入,只不过输入的部分不同,一个在URL路径部分,另一个在参数部分。要访问一篇博客文章,这两种URL设计都是可以的
使用选择方式:
1、当URL指向的是某一具体业务资源(或资源列表),例如博客,用户时,使用@PathVariable
2、当URL需要对资源或者资源列表进行过滤,筛选时,用@RequestParam
一旦我们在方法中定义了@RequestParam变量,如果访问的URL中不带有相应的参数,就会抛出异常——这是显然的,Spring尝试帮我们进行绑定,然而没有成功。但有的时候,参数确实不一定永远都存在,这时我们可以通过定义required属性:
@RequestParam(value = "id", required = false)
当然,在参数不存在的情况下,可能希望变量有一个默认值:
@RequestParam(value = "id", required = false, defaultValue = "0")
可以注入到配置类中
#普通的key-value
name: chenbin
# 对象
student:
name: chenbin
age: 3
# 行内写法
student: {
name: chenbin,age: 3}
#数组
pets:
- cat
- dog
- pig
pets: {
cat,dog,pig}
yaml也可以保存对应的对象:
person:
name: chenbin
age: 3
happy: false
birth: 1998/02/04
list:
- code
- music
- girl
dog:
name: hehe
age: 2
可以在一个pojo类上面通过@configurationProperties(prefix = ""person)
将上面所写是yaml 导入到对应的pojo。但是导入值的时候,需要所有的属性都对应起来
配置文件位置
以上文件位置 等级 从高到低
springboot的多环境配置
可以在默认环境中配置对应的 properties文件,有以下三个环境
只需要在默认环境下application.properties 中指定
spring.profiles.active=dev 即可 指定application-dev.properties 文件为配置文件
yaml一个文件,可以指定多个配置,不用新建三个文件
在配置文件中能配置的东西,都存在一个固有的规律 --> xxxAutoConfiguration xxxProperties 配置文件绑定,我们就可以使用自定义的配置了。
自动装配的原理
要解决的问题:
静态资源目录包含以下的目录
以上目录优先级 由上往下排列
总结:
在templates目录下的所有文件 只能通过controller跳转
导入对应的thymeleaf,只需要导入对应的依赖就行了。
自动装配:只需要实现WebMvcConfigurer 就可以定义一个自己的自动装配的类了。
Springboot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和组件默认的组合起来!、
以上配置可以取代@Controller里面的默认配置
register可以添加多个,可以取代多个访问跳转到同一个连接。
# 我们的配置文件的真实位置
spring.message.basename=i18n.login
判断前端传过来的l
参数,在LocalResolver中设置对应的语言。
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
//获取请求
String language=request.getParameter("l");
Locale locale=Locale.getDefault();//如果没有就使用默认的
//如果请求的链接携带了国际化的参数
if(!StringUtils.isEmpty(language)){
//zh_CN
String[] split=language.split("_");
//国家,地区
locale=new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
编写完以上的类之后需要将这个类添加进自己写的MyMvcConfig类中@bean 才可生效
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
//返回自定义的国际化
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/css/**","/img/**","/js/**");
}
}
// 编写拦截器
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功之后,是有用户的session的
Object loginUser = request.getSession().getAttribute("loginUser");
//没有session登录失败
if (loginUser==null){
request.setAttribute("msg","没有权限,请先登录!");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
return true;
}
}
}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
//返回自定义的国际化
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
///!!!!!!!!!!!!这里
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/css/**","/img/**","/js/**");
}
}
前端页面
可以提取公共页面。
1. th:fragment="sidebar"
2. th:replace="~{commons/commons::topbar}"
3. 如果要传递参数,可以直接传参
前端框架:x-admin
xxx Template:SpringBoot已经配置哈皮模板bean,拿来即用
jdbcTemplate
redisTemplate
配置Druid数据源
只需要在application.properties里面添加一行配置
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
以下是Druid默认的配置
而且使用Druid的时候记得导入log4j的jar
<dependency>
<groupId>log4groupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
添加入Druid的时候可以添加直接的配置文件
配置登录查看数据库操作的账号和密码
initParameters.put(“allow”,""): 后面为空是允许所有人访问。记得注入容器中,就可以登录Druid内置网站查看sql信息
//因为Springboot内置了servlet容器,所以没有web.xml文件,替代方法:ServletRegisteationBean
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vx32e9QV-1597890434860)(C:\Users\晨边\AppData\Local\Temp\WeChat Files\df874f443ec23739b5f4602e7fe7820.jpg)]
mybatis扫描包:
① 可以直接在启动类上添加@MapperScan(“com.iscas.Mapper”) 直接要扫描的包
② 可以直接在需要扫描的Mapper接口上面添加@Mapper注解
在web开发中,安全第一!过滤器,拦截器
shiro,springsecurity:很像,除了类不一样,名字不一样
认证,授权(vip1,vip2,vip3)
功能权限
访问权限
菜单权限
。。拦截器,过滤器:大量的原生代码~ 冗余
MVC - SPRING -SPRINGBOOT 框架思想
简介
Spring Security 是针对Spring项目的安全框架,也是Spring底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-starter-security模块。进行少量的配置,即可实现强大的安全管理!
记住几个类:
SPring Security 的两个主要目标是"认证"和"授权" (访问控制)
package com.iscas.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* @Author 晨边#CB
* @Date:created in 2020/6/14 0:40
* @Version V1.0
**/
//AOP: 拦截器!
@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");
//没有权限默认会到登录页面,需要开启登录页面 ----> 跳转到/login
http.formLogin().loginPage("/toLogin").usernameParameter("user").passwordParameter("pwd").loginProcessingUrl("/login");
//防止网站攻击 get
http.csrf().disable();//关闭csrf功能
//开启了注销功能,退出后 转到首页
http.logout().logoutSuccessUrl("/");
//开启记住我功能,cookies 默认保存两周,自定义接收前端的参数
http.rememberMe().rememberMeParameter("remember");
}
//认证 ,springboot 2.1.x 可以直接使用
//密码编码: passwordEncoder
// 在Spring security 5.0+ 新增了很多加密方法
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//定制一些认证的规则
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("chenbin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2","vip3")
.and()
.withUser("customer").password(new BCryptPasswordEncoder().encode("123")).roles("vip1");
}
}
配置数据库用户的认证和授权,jdbc
spring版本要2.0.9以下才可以呢
///获得当前用户信息:
Subject currentUser = SecurityUtils.getSubject();
//通过当前用户对象获得session
Session session = currentUser.getSession();
//判断当前的用户是否被认证
currentUser.isAuthenticated();
// 当前用户的角色
currentUser.hasRole("schwartz");
//当前用户的权限
currentUser.isPermitted("winnebago:drive:eagle5")
打扰了!!。没完成
简介
开发中产生的问题:
解决方案:
swagger:世界上最流行的API框架
官网:https://swagger.io/
在项目中使用Swagger需要使用springbox;
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.6.1version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.6.1version>
dependency>
@Configuration
@EnableSwagger2
public class SwaggerConfig {
}
Swagger的bean实例Docket;
package com.iscas.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;
import static springfox.documentation.service.ApiInfo.DEFAULT_CONTACT;
/**
* @Author 晨边#CB
* @Date:created in 2020/6/14 15:37
* @Version V1.0
**/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
//配置swagger 的Docket的bean实例;
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
//配置swagger信息=apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("陈彬", "https://www.baidu.como", "[email protected]");
return new ApiInfo(
"晨边的swagger Api文档",
"很酷哦!",
"v1.0",
"https://www.baidu.com",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0");
}
}
Docket select()
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.enable(false) //关闭,默认是true false为比启动swagger
//RequestHandlerSelectors 配置要扫描的接口的方式
//basePackage:制订要扫描的包
//any() : 扫描全部
//non(): 都不扫描
//withClassAnnotation: 扫描类上的注解,参数是一个注解的反射对象
//withMethodAnnotation 扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.iscas.controller"))
//paths 过滤什么路径
.paths(PathSelectors.ant("/chen/**"))
.build(); //工厂模式
}
我只希望Swagger在生产环境中使用,在发布的时候不使用
//配置swagger 的Docket的bean实例;
@Bean
public Docket docket(Environment environment){
// 设置要显示的swagger环境
Profiles profiles = Profiles.of("dev","test");
//获取项目的环境:监听是否处在自己设定的环境中。
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(flag)
.select()
//RequestHandlerSelectors 配置要扫描的接口的方式
//basePackage:制订要扫描的包
//any() : 扫描全部
//non(): 都不扫描
//withClassAnnotation: 扫描类上的注解,参数是一个注解的反射对象
//withMethodAnnotation 扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.iscas.controller"))
//paths 过滤什么路径
// .paths(PathSelectors.ant("/chen/**"))
.build(); //工厂模式
}
.groupName("陈彬");
如何配置多个分组,多个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");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("C");
}
实体类配置:
在controller中的配置
//Operation 不是放在类上的
@ApiOperation("Hello控制器类")
@GetMapping("/hello2")
public String hello(@ApiParam("用户名") String username){
return "hello"+username;
}
//添加上对应的注释
给pojo类添加上对应的注解
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}
总结:
Swagger是一个优秀的工具,几乎所有大公司都有使用它
[注意点: 在正式发布的时候,关闭swagger!! 处于安全考虑,而且节省内存]
异步任务-
定时任务-
邮件发送-
开启异步注解功能
第一步:在main方法中开启注解功能:@EnableAsync
//开启异步注解功能
@EnableAsync
@SpringBootApplication
public class WorkajaxApplication {
public static void main(String[] args) {
SpringApplication.run(WorkajaxApplication.class, args);
}
}
在对应要开启注解的方法上添加上@Async
注解
//告诉spring这是一个异步的方法
@Async
public void hello(){
try{
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("数据正在处理。。。");
}
邮件发送:
导入xml
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-start-mailartifactId>
dependency>
定时器功能:
TaskScheduler 任务调度者
TaskExecutor 任务执行者
@EnableScheduling //开启定时功能的注解
@Scheduled //什么时候执行
cron表达式
SpringBoot操作数据:spring-data jpa jdbc mongodb redis!
SpringData也是和SpringBoot齐名的项目
整合测试
说明:springBoot2.x之后,原来使用jedis被替换为lettuce
jedis:采用直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool 连接池! BIO模式
letture:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数量,NIO模式
导入依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
配置连接
#配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
package com.iscas;
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 RedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//redisTemplate 操作不同是数据类型,api和我们的指令是一样的
//opsForValue 操作字符串 类似String
//opsForList 操作list 类似List
//opsForSet
//opsForHash
//opsForZSet
//opsForGeo
//opsForHyperLogLog
//除了基本的操作,我们常用的方法都开口哟直接通过redisTemplate操作,比如事务,和基本的CRUD
//获取redis连接对象
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushDb();
// connection.flushAll();
redisTemplate.opsForValue().set("mykey","chenbin");
System.out.println(redisTemplate.opsForValue().get("mykey"));
}
}
在企业中,我们所有的pojo类都会序列化
编写一个直接的redisTemplate
package com.iscas.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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;
/**
* @Author 晨边#CB
* @Date:created in 2020/6/14 22:41
* @Version V1.0
**/
@Configuration
public class RedisConfig {
//一个固定的模板,企业中直接使用就行了
//编写我们自己的 redisTemplate
//自己定义了一个redistemplate
@Bean
@SuppressWarnings("all")
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
//我们为了自己开发方便,一般直接使用
RedisTemplate<String,Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
//json序列化配置
Jackson2JsonRedisSerializer<Object> 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);
template.afterPropertiesSet();
//配置具体的序列化方式
return template;
}
}
RPC:(Remote Procedure Call):远程过程调用,是一种进程间通信方式。
Dubbo
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需要Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展 进行加载。
如果不想使用Spring配置,可以通过API的方式进行调用
**快速启动手册:**http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
服务提供者(Provider): 暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务
服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
**注册中心(Registry)*注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心基于长连接推送变更数据给消费者,
**监控中心(Monitor)*服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
zookeeper:zoo+keeper:hadoop hive~
dubbo-admin: 是一个监控管理后台 查看我们注册了那些服务,那些服务被消费了
zookeeper:注册中心
Dubbo:jar包~
导入相关依赖:两个服务器都需要导入
<dependency>
<groupId>io.dubbo.springbootgroupId>
<artifactId>spring-boot-starter-dubboartifactId>
<version>1.0.0version>
dependency>
<dependency>
<groupId>com.github.sgroschupfgroupId>
<artifactId>zkclientartifactId>
<version>0.1version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
<version>2.12.0version>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.4.14version>
<exclusions>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.6.2version>
dependency>
提供者
server.port=8001
#服务应用名字
dubbo.application.name=provider-server
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#哪些服务要被注册
dubbo.scan.base-package=com.iscas.service
需要在启动类上加上@EnableDubbo
注解
package com.iscas;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubbo
public class ProviderServerApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderServerApplication.class, args);
}
}
service类需要继承一个接口,方便接受方调用。并且将该类添加进容器@Component
再加上@Service注解:—> 注意该注解的包:com.alibaba.dubbo.config.annotation.Service;
package com.iscas.service;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;
// zookeeper:服务注册与发现
/**
* @Author 晨边#CB
* @Date:created in 2020/6/15 10:38
* @Version V1.0
**/
@Service
@Component //使用了Dubbo后尽量不要使用@Service注解
public class TicketServiceImpl implements TicketService {
@Override
public String getTicket() {
return "hello chenbin!";
}
}
接收者
添加配置文件properties
server.port=8002
#消费者去哪里拿服务需要暴露自己的名字
dubbo.application.name = consumer-server
#注册中心的地址
dubbo.registry.address = zookeeper://127.0.0.1:2181
实现同样的接口:(用于接收提供者那边的接口)
public interface TicketService {
public String getTicket();
}
接收方的@Service是用于放入容器中的org.springframework.stereotype.Service;
在需要调用的提供者接口的上面,添加@Reference就可以调用接口了。
package com.iscas.service;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
/**
* @Author 晨边#CB
* @Date:created in 2020/6/15 10:43
* @Version V1.0
**/
@Service //放入到容器中
public class UserService {
//想拿到provider-server提供的票,要去注册中心拿到服务
@Reference //引用, Pom坐标,可以定义路径相同的接口名
TicketService ticketService;
public void buyTicket(){
String ticket = ticketService.getTicket();
System.out.println("在注册中心拿到一张票=>"+ticket);
}
}
启动zookeeper 再启动Dubbo,以及启动提供者类,启动接收者的测试类就可以调用了!
步骤:
前提:zookeeper服务已开启
暑期在中国科学院软件应用技术研究所学习的内容。
之前用Typora写了之后上传到GitHub
现在搬运过来csdn了