//=========为服务提供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();
}
}
//=========远程服务引用=========