1. @Reference 的工作原理
用法 :
@Service
public class OrderServiceImpl implements OrderService {
@Reference
private UserService userService;
@Override
public void test() {
System.out.println(userService.getUser());
}
}
当某个主要注册到spring容器中的bean 的属性上有@Reference注解时,并且 注解的injvm = false时(默认),表明该属性会被注入一个远程接口实例,用作rpc远程调用。
@Reference不是派生自spring默认支持的@Resource和@Autowired,那么说明spring是不支持该注解用于依赖注入的,dubbo对此进行了支持该注册的拓展。
1.1 ReferenceAnnotationBeanPostProcessor的引入
在入口@EnableDubbo配置了扫描的包路径
用于扫描类上含有dubbo@Service 和类属性上含有 @Reference 的bean
@EnableDubbo(scanBasePackages = "com.lb.dubbo_c.impl")
@PropertySource("dubbo.properties")
public class AnnoBean {
}
@DubboComponentScan 导入了DubboComponentScanRegistrar
DubboComponentScanRegistrar实现Spring的ImportBeanDefinitionRegistrar接口,被调用到实现的registerBeanDefinitions()时,会注册两个beanPostProcessor类
ServiceAnnotationBeanPostProcessor 对@Service的支持
ReferenceAnnotationBeanPostProcessor 对@Reference 的支持
1.2 ReferenceAnnotationBeanPostProcessor对@Reference的支持
ReferenceAnnotationBeanPostProcessor实现了和spring中支持@Autowired注册的AutowiredAnnotationBeanPostProcessor一模一样的接口 :MergedBeanDefinitionPostProcessor,继承了InstantiationAwareBeanPostProcessorAdapter。两者的工作逻辑几乎一模一样。
在bean实例化之后,对 bean进行依赖注入
1. 对每一个实例化的bean进行含有@Reference属性和方法的收集
2. 获取所依赖的bean实例
3. 反射设置到当前实例化bean的属性上
postProcessPropertyValues()
这个方法每个bean实例化都会调到,ReferenceAnnotationBeanPostProcessor用的是父类AnnotationInjectedBeanPostProcessor的
1.2.1 属性收集
判断方法和类上是否有@Reference注解,并将其包包装成AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata 对象,进行缓存
判断属性是否可以获取到@Reference,获取到返回
1.2.2 依赖注入
收集到需要依赖注入的属性之后,下一步获取到被依赖的bean实例,进行反射赋值
调用内部类AnnotatedFieldElement中的inject方法
获取到dubbo创建的代理实例,反射设置有@Reference的属性上