发表于: 2020-07-20 00:16:00
1 1307
今天完成的事情:
深度思考:
1.什么是rmi?为什么要使用rmi框架?
rmi,即远程方法调用。因为要分离远程调用分离出去的Service。
2.部署两台Service,如何在WEB中随机访问任意一台Service?
可以在每次访问时生成随机数字0或1,使用if判断若为0则访问Service1,若为1则访问Service2。或者使用cluster4spring,不过这个我没有试过。
3.RMI的简单介绍.
RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。RMI用于不同Java虚拟机之间的通信,这些虚拟机可以在不同的主机上、也可以在同一个主机上;一个虚拟机中的对象调用另一个虚拟上中的对象的方法,只不过是允许被远程调用的对象要通过一些标志加以标识。
4.什么是RMI,什么是RPC,两者之间的区别是什么?
RPC,(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务。
不同:
1:方法调用方式不同:
RMI中是通过在客户端的Stub对象作为远程接口进行远程方法的调用。每个远程方法都具有方法签名。如果一个方法在服务器上执行,但是没有相匹配的签名被添加到这个远程接口(stub)上,那么这个新方法就不能被RMI客户方所调用。
RPC中是通过网络服务协议向远程主机发送请求,请求包含了一个参数集和一个文本值,通常形成“classname.methodname(参数集)”的形式。RPC远程主机就去搜索与之相匹配的类和方法,找到后就执行方法并把结果编码,通过网络协议发回。
2:适用语言范围不同:
RMI只用于Java;
RPC是网络服务协议,与操作系统和语言无关。
3:调用结果的返回形式不同:
Java是面向对象的,所以RMI的调用结果可以是对象类型或者基本数据类型;RMI的结果统一由外部数据表示,这种语言抽象了字节序类和数据类型结构之间的差异。
5.什么是RMI,什么是RPC,两者之间的区别是什么?
技术上来说,可以调用。但是不建议这样使用,除非你这个方法是service公用的工具类。之所以不建议调用,是为了减少耦合性,同一层之间,最好不要耦合。比如maven项目,如果A层Service调用了B层Service的方法,那么就一定要先启动B工程,否则A层启动的时候就会报错,虽然可以不介意这种Exception,但是如果真的是B层的service出了问题那也会被误以为没错。如果这个时候B层又调用了A层的Service,那么真不知道该先启动哪个工程才好了。所以宁愿是统一调用。
6.Service对外暴露的接口粒度应该是怎么样的,是只提供基础的CRUD服务,还是应该将业务逻辑包含进去?
web service服务接口粒度太小了,那纯粹是不考虑xml解析性能了。简单的把类的方法暴露出来做服务接口,这样其实是把原来在 locale的调用放到了remote,除此之外几乎没有任何好处。粒度太大,会给使用者带来很多麻烦,因为在web service中,粒度很大的服务一般都需要很多参数来映射该服务各种各样的情况。
7.Thrift,Protobuffer分别是什么,一般用于什么场景?
Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。
protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。
可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。
8.什么是序列化和反序列化,在RMI中是否要实现 Serializable 接口, serialVersionUID的用处是什么?
序列化:把对象转换为字节序列的过程称为对象的序列化。
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
RMI 需要实现序列化接口 静态static的属性不能被序列化
serialVersionUID 的作用和用法
序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值
简单的来说,就是为了保证反序列化,是之前的序列化的那个类,保证它的唯一性。
学习SpringBoot。
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
使用springboot,就不用再配置各种xml文件了,十分简便。
使用springboot写一个HelloWorld入门web程序:
首先导入依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jnshu</groupId>
<artifactId>SpringBoot</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<parent>起版本控制的作用,定义了这个之后,后面再导包就不需要定义版本了。
spring-boot-starter-web是spring-boot场景启动器,可以自动导入web模块正常运行所需要依赖的组件。
spring-boot-maven-plugin是一个打包插件,可以将程序打包成一个可执行jar包。
接下来定义主程序类:
package com.jnshu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloMain {
public static void main(String[] args) {
SpringApplication.run(HelloMain.class,args);
}
}
@SpringBootApplication: springBoot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用,并且这是一个组合注解,查看源码可以看到:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@SpringBootConfiguration:SpringBoot的配置类
@EnableAutoConfiguration:开启自动配置功能,将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到spring容器
接下来定义Controller类:
package com.jnshu.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "HelloWorldjhkjhgkh";
}
}
接着只要运行主程序类即可,不需要再配置tomcat等复杂繁琐的步骤。可以感受到springboot的方便,不再需要配置原来的springmvc.xml,也不用再配置web.xml等文件了。
使用idea还可以快速构建springboot项目:
填写项目信息之后下一步:
可以选择自己需要的模块。
构建成功之后,系统会自动导入依赖,生成骨架:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jnshu</groupId>
<artifactId>springbootquick</artifactId>
<version>1.0</version>
<name>springbootquick</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
更加快捷。
resources文件夹下
static一般用来放各种静态资源:js,css,images
templates一般用来保存所有的模板页面。由于springboot默认使用jar包嵌入式的tomcat,不支持jsp页面,但是可以使用模板引擎(freemarker,thymeleaf)
application.properties:springboot应用的配置文件,有两种格式,properties和yml
properties配置文件值获取:
定义Student实体类:
package com.jnshu.Pojo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "student")
public class Student {
private String name;
private Integer age;
private String address;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
需要使用@Component将实体类注入spring工厂,@ConfigurationProperties将properties中的值绑定
properties:
Student.name="张三"
Student.age=18
Student.address="中国"
测试:
package com.jnshu;
import com.jnshu.Pojo.Student;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
class SpringbootquickApplicationTests {
@Autowired
Student student;
@Test
void contextLoads() {
System.out.println(student);
}
}
运行结果:
这里可能会出现中文乱码的问题,在settings里面设置一下fileEncoding即可,设为utf8.
使用yml也是一样的,不过yml有自己的语法,这里我暂时没有去学习。
明天计划完成的事情:
继续学习springboot
评论