文章结构
- 什么是远程过程调用
- 什么是RMI
- RMI调用示例
- 公共接口
- 客户端
- 服务端
- 调用过程图
- 代码结构
- 切面类
- 被增强的类
- aop配置
- 测试程序
什么是远程过程调用
RPC(Remote Processor Call)就是远程过程调用。是一个概念,既不是技术也不是框架。概念描述了一下信息:
1、客户端吧"我要调用什么类 、什么方法、什么参数"告诉服务器"
2、服务器根据要求完成调用,并把返回值返回给客户端
3、客户端就拿到了返回的数据。
上面3步完成后,就完成了远程过程调用。 关于RPC的概念可以参考马士兵老师的视频:https://www.bilibili.com/video/BV1zE41147Zq/?from=search&seid=13740626242455157002
什么是RMI
RMI全称是Remote Method Invocation-远程方法调用,其实它可以被看作是RPC的Java版本。Java RMI 支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。
RMI调用示例
公共接口
1、这个一个接口,是客户端和服务端都要有的接口。
2、客户端只有有这个接口知道服务端提供了哪些功能就可以了
3、服务端需要实现接口来提供功能
public interface UserService extends java.rmi.Remote {
public String getName() throws RemoteException;
public void updateName(String name) throws RemoteException;
}
客户端
public class Client {
public static void main(String[] args) throws Exception {
// 指明了我要去连那个服务器
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 8888);
// 告诉服务端我需要这个"功能接口"
UserService user = (UserService) registry.lookup("user");
// 告诉服务端RPC的调用信息(什么接口、什么方法、什么参数),要求服务端完成调用并返回结果
System.out.println("远程调用的结果是:" + user.getName());
}
}
服务端
public class Server {
public static void main(String[] args) throws Exception {
UserService liming = new UserServiceImpl();
// 注册一个端口提供服务
Registry registry = LocateRegistry.createRegistry(8888);
// 暴露服务端的功能
registry.bind("user",liming);
System.out.println("registry is running...");
System.out.println("liming is bind in registry");
}
}
public class UserServiceImpl extends UnicastRemoteObject implements UserService {
public String name;
public int age;
protected UserServiceImpl() throws RemoteException {
}
public String getName(){
return "["+ "张三" +"]";
}
public void updateName(String name){
this.name = name;
}
}
调用过程图
上图是我修改后画的,也可以看看先知中这个师傅里边用的流程图
文章结构
- 什么是远程过程调用
- 什么是RMI
- RMI调用示例
- 公共接口
- 客户端
- 服务端
- 调用过程图
- 代码结构
- 切面类
- 被增强的类
- aop配置
- 测试程序
代码结构
切面类
AspectJTest.java
@Aspect
public class AspectJTest {
@Pointcut("execution(* *.test(..))")
public void test() {}
@Before("test()")
public void beforeTest() {
System.err.println("aspect @Before...");
}
@After("test()")
public void afterTest() {
System.err.println("aspect @After...");
}
@Around("test()")
public Object aroundTest(ProceedingJoinPoint p) {
System.err.println("aspect @Around...before...");
Object o = null;
try {
o = p.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.err.println("aspect @Around...after...");
return o;
}
}
被增强的类
将被增强方法进行增强
TestBean.java
@Data
public class TestBean {
private String testStr = "testStr";
public void test() {
System.err.println("test...");
}
}
aop配置
application.xml
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启aop-->
<aop:aspectj-autoproxy/>
<!-- bean -->
<bean id="test" class="com.firefish.springsourcecodedeepanalysis.chapter07.TestBean"/>
<!-- 切面-->
<bean class="com.firefish.springsourcecodedeepanalysis.chapter07.AspectJTest"/>
</beans>
测试程序
AopTest.java
public class AopTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("com/firefish/springsourcecodedeepanalysis/chapter07/application.xml");
TestBean bean = (TestBean) context.getBean("test");
bean.test();
}
}
欢迎与作者一起交流技术和工作生活