目的:模拟控制层Controller向业务层发送请求,远程调用
1、思路:控制层实现org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean,
业务层实现org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter
控制层去业务层寻找实例,然后通过反射执行方法,返回数据;
2、控制层:
配置:
<bean id="wanbaoService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="${rmi.address}"/>
<property name="serviceInterface" value="com.zjpii.wanbao.springrmi.WanbaoRMI"/>
</bean>
其中rmi.address 是业务层地址http://IP:端口/项目名/业务层实现HttpInvokerServiceExporter的自定义名 (http://localhost:8088/app/wanbaoAppRemote)
代码:
调用业务层方法的入口:
public class CallServiceUtil {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> T callDataService(String springBeanId, String methodName, Object[] params, Class[] classes) {
T returncode = (T) CallWanbaoAppServiceUtil.CallDataappService(springBeanId, methodName, params, classes);
return returncode;
}
}
public class CallWanbaoAppServiceUtil {
public static Object CallDataappService(String springBeanId, String methodName, Object[] params, Class[] classes)
throws BaseException {
Object returnObject = null;
try {
WanbaoRMI dsjyyRMI = (WanbaoRMI) SpringContextHolder.getBean("wanbaoService");
returnObject = dsjyyRMI.invokeMethod(springBeanId, methodName, params, classes);
} catch (BaseException e) {
throw e;
} catch (ClassNotFoundException e) {
throw new BaseException(e);
} catch (NoSuchMethodException e) {
throw new BaseException(e);
}
return returnObject;
}
}
RMI的接口和接口实现
public interface WanbaoRMI {
public Object invokeMethod(String springbeanid, String methodName, Object[] params, Class[] classes)
throws ClassNotFoundException, NoSuchMethodException, BaseException;
}
public class WanbaoRMIImpl implements WanbaoRMI {
@Override
public Object invokeMethod(String springbeanid, String methodName, Object[] params, Class[] classes)
throws ClassNotFoundException, NoSuchMethodException, BaseException {
BaseWanbaoControl oBaseCallbackControl = BaseWanbaoControl.getInstance();
return oBaseCallbackControl.invokeMethod(springbeanid, methodName, params, classes);
}
}
业务层:
配置:
<bean id="wanbaoAppService" class="com.zjpii.wanbao.springrmi.impl.WanbaoRMIImpl" />
<bean name="wanbaoAppRemote" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="wanbaoAppService"/>
<property name="serviceInterface" value="com.zjpii.wanbao.springrmi.WanbaoRMI"/>
</bean>
反射调用方法,返回数据:
public class BaseWanbaoControl {
Log logger = LogFactory.getLog(BaseWanbaoControl.class);
// 单例容器
private static Map<String, Object> serviceHolder = new HashMap<String, Object>();
static class SingletonHolder {
static BaseWanbaoControl instance = new BaseWanbaoControl();
}
public static BaseWanbaoControl getInstance() {
return SingletonHolder.instance;
}
public Object invokeMethod(String springbeanid, String methodName, Object[] params, Class[] classes)
throws ClassNotFoundException, NoSuchMethodException, BaseException {
Object returnObject = null;
try {
// Class clz = Class.forName(className);
Object serviceObj = null;
if (serviceHolder.get(springbeanid) == null) {
// serviceObj = clz.newInstance();
serviceObj = SpringContextHolder.getBean(springbeanid);
serviceHolder.put(springbeanid, serviceObj);
} else {
serviceObj = serviceHolder.get(springbeanid);
}
logger.info("execute springbean:" + springbeanid + " method:" + methodName);
Method m = null;
try {
m = serviceObj.getClass().getMethod(methodName, classes);
} catch (Exception e) {
for (Method method : serviceObj.getClass().getDeclaredMethods()) {
if (method.getName().equals(methodName)) {
m = method;
break;
}
}
}
returnObject = m.invoke(serviceObj, params);
} catch (IllegalAccessException e) {
throw new BaseException(e);
} catch (IllegalArgumentException e) {
throw new BaseException(e);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof BaseException) {
throw (BaseException) e.getCause();
} else {
throw new BaseException(e.getCause());
}
}
return returnObject;
}
}
SpringContextHolder:
<bean class="com.zjpii.wanbao.spring.SpringContextHolder" lazy-init="false" />
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextHolder.applicationContext = applicationContext;
}
/**
* 取得存储在静态变量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return applicationContext;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
return (T) applicationContext.getBeansOfType(clazz);
}
private static void checkApplicationContext() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
}
}
}
给自己留下一个思考 springCloud中 feign的使用是 去注册中心寻找服务,然后根据地址像这样去调用吗