자바 가 어떻게 인 터 페 이 스 를 통 해 대 리 를 만 들 고 http 요청 을 하 는 지 자세히 알 아 보기
지금 이런 일 을 하려 면 회사 의 dubbo 서 비 스 는 모두 내부 네트워크 이지 만 대외 적 인 수출 을 제공 하여 링크 를 통 해 해당 하 는 dubbo 서 비 스 를 요청 할 수 있 습 니 다.구체 적 으로 어떻게 하 는 지 는 게 이 트 웨 이 이 이 고 http 요청 을 dubbo 요청 으로 바 꾸 고 일반화 호출 을 통 해 호출 해 야 합 니 다.코드 가 보이 지 않 습 니 다.)지금 은 테스트 를 편리 하 게 하기 위해 서 설정 한 인 터 페 이 스 를 http 요청 을 통 해 해당 하 는 링크 를 요청 해 야 합 니 다.
분석 하 다.
프로젝트 의 사상 은 사실 mybatis-spring 통합 패키지 의 사상 과 차이 가 많 지 않 고 모두 에이 전 트 를 생 성하 여 인 터 페 이 스 를 실행 하 는 방법 이다.
https://www.jb51.net/article/153378.htm
프로젝트 는 간단 한 spring 프로젝트 면 됩 니 다.그 다음 에 프로젝트 가 프로젝트 의 api 를 도입 한 다음 에 해당 하 는 서비스 이름 을 설정 하여 spring 을 통 해 대 리 를 생 성하 고 spring 용 기 를 주입 한 다음 에 실행 방법 은 해당 하 는 도 메 인+인터페이스 전체 경로+방법 명 에 따라 요청 하 는 것 입 니 다.매개 변 수 는 json 입 니 다.프로젝트 의 편 의 를 위해 hutool 도구 류 를 사용 하고 fastjson 을 직접 사용 하여 직렬 화 합 니 다.
조작 하 다.
우선 공장 bean 을 만 드 는 것 은 대리 로 돌아 가 는 Factory Bean 입 니 다.
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.reflect.Proxy;
/**
* @Title: BeanFactory , , bean( bean)
* @Description
* @Version
*/
public class HttpProxyFactoryBean<T> implements FactoryBean<T> {
/**
*【 】
* , HttpProxyFactoryBean Spring
* ( , @Component、@Service )
* BeanDefinition , , HttpProxyFactoryBean HttpProxyInvocationHandler
*
* :
* ApplicationContextAware setApplicationContext applicationContext,
* applicationContext
* applicationContext getBean InvocationHandler
*/
@Autowired
private HttpProxyInvocationHandler httpProxyInvocationHandler;
private Class<T> rpcInterface;
public HttpProxyFactoryBean(Class<T> rpcInterface){
this.rpcInterface = rpcInterface;
}
@Override
public T getObject() throws Exception {
// ComputerService
return (T)Proxy.newProxyInstance(rpcInterface.getClassLoader(),new Class[]{rpcInterface} ,httpProxyInvocationHandler);
}
@Override
public Class<?> getObjectType() {
return rpcInterface;
}
}
모든 동적 에이전트 클래스 는 Invocation Handler 라 는 인 터 페 이 스 를 실현 해 야 합 니 다.모든 동적 프 록 시 클래스 는 Invocation Handler 라 는 인 터 페 이 스 를 실현 해 야 하고 모든 프 록 시 클래스 의 인 스 턴 스 는 하나의 handler 와 연결 되 어 있 습 니 다.우리 가 프 록 시 대상 을 통 해 하나의 방법 을 호출 할 때 이 방법의 호출 은 Invocation Handler 라 는 인터페이스의 invoke 방법 으로 전 송 됩 니 다.
우 리 는 Invocation Handler 의 실현 류 를 spring 용기 에 직접 주입 한 다음 에 모든 인터페이스 가 같은 innvoke 방법 으로 갈 수 있 습 니 다.물론 모든 것 이 new 이 고 그 다음 에 구조 방법 에 특정한 매개 변 수 를 넣 을 수 있 습 니 다.내 쪽 은 대응 하 는 모든 대리 들 이 특별한 것 이 없 기 때문에 같은 곳 으로 간다.
일부 인자,요청 한 urlproxy.server Url,추가 요청 항목,proxy.project 를 정의 합 니 다.
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @Description http
* @Version
*/
@Component
public class HttpProxyInvocationHandler implements InvocationHandler {
@Value("${proxy.serverUrl}")
private String serverUrl;
@Value("${proxy.project}")
private String serverProject;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class<?> declaringClass = method.getDeclaringClass();
if (Object.class.equals(declaringClass)) {
return method.invoke(this, args);
}
String methodName = method.getName();
String name = method.getDeclaringClass().getName();
//
String url = serverUrl + name + "/" + methodName;
// String url = "http://test:8080/soa/com.rdd.TestService/createActivity";
HashMap<String, String> paramMap = new HashMap<>();
// String result = HttpRequest.post(url).headerMap(paramMap, true).body("[" + JSONObject.toJSONString(args) + "]").execute().body();
String result = HttpRequest.post(url).headerMap(paramMap, true).body(JSONObject.toJSONString(args)).execute().body();
System.out.println(">>>" + url + " :" + result);
//
Class<?> returnType = method.getReturnType();
if (returnType.isPrimitive() || String.class.isAssignableFrom(returnType)) {
if (returnType == int.class || returnType == Integer.class) {
return Integer.valueOf(result);
} else if (returnType == long.class || returnType == Long.class) {
return Long.valueOf(result);
}
return result;
} else if (Collection.class.isAssignableFrom(returnType)) {
return JSONArray.parseArray(result, Object.class);
} else if (Map.class.isAssignableFrom(returnType)) {
return JSON.parseObject(result, Map.class);
} else {
return JSONObject.parseObject(result, returnType);
}
}
}
마지막 으로 대응 하 는 공장 bean 을 bean 정의 로 밀봉 하여 spring 용기 에 주입 합 니 다.우리 의 인 터 페 이 스 는 일반적으로 jar 형식 입 니 다.저 는 proxy.txt 파일 에 간단하게 쓴 다음 에 해당 하 는 인터페이스 전 경 로 를 읽 고 spring 용기 에 주입 할 수 있 습 니 다.물론 특정한 가방 을 스 캔 하고 사용자 정의 주석 등 방식 으로 이 루어 질 수 있 습 니 다.
import cn.hutool.core.io.file.FileReader;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.*;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @Title:bean , bean
* @Date 2021/3/23 10:13
* @Description
* @Version
*/
@Component
@PropertySource("classpath:application.properties")
public class HttpProxyRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
/**
* bean spring
*
* @param beanDefinitionRegistry
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
// UTF-8 ,
FileReader fileReader = new FileReader("proxy.txt");
List<String> classStrList = fileReader.readLines();
Set<Class<?>> proxyClazzSet = new HashSet<>();
for (String s : classStrList) {
if (StringUtils.isBlank(s)) {
continue;
}
try {
Class<?> aClass = Class.forName(s);
proxyClazzSet.add(aClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
for (Class<?> targetClazz : proxyClazzSet) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(targetClazz);
GenericBeanDefinition definition = (GenericBeanDefinition) beanDefinitionBuilder.getRawBeanDefinition();
// Class<?>, Class, Class
//definition.getConstructorArgumentValues().addGenericArgumentValue(targetClazz);
definition.getConstructorArgumentValues().addGenericArgumentValue(targetClazz.getName());
//Bean ,
definition.setBeanClass(HttpProxyFactoryBean.class);
//
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
beanDefinitionRegistry.registerBeanDefinition(targetClazz.getName(),definition);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
자바 가 어떻게 인 터 페 이 스 를 통 해 프 록 시 를 만 들 고 http 요청 을 하 는 지 에 대한 자세 한 설명 은 여기까지 입 니 다.자바 생 성 프 록 시 에 대한 http 요청 내용 은 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 지원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.