项目地址:jms-support
执行流程:对调用的方法进行代理,将代理对象在mq中传输,监听到来的消息并调用真实对象的方法。
理解前提:需要有JDK代理的使用经验。
整个流程的思想和Dubbo实现远程调用是一样的,dubbo的核心读在于proxy的使用,所有的操作都尽量向proxy上靠拢,从表面上看dubbo配置完成后可以让远程的服务实现成为本地的一个bean被使用,事实上是本地对接口进行代理,通过网络传输(netty),在真实服务上调用真实的实现类执行请求完成后返回结果。
基于jms代理的远程方法调用,对接口进行JDK代理,代理通过消息发送进消息队列,被监听类监听到,在配置之后,对代理对象的方法调用将传递到真实的类方法调用上。
这里解释下代理,代理是由静态代理再衍生至动态代理,静态代理其实很常见,dao层被嵌入到service层也可以看做是静态代理,service层上的get操作最终传递到dao层上的get方法,只是service层上会做一些处理。动态代理的出现是为了解决静态代理需要为每一个被代理的类都进行一次重复的封装操作,动态代理是基于运行时的。
笔记:
1.实现ApplicationContextAware可以获取到容器,但前提是容器已经实例化完成,在这之前得到的applicationContext是null,但是同时实现BeanPostProcessor接口却可以得到容器,debug发现实现了BeanPostProcessor接口的类会得到ApplicationContextAwareProcessor的处理,只有经过这个处理器处理后才会调用set方法将容器setApplicationContext,初步判断原因是容器实例化时会先一步调用registerBeanPostProcessors方法,即实现了BeanPostProcessor接口的类会被优先处理。
2.手动注册bean时,需要在获取beanDefinationBuilder类后添加类属性,类实例中的属性会丢失。
3.使用field.set方法替换属性时,需要满足当前属性和obj是可相互转换的,否则将报错,IllegalArgumentsException。
4.使用@Bean,所标注的方法如果有参数,这个方法返回的将被注入容器的对象,需要有这个参数的构造函数存在,否则报错。