上一篇看了下Springboot启动原理。我们知道了,Springboot在启动过程中,如何实现BeanDefinition–>Bean–>Proxy的过程。今天我们就从RPC框架Motan源码来看看,Motan是如何集成到Springboot中的。
在源码的springsupport包下面, 我们重点看AnnotationBean这个类。由这个类出发,完成了上述功能。
代码行格式说明:方法名()[实现类]{方法内部截取} 。为简明,方法参数部分省略。
AnnotationBean 实现了BeanPostProcessor。 在Springboot启动过程中,在refreshContext()
执行过程中,调用 invokeBeanFactoryPostProcessors()
。就会执行AnnotationBean 的postProcessBeanFactory()
方法。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory){
if (beanFactory instanceof BeanDefinitionRegistry) {
try {
Object scanner = scannerClass.getConstructor(new Class<?>[]{BeanDefinitionRegistry.class, boolean.class})
.newInstance(new Object[]{(BeanDefinitionRegistry) beanFactory, true});
// add filter
Class<?> filterClass = ClassUtils.forName();
// 需要扫描带@MotanService注解的类
Object filter = filterClass.getConstructor(Class.class).newInstance(MotanService.class);
Method scan = scannerClass.getMethod("scan", new Class<?>[]{String[].class});
// 从配置的annotationPackages开始扫描
scan.invoke(scanner, new Object[]{annotationPackages});
}
}
}
在postProcessBeforeInitialization方法中实现
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
// 找出@MontanRefer注解的字段
MotanReferer reference = field.getAnnotation(MotanReferer.class);
if (reference != null) {
// 这一行refer就是去做代理
Object value = refer(reference, field.getType());
if (value != null) {
// 将实现了调用代理类的字段赋值
field.set(bean, value);
}
}
}
}
return bean;
}
我们已经看到是从refer()方法进入,去构造代理的。那么我们继续看如何实现代理的
private <T> Object refer(MotanReferer reference, Class<?> referenceClass) {
return referenceConfig.getRef()[ReferConfig]{
initRef()[ReferConfig]{
// 这里从Zk获取了服务端的注册信息。假设我们是从AccountBusiness远端调用UserBusiness。那么这里就是将UserBusiness集群注册信息获取到
ClusterSupport<T> clusterSupport = createClusterSupport(refUrl, configHandler);
// 这里就是具体的代理实现了
ref = configHandler.refer(interfaceClass, clusters, proxy)[SimpleConfigHandler]{
return proxyFactory.getProxy(interfaceClass, clusters)
};
}
};
}
在postProcessAfterInitialization方法中实现
public Object postProcessAfterInitialization(Object bean, String beanName) throws
BeansException {
MotanService service = clazz.getAnnotation(MotanService.class);
if (service != null) {
serviceConfig.setRef(bean);
// 暴露或者注册到注册中心
serviceConfig.export();
}
return bean;
}
其实RPC框架的实现,说难也难说简单也简单。难的是你的设计将如何面对实际中的复杂应用场景;简单的是其思想可以仅仅浓缩成一行方法调用。这篇文章,我们只是讲了Motan如何集成到Springboot的。但是还有很多RPC框架实现难点,我们并没有说明。如:HA,路由,熔断,序列化等。但只要我们知道了设计思路,都可以从源码中清晰的看到别人如何实现的。