手撸RPC

//=========为服务提供http的访问方式=========
@RestController
public class RPCProvidersContrller implements ApplicationContextAware{

    private ApplicationContext applicationContext;
    @RequestMapping({"/**"})
    String hello(@RequestBody String req,HttpServletRequest request) throws Exception {
        String requestURI = request.getRequestURI();
        String[] split = requestURI.split("/");
        Object bean = applicationContext.getBean(split[split.length-2]);
        Method method = bean.getClass().getMethod(split[split.length-1], String.class);
        return method.invoke(bean, req).toString();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
//=========为服务提供http的访问方式=========

//=========远程服务引用=========
public class InterfaceFactoryBean<T> implements FactoryBean<T> {
    
    private Class<T> interfaceType;
 
    public InterfaceFactoryBean(Class<T> interfaceType) {
        this.interfaceType = interfaceType;
    }
 
    @SuppressWarnings("unchecked")
    @Override
    public T getObject() throws Exception {
        InterfaceProxy<T> handler = new InterfaceProxy<>(this.interfaceType);
        //可以定义接口与实际代理对象的映射Map类,使得不同的接口用不同的代理对象(这里所有的接口都是用同一个代理对象)
        return (T) Proxy.newProxyInstance(interfaceType.getClassLoader(),
                new Class[] {interfaceType}, handler);
    }
 
    @Override
    public Class<T> getObjectType() {
        return interfaceType;
    }
 
    @Override
    public boolean isSingleton() {
        return true;
    }
}

public class InterfaceProxy<T> implements InvocationHandler {

    private Class<T> interfaceType;

    public InterfaceProxy(Class<T> intefaceType) {
        this.interfaceType = interfaceType;
    }

    public Class<T> getInterfaceType() {
        return interfaceType;
    }

    public void setInterfaceType(Class<T> interfaceType) {
        this.interfaceType = interfaceType;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Field field = method.getClass().getDeclaredField("clazz");
        field.setAccessible(true);
        Class<?> clazz = (Class<?>) field.get(method);
        String serviceName = clazz.getSimpleName();
        System.out.println(serviceName);
        System.out.println(method.getName());
        // 构造一个http请求
        try {
            URL url = new URL("http://127.0.0.1:8080/" + serviceName + "/" + method.getName());
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(5000);
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
            httpURLConnection.connect();
            OutputStream outputStream = httpURLConnection.getOutputStream();
            Random random = new Random();
            String requstbody = "RANDOM" + random.nextInt(10000);
            outputStream.write(requstbody.getBytes(), 0, requstbody.getBytes().length);
            outputStream.close();
            BufferedReader bufferedReader = new BufferedReader(
                    new InputStreamReader(httpURLConnection.getInputStream()));
            String line = null;
            StringBuffer stringBuffer = new StringBuffer();
            while ((line = bufferedReader.readLine()) != null) {
                line = new String(line.getBytes("UTF-8"));
                stringBuffer.append(line);
            }
            bufferedReader.close();
            httpURLConnection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "动态注入";
    }
}

@Component
public class RPCConsumers implements BeanDefinitionRegistryPostProcessor,ResourceLoaderAware,ApplicationContextAware {
 
    @SuppressWarnings("rawtypes")
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        Set<Class<?>> beanClazzs = scannerPackages("接口所在包,需要动态代理的接口");
        for (Class beanClazz : beanClazzs) {
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClazz);
            GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
            definition.getConstructorArgumentValues().addGenericArgumentValue(beanClazz);
            definition.setBeanClass(InterfaceFactoryBean.class);
            definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
            registry.registerBeanDefinition(beanClazz.getSimpleName(), definition);
        }
    }
 
    private static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
 
    private MetadataReaderFactory metadataReaderFactory;
 
    private Set<Class<?>> scannerPackages(String basePackage) {
        Set<Class<?>> set = new LinkedHashSet<>();
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                resolveBasePackage(basePackage) + '/' + DEFAULT_RESOURCE_PATTERN;
        try {
            Resource[] resources = (Resource[]) this.resourcePatternResolver.getResources(packageSearchPath);
            for (Resource resource : resources) {
                if (resource.isReadable()) {
                    MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
                    String className = metadataReader.getClassMetadata().getClassName();
                    Class<?> clazz;
                    try {
                        clazz = Class.forName(className);
                        set.add(clazz);
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return set;
    }
 
    protected String resolveBasePackage(String basePackage) {
        return ClassUtils.convertClassNameToResourcePath(this.getEnvironment().resolveRequiredPlaceholders(basePackage));
    }
 
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
 
    }
 
    private ResourcePatternResolver resourcePatternResolver;
 
    private ApplicationContext applicationContext;
 
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
        this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
 
    private Environment getEnvironment() {
        return applicationContext.getEnvironment();
    }
}

//=========远程服务引用=========

上一篇:java – 使用html单元提交表单


下一篇:java – 关注谷歌“我感觉很幸运”重定向与httpURLConnection