一、创建项目
二、设计目标
2.1 概论
设计一个基于接口的调用方式的远程调用框架,和spring 整合在一起
2.2 形式
2.2.1 导入spring的依赖
<?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.sxt</groupId>
<artifactId>link</artifactId>
<version>2.0</version>
<properties>
<spring.version>4.3.16.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${
spring.version}</version>
</dependency>
</dependencies>
</project>
2.2.2 服务的提供者的启动类和配置文件
启动类:
/**
* 服务提供者的启动类
*/
public class ProviderApp {
/**
* 我们和spring 整合在了一起
* @param args
*/
public static void main(String[] args) {
// 加载spring的容器
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:provider.xml");
app.start();
// 挂起jvm
try {
System.in.read() ;
} catch (IOException e) {
e.printStackTrace();
}
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.sxt.test.service.impl"></context:component-scan>
</beans>
2.2.3 接口和实现类的准备
2.2.4 服务消费者的启动类和配置文件
启动类:
/**
* 消费者
*/
public class ConsumerApp {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("consumer.xml");
app.start();
ConsumerService consumerService = app.getBean(ConsumerService.class);
consumerService.consumer(); // consumer 底层会触发远程调用
try {
// 挂起jvm
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.sxt.test.consumer.service.impl"></context:component-scan>
</beans>
2.2.5 服务消费者的接口和实现类
三、设计注解和功能
3.1 对于服务的提供者
要注册该服务,已经暴露该服务!
在dubbo 里面使用@service来完成该功能
对于link:
使用该注解:
代表该服务以后将被暴露出去
3.2 对于服务的消费者
去远程调用一个服务
使用该注解:
3.3 设计工具和接口
3.3.1 负载均衡的功能定义
3.3.2 注册中心的功能
3.3.3 编码器(影响性能的关键)
我们在远程调用时,不可避免要把对象转换为字节去在socket 上面发送?
我们昨天的Request 还实现序列化的接口了
我们把对象->字节
字节-> 对象
3.3.4 模型对象
3.3.5 代理对象的工具类
/**
* 代理对象的工具类
*/
public class ProxyUtil {
/**
* 通过接口创建代理对象
* @param interfacee
* @param <T>
* @return
*/
public static <T> T createProxy(Class<T> interfacee){
return (T) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),
new Class<?>[]{
interfacee},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* 1 普通方法的处理
*/
boolean isCommonMethod = false ;
if(isCommonMethod){
return commonInvoker(method.getName());
}
/**
* 2 远程调用的方法的处理
*/
Request request = new Request();
request.setInterfaceName(interfacee.getName());
request.setMethodName(method.getName());
request.setArgs(args);
return rpcInvoker(request); // 远程调用
}
}
);
}
/**
* 完成远程的调用
* @param request
* @