1 使用方法
1.1 Provider
使用示例如下:
@RpcSchema(schemaId = "hello")
//@RpcSchema
public class HelloImpl implements Hello {
@Override
public String sayHi(String name) {
return "Hello " + name;
}
@Override
public String sayHello(Person person) {
return "Hello person " + person.getName();
}
}
1.2 Consumer
使用示例如下:
@Component
public class CustomHandlerCustomerMain {
// 表示使用的provider的信息
@RpcReference(microserviceName = "customerhandler", schemaId = "hello")
private static Hello hello;
public static void main(String[] args) throws InterruptedException {
BeanUtils.init();
System.out.println(hello.sayHi("Java Chassis"));
Person person = new Person();
person.setName("ServiceComb/Java Chassis");
System.out.println(hello.sayHello(person));
sleep(1000);
}
}
2 信息初始化
cse和spring的启动过程此处省略。
2.1 Consumer初始化过程
RpcReferenceProcessor类扫描RpcReference注解:
@Component
public class RpcReferenceProcessor implements BeanPostProcessor, EmbeddedValueResolverAware {
private StringValueResolver resolver;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 1 扫描所有field,处理扩展的field标注,递归扫描所有声明变量
ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
processConsumerField(bean, field);
}
});
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
protected void processConsumerField(Object bean, Field field) {
RpcReference reference = field.getAnnotation(RpcReference.class);
if (reference == null) {
return;
}
// 2 添加了RpcReference注解的变量都会进入该方法
handleReferenceField(bean, field, reference);
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.resolver = resolver;
}
private void handleReferenceField(Object obj, Field field,
RpcReference reference) {
String microserviceName = reference.microserviceName();
// 3 解析microserviceName,可以使用通配符
microserviceName = resolver.resolveStringValue(microserviceName);
PojoReferenceMeta pojoReference = new PojoReferenceMeta();
pojoReference.setMicroserviceName(microserviceName);
pojoReference.setSchemaId(reference.schemaId());
// 4 所有interface接口信息,创建代理使用
pojoReference.setConsumerIntf(field.getType());
// 5 创建动态代理对象
pojoReference.afterPropertiesSet();
ReflectionUtils.makeAccessible(field);
// 6 设置对象为动态代理对象
ReflectionUtils.setField(field, obj, pojoReference.getProxy());
}
}
其中,第5步,pojoReference.afterPropertiesSet(),创建动态代理,PojoReferenceMeta类的实现如下:
public class PojoReferenceMeta implements FactoryBean<Object>, InitializingBean {
// 原始数据
private String microserviceName;
private String schemaId;
// consumerIntf意思是consumer interface
private Class<?> consumerIntf;
// 根据intf创建出来的动态代理
// TODO:未实现本地优先(本地场景下,应该跳过handler机制)
private Object proxy;
......
@Override
public void afterPropertiesSet() {
if (consumerIntf == null) {
throw new ServiceCombException(
String.format(
"microserviceName=%s, schemaid=%s, \n"
+ "do not support implicit interface anymore, \n"
+ "because that caused problems:\n"
+ " 1.the startup process relies on other microservices\n"
+ " 2.cyclic dependent microservices can not be deployed\n"
+ "suggest to use @RpcReference or "
+ "<cse:rpc-reference id=\"...\" microservice-name=\"...\" schema-id=\"...\" interface=\"...\"></cse:rpc-reference>.",
microserviceName,
schemaId));
}
proxy = Invoker.createProxy(microserviceName, schemaId, consumerIntf);
}
}
其中,创建proxy过程在Invoker类中实现,Invoker类如下:
public class Invoker implements InvocationHandler {
protected final PojoConsumerMetaRefresher metaRefresher;
protected final PojoInvocationCreator invocationCreator;
protected final DefaultMethodMeta defaultMethodMeta = new DefaultMethodMeta();
protected InvocationCaller invocationCaller;
// 创建动态代理的实现
@SuppressWarnings("unchecked")
public static <T> T createProxy(String microserviceName, String schemaId, Class<?> consumerIntf) {
Invoker invoker = new Invoker(microserviceName, schemaId, consumerIntf);
// 创建代理,调用方法时,会调用其中的public Object invoke(Object proxy, Method method, Object[] args)方法
// Proxy的实现为java.lang.reflect.Proxy
return (T) Proxy.newProxyInstance(consumerIntf.getClassLoader(), new Class<?>[] {
consumerIntf}, invoker);
}
public Invoker(String microserviceName, String schemaId, Class<?> consumerIntf) {
this.metaRefresher = createInvokerMeta(microserviceName, schemaId, consumerIntf);
this.invocationCreator = createInvocationCreator();
}
protected PojoConsumerMetaRefresher createInvokerMeta(String microserviceName, String schemaId,
Class<?> consumerIntf) {
return new PojoConsumerMetaRefresher(microserviceName, schemaId, consumerIntf);
}
public PojoInvocationCreator createInvocationCreator() {
return new PojoInvocationCreator();
}
protected InvocationCaller createInvocationCaller() {
if (SCBEngine.getInstance().isFilterChainEnabled()) {
return new FilterInvocationCaller();
}
return new HandlerInvocationCaller();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isDefault()) {
return defaultMethodMeta.getOrCreateMethodHandle(proxy, method)
.invokeWithArguments(args);
}
SCBEngine.getInstance().ensureStatusUp();
prepareInvocationCaller();
return invocationCaller.call(method, metaRefresher, invocationCreator, args);
}
protected void prepareInvocationCaller() {
if (invocationCaller != null) {
return;
}
this.invocationCaller = createInvocationCaller();
}
}
后面,还会进行更加深入的介绍,初始化过程到此结束。
2.2 Provider初始化过程
在CSE初始化过程中,会调用如下过程:
public class SCBEngine {
// 类的构造方法
protected SCBEngine() {
......
producerProviderManager = new ProducerProviderManager(this);
serviceRegistryListener = new ServiceRegistryListener(this);
}
// 初始化过程中调用方法
private void doRun() throws Exception {
createProducerMicroserviceMeta();
triggerEvent(EventType.BEFORE_PRODUCER_PROVIDER);
producerProviderManager.init();
triggerEvent(EventType.AFTER_PRODUCER_PROVIDER);
......
RegistrationManager.INSTANCE.run();
}
}
ProducerProviderManager类的部分实现过程如下:
public class ProducerProviderManager {
private List<ProducerProvider> producerProviderList = new ArrayList<>(
SPIServiceUtils.getOrLoadSortedService(ProducerProvider.class));
public void init() {
registerProducerMetas(producerMetas);
for (ProducerProvider provider : producerProviderList) {
List<ProducerMeta> producerMetas = provider.init();
if (producerMetas == null) {
LOGGER.warn("ProducerProvider {} not provide any producer.", provider.getClass().getName());
continue;
}
registerProducerMetas(producerMetas);
}
}
}
producerProviderList通过SPI方式初始化,SPI的配置信息如下:
org.apache.servicecomb.provider.pojo.PojoProducerProvider
在ProducerProviderManager的init方法中,对producerProviderList进行逐一init初始化和处理。
RpcSchema注解使用PojoProducerProvider进行扫描,PojoProducerProvider的init方法如下:
@Override
public List<ProducerMeta> init() {
// for some test cases, there is no spring context
if (BeanUtils.getContext() == null) {
return Collections.emptyList();
}
PojoProducers pojoProducers = BeanUtils.getContext().getBean(PojoProducers.class);
for (ProducerMeta producerMeta : pojoProducers.getProducerMetas()) {
PojoProducerMeta pojoProducerMeta = (PojoProducerMeta) producerMeta;
// cse 提供了多种provider,pojoprovider实现方式不需要单独初始化
initPojoProducerMeta(pojoProducerMeta);
}
return pojoProducers.getProducerMetas();
}
PojoProducers扫描RpcSchema注解,并将接口契约信息保存入类的producerMetas变量中,PojoProducers的实现过程如下:
public class PojoProducers implements BeanPostProcessor {
private List<ProducerMeta> producerMetas = new ArrayList<>();
public synchronized void registerPojoProducer(PojoProducerMeta pojoProducer) {
producerMetas.add(pojoProducer);
}
......
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
processProvider(beanName, bean);
return bean;
}
protected void processProvider(String beanName, Object bean) {
// aop后,新的实例的父类可能是原class,也可能只是个proxy,父类不是原class
// 所以,需要先取出原class,再取标注
Class<?> beanCls = BeanUtils.getImplClassFromBean(bean);
if (beanCls == null) {
return;
}
RpcSchema rpcSchema = beanCls.getAnnotation(RpcSchema.class);
if (rpcSchema == null) {
return;
}
// 如果未设置schemaId,则会使用路径名称作为schemaId
String schemaId = rpcSchema.schemaId();
if (StringUtils.isEmpty(schemaId)) {
Class<?>[] intfs = beanCls.getInterfaces();
if (intfs.length == 1) {
schemaId = intfs[0].getName();
} else {
throw new Error("Must be schemaId or implements only one interface"

2077

被折叠的 条评论
为什么被折叠?



