https://www.jianshu.com/p/096dbda7d528
代理方式
public class RpcFactory implements InvocationHandler {
@Autowired
private NettyClient client;
Logger logger = LoggerFactory.getLogger(this.getClass());
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Request request = new Request();
request.setClassName(method.getDeclaringClass().getName());
request.setMethodName(method.getName());
request.setParameters(args);
request.setParameterTypes(method.getParameterTypes());
request.setId(IdUtil.getId());
Object result = client.send(request);
Class<?> returnType = method.getReturnType();
Response response = JSON.parseObject(result.toString(), Response.class);
if (response.getCode()==1){
throw new Exception(response.getError_msg());
}
if (returnType.isPrimitive() || String.class.isAssignableFrom(returnType)){
return response.getData();
}else if (Collection.class.isAssignableFrom(returnType)){
return JSONArray.parseArray(response.getData().toString(),Object.class);
}else if(Map.class.isAssignableFrom(returnType)){
return JSON.parseObject(response.getData().toString(),Map.class);
}else{
Object data = response.getData();
return JSONObject.parseObject(data.toString(), returnType);
}
}
}
package com.viewscenes.netsupervisor.configurer.rpc;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.context.support.AbstractApplicationContext;
import java.lang.reflect.Proxy;
/**
* Created by MACHENIKE on 2018-12-03.
*/
public class RpcFactoryBean<T> implements FactoryBean<T> {
private Class<T> rpcInterface;
@Autowired
private RpcFactory<T> factory;
/**
* {@link AbstractApplicationContext#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)}
* 会通过 rpcInterface 实例化 RpcFactoryBean
* @param rpcInterface
*/
public RpcFactoryBean(Class<T> rpcInterface) {
this.rpcInterface = rpcInterface;
}
/**
* 把 Bean 的定义 GenericBeanDefinition 放到了容器之后,就需要初始化这些 Bean,
* 而 Bean 的初始化时机有2个:
* 1、在程序第一个主动调用 getBean 的时候
* 2、在完成容器初始化的时候会初始化 lazy-init 配置为 false 的Bean(默认为false)
* 在这里,由于 RpcFactoryBean 未设置懒加载,故初始化的时机是第二种。上面两种初始化的过程都是一样的,
* 都会调用 {@link AbstractBeanFactory#doGetBean(java.lang.String, java.lang.Class, java.lang.Object[], boolean) 方法,
* 里面有个方法 getObjectForBeanInstance,会判断当前的 Bean 是否实现了 {@link FactoryBean}。
* 如果该 Bean 未实现 FactoryBean 接口,则直接返回该Bean实例;
* 如果该 Bean 实现了 FactoryBean 接口,则会返回的实例是 getObject() 返回值。
* @return
* @throws Exception
*/
public T getObject() throws Exception {
return getRpc();
}
public Class<?> getObjectType() {
return this.rpcInterface;
}
public boolean isSingleton() {
return true;
}
/**
* JDK 动态代理,当调用 rpcInterface 接口的方法时,会走 factory 的 invoke 方法
* @param <T>
* @return
*/
public <T> T getRpc() {
return (T) Proxy.newProxyInstance(rpcInterface.getClassLoader(), new Class[] { rpcInterface },factory);
}
}
// 0.容器启动
1.编码是要实现FactoryBean类,getObjectType方法通过外部传入用于初始化,getObject方法返回代理对象。
1.编码时需要标记哪些服务是rpc bean(dubbo:reference, sofa:reference ...)。
2.spring容器启动时基于bean加载注册时某些扩展点的进行判断为rpc bean。
针对rpc bean进行改造,将其BeanDefiniation的Class改为自定义的FactoryBean,
并改为按type注册,也就是FactoryBean.getObjectType方法。
3.BeanDefiniation实例化时(注册或者首次使用)会判断是否是FactoryBean实现类,
如果是会通过FactoryBean.getObject方法来返回实例对象(代理对象)。
4.代理对象在执行时实际执行时通过socket通信获取结果。并不会实际调用method.invoke,或者说
这一步被推到服务端进行执行了。
// 1.Client
class XXClientImpl{
@AutoWired
private UserService userService;
public void doSomething(){
userService.getUser();
}
}
// 2. 客户端通过动态代理 + socket(netty) + 服务端通过反射
// FactoryBean是springIoC提供的一项比较方便来实现动态代理类注册的功能,因为它把实现对象和注册类
// 在分化开来,并在框架内给予了特殊处理。
// 想想一下,如果没有FactoryBean,如何处理?也就是要把代理类作为普通bean来注册,这就需要一个地方来
// 维护jar类和代理类之间的关系,或者基于约定大于配置的思想,通过名称来关联。