文章结构

  • 什么是远程过程调用
  • 什么是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实现远程过程调用_rpc


上图是我修改后画的,也可以看看先知中这个师傅里边用的流程图

如何通过RMI实现远程过程调用_rmi_02


文章结构

  • 什么是远程过程调用
  • 什么是RMI
  • RMI调用示例
  • 公共接口
  • 客户端
  • 服务端
  • 调用过程图
  • 代码结构
  • 切面类
  • 被增强的类
  • aop配置
  • 测试程序


代码结构

如何通过RMI实现远程过程调用_java_03

切面类

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();
	}
}

欢迎与作者一起交流技术和工作生活