Lottery lec3
今天主要学习一下lottery抽象项目中,第三节中如何使用Dubbo跑通Rpc过程调用以及在这个过程中遇到的知识盲点(实在是刚开始学习Java,不懂的地方太多了)Serializable接口
首先在创建Rpc的Request和Response对象时,必须将对象继承Serializable,这个可以理解(毕竟之前使用过brpc),因为在Rpc调用过程中,需要将Req和Response对象序列化为二进制发送给对端,那么需要实现特定的方法是很自然的..不过我尝试去implement Serializable接口,发现没有我需要去实现的方法,这就有点奇怪了~需要去了解一下这个序列化接口是怎么工作的?看一下这个接口的代码
fuck~为什么是空的,那这个接口还有什么意义呢?
经过一些查阅,这种没有内容的接口是一种标识接口,就是去通知JVM,当JVM检查到这个接口实现,意思就是用户不负责对类的序列化,由jvm负责该类的序列化。
和这个序列化相关,有一个知识点就是serialVersionUID。
在Serializable接口上,有这样的一段注释。
简单翻译一下就是:如果一个序列化类没有显示声明一个serialVersionUID,这个类在运行时会自动创建一个。但是官方强烈建议我们将所有除了enum类型的序列化类声明一个serialVersionUID。因为默认生成的serialversionUID对class极其敏感,在反序列化的时候很容易抛出InvalidClassException异常。
我理解的就是,如果我们不自己创建一个,那么序列化后的对象,在反序列化时,只要类有一点点变动(比如多了个方法、多了个字段),都会导致InvalidClassException。这样就导致与编译器的实现细节耦合,可能会导致在反序列化的过程中发生意外的InvalidClassException异常。
此外serialVersionUID字段地声明要尽可能使用private关键字修饰,这是因为该字段的声明只适用于声明的类,该字段作为成员变量被子类继承是没有用处的!
解决了这个问题,继续搭建环境~
当在定义Result(统一返回对象)的枚举信息时,遇到了知识盲区,java中枚举是如何表示的?
// 学习一下枚举类型
// enum类型继承java.lang.Enum
public enum Color {
RED(1,"我是红色"), // 这些变量默认被final、public、static修饰
BLUE(2,"我是蓝色"),
GREEN(3,"我是绿色");
private int value;
private String description;
// 枚举类型中可以定义构造函数和其它变量
private ColorEnum(int value, String description)
{
this.value = value;
this.description = description;
}
}
// 枚举类型优势:
//(1)类型安全。
//(2)紧凑有效的数据定义。
//(3)可以和程序其他部分完美交互。
//(4)运行效率高。
通过对上面枚举类型的学习,这个枚举类的代码可以很清晰的理解, 通过枚举变量的构造函数,可以创建4个不同的常量,有不同的错误码和说明信息,这样确实比C++中方便了很多,在C++项目中,往往会定义变量后,在创建专门的错误信息类,将不同的错误码和错误信息进行匹配,从而通过类似CodeToString()的方法,进行转换后打印...
public enum ResponseCode {
SUCCESS("0000", "成功"),
UN_ERROR("0001","未知失败"),
ILLEGAL_PARAMETER("0002","非法参数"),
INDEX_DUP("0003","主键冲突");
private String code;
private String info;
ResponseCode(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public String getInfo() {
return info;
}
}
然后..又遇到了另一个问题,当我创建好了common公共对象类Result, 在rpc模块下,直接import是找不到的,肯定是rpc模块没有引入common的jar包,那么如何解决这个问题呢?
很明显这个问题是由于我对maven的认识不足导致的(之前没有去了解maven的lifecycle)
下面就看一下这几个生命周期方法的作用
clean:清除之前构建生成的所有文件
validate:用于验证项目是否正确,并且其中有必要信息是否都可用
compile:编译项目中的源代码,主要是java文件
test:用合适的测试框架来进行测试,测试compile中编译出来的代码
package:生成target目录,编译、测试代码,生成测试报告,生成jar/war文件
vertify:这步是用来验证testm检查test的结果是否满足标准
install:将软件包安装到本地存储库中
deploy:复制最终的包至远程仓库,共享给其它开发人员和项目
这样一看很明显,我得先把common的模块compile 然后 package,在install到本地的maven仓库当中。
执行一套流程后,发现还是不能引入。不清楚具体原因hhh,继续查找问题。先来看看本地的maven仓库的情况
明明有对应的jar包,为什么不能引入呢?
又看了project setting中的module的依赖
明明也可以找到对应的位置..为什么还要爆红?
仔细看之后,发现是因为包名不一样,一个是com.xyf.lottery,另一个是com.xyf,晕死~
改变dependencies后,恢复正常
<dependencies>
<dependency>
<groupId>com.xyf</groupId>
<artifactId>lottery-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
在配置业务层的一个类时,看到了一种注解方法@Resource,虽然明白其应该和@Autowired作用类似,实现Bean的注入,下面简单了解下区别
@Resource和@Autowired注解都是用来实现依赖注入的。只是@AutoWried按by type自动注入,而@Resource默认按byName自动注入。
其它配置遇到的问题:
- mysql 8.0以上配置连接,需要将mysql配置属性改为如下,需要url添加serverTimezone, 同时driver-class-name改为com.mysql.cj.jdbc.Driver:
2. 要注意Dubbo接口实现类上的Service注解,需要是Dubbo包下面的,而不是Spring的Service注解。如下: