通过反射执行方法
新入職,上級分配了個任務(wù),通過hessian實現(xiàn)rpc,服務(wù)端接口接收參數(shù)封裝成實體類,我實現(xiàn)了一個實體類RemoteParam,包括bean名稱,method名稱和參數(shù)列表,我通過class.getMethod(methodName,classes)來查找方法然后invoke執(zhí)行它:
?public class RemoteParam implements Serializable{
? ? /**
*?
*/
private static final long serialVersionUID = 114263984568171511L;
/* bean名稱 ?*/
private String beanName;
/* 方法名稱 */
private String methodName;
/* 參數(shù)列表 */
private List<? extends Serializable> list;
/* 設(shè)置連接時間*/
private Long timeout;
/* 子站地址 */
private String website;
/**
* 無參構(gòu)造方法
*/
public RemoteParam(){
}
/**
* 構(gòu)造方法
* @param beanName?
* @param methodName
*/
public RemoteParam(String beanName,String methodName){
this.beanName=beanName;
this.methodName=methodName;
}
/**
* 構(gòu)造方法
* @param beanName
* @param methodName
* @param list
*/
public RemoteParam(String beanName,String methodName,List<? extends Serializable> list){
this.beanName=beanName;
this.methodName=methodName;
if(list!=null){
if(!list.isEmpty()){
this.list=list;
}else{
this.list=null;
}
}else{
this.list=null;
}
}
/**
* 構(gòu)造方法
* @param beanName
* @param methodName
* @param timeout
*/
public RemoteParam(String beanName,String methodName,Long timeout){
this.beanName=beanName;
this.methodName=methodName;
this.timeout=timeout;
}
/**
* 構(gòu)造方法
* @param beanName
* @param methodName
* @param list
* @param timeout
*/
public RemoteParam(String beanName,String methodName,List<? extends Serializable> list,Long timeout){
this.beanName=beanName;
this.methodName=methodName;
if(list!=null){
if(!list.isEmpty()){
this.list=list;
}else{
this.list=null;
}
}else{
this.list=null;
}
this.timeout=timeout;
}
/**
* 構(gòu)造方法
* @param beanName?
* @param methodName
*/
public RemoteParam(String beanName,String methodName,String website){
this.beanName=beanName;
this.methodName=methodName;
this.website=website;
}
/**
* 構(gòu)造方法
* @param beanName
* @param methodName
* @param list
*/
public RemoteParam(String beanName,String methodName,List<? extends Serializable> list,String website){
this.beanName=beanName;
this.methodName=methodName;
if(list!=null){
if(!list.isEmpty()){
this.list=list;
}else{
this.list=null;
}
}else{
this.list=null;
}
this.website=website;
}
/**
* 構(gòu)造方法
* @param beanName
* @param methodName
* @param timeout
*/
public RemoteParam(String beanName,String methodName,Long timeout,String website){
this.beanName=beanName;
this.methodName=methodName;
this.timeout=timeout;
this.website=website;
}
/**
* 構(gòu)造方法
* @param beanName
* @param methodName
* @param list
* @param timeout
*/
public RemoteParam(String beanName,String methodName,List<? extends Serializable> list,Long timeout,String website){
this.beanName=beanName;
this.methodName=methodName;
if(list!=null){
if(!list.isEmpty()){
this.list=list;
}else{
this.list=null;
}
}else{
this.list=null;
}
this.timeout=timeout;
this.website=website;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public List<? extends Serializable> getList() {
return list;
}
public void setList(List<? extends Serializable> list) {
this.list = list;
}
public Long getTimeout() {
return timeout;
}
public void setTimeout(Long timeout) {
this.timeout = timeout;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
}
public RemoteMsg getRemoteResult(RemoteParam paramObject,LoginBean loginBean){
Object result = null ;
? ?RemoteMsg remoteMsg = new RemoteMsg();
String beanName=paramObject.getBeanName();
String methodName=paramObject.getMethodName();
Object[] objects=null;
Class<?>[] classes=null;
if(paramObject.getList()==null){
objects=new Object[]{};
classes=new Class<?>[]{};
}else{
if(paramObject.getList().isEmpty()){
objects=new Object[]{};
classes=new Class<?>[]{};
}else{
objects=paramObject.getList().toArray();
classes=(Class<?>[])ListUtil.listToClasses(paramObject.getList()).toArray(new Class[0]);
}
}
result=this.invokeMethod(beanName, methodName, objects, classes);
Object jsonResult = JSON.toJSON(result);
remoteMsg.setResult(jsonResult);
return remoteMsg;
}
@Override
public <T> T getRemoteResult(RemoteParam paramObject,LoginBean loginBean,Class<T> clazz){
Object result = null ;
String beanName=paramObject.getBeanName();
String methodName=paramObject.getMethodName();
Object[] objects=null;
Class<?>[] classes=null;
if(paramObject.getList()==null){
objects=new Object[]{};
classes=new Class<?>[]{};
}else{
if(paramObject.getList().isEmpty()){
objects=new Object[]{};
classes=new Class<?>[]{};
}else{
objects=paramObject.getList().toArray();
classes=(Class<?>[])ListUtil.listToClasses(paramObject.getList()).toArray(new Class[0]);
}
}
result=this.invokeMethod(beanName, methodName, objects, classes);
return (T)result;
}
private Object invokeMethod(String beanName, String methodName,
Object[] params, Class... type) {
Object serviceObj = null;
try {
serviceObj = this.context.getBean(beanName);
} catch (NoSuchBeanDefinitionException e) {
throw new RemoteException(RemoteMsgUtils.BEAN_ERROR_TYPE);
}
if (serviceObj == null) {
throw new RemoteException(RemoteMsgUtils.BEAN_ERROR_TYPE);
}
Method m = null;
try {
m = serviceObj.getClass().getMethod(methodName, type);
} catch (Exception e) {
throw new RemoteException(RemoteMsgUtils.METHOD_ERROR_TYPE,
e.getLocalizedMessage());
}
if (m == null) {
throw new RemoteException(RemoteMsgUtils.METHOD_ERROR_TYPE);
}
Object result;
try {
result = m.invoke(serviceObj, params);
} catch (Exception e) {
e.printStackTrace();
log.error(RemoteReceivedServiceImpl.class, e);
// e是invoke的時候拋出來的.應(yīng)該找它封裝的
String errorMsg = "";
try {
errorMsg = getErrorMsg(e);
} catch (Exception e1) {
// 說明沒有這個屬性,就不用了
}
RemoteException remoteException = null;
if (StringUtils.isNotBlank(errorMsg)) {
remoteException = new RemoteException(errorMsg);
remoteException.setErrorMsg(errorMsg);
} else {
remoteException = new RemoteException(
RemoteMsgUtils.INVOKE_ERROR_TYPE);
}
if (StringUtils.isNotBlank(errorMsg)) {
}
throw remoteException;
}
return result;
}
這里我是通過reflect獲取參數(shù)類型,然后傳入執(zhí)行方法,但是問題來了,如果傳入的是一個引用類型例如User,ArrayList...我獲取到的參數(shù)類型就不是method的了,因為method作為公用方法,那么入?yún)⒖隙ㄊ荗bject,List這些了,先前的想法是客戶端傳入需要轉(zhuǎn)換的class,但是正常Object可以了,但是List這種復(fù)雜對象就不ok了,所幸,class里面有個方法:Class.isAssignableForm(Class clz),可以匹配它的超類或借口。
重寫invokeMethod方法:
/**
? ?* 重寫invokeMethod
? ?*/
@SuppressWarnings("rawtypes")
private Object newInvokeMethod(String beanName, String methodName,
Object[] params, ?Class... type) {
Object serviceObj = null;
try {
serviceObj = this.context.getBean(beanName);
} catch (NoSuchBeanDefinitionException e) {
throw new RemoteException(RemoteMsgUtils.BEAN_ERROR_TYPE);
}
if (serviceObj == null) {
throw new RemoteException(RemoteMsgUtils.BEAN_ERROR_TYPE);
}
Method m = null;
Method[] ms=serviceObj.getClass().getMethods();
for(Method method:ms){
String mName=method.getName();
if(StringUtils.equals(methodName, mName)){
boolean isThis = true;
Class<?>[] pt=method.getParameterTypes();
if(type.length==pt.length){
int plength = type.length;
? ? ? ? ? ? ? ? ? ? ?if (plength == 0) {
? ? ? ? ? ? ? ? ? ? ? ? ?isThis = true;
? ? ? ? ? ? ? ? ? ? ?} else {
? ? ? ? ? ? ? ? ? ? ? ? ?for (int i = 0; i < plength; i++) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?boolean ff = pt[i]
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.isAssignableFrom(type[i]);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (!ff) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?isThis = false;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ?}
}else {
isThis=false;
}
if (isThis) {
m=method ;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
}
}
if (m == null) {
throw new RemoteException(RemoteMsgUtils.METHOD_ERROR_TYPE);
}
Object result;
try {
result = m.invoke(serviceObj, params);
} catch (Exception e) {
e.printStackTrace();
log.error(RemoteReceivedServiceImpl.class, e);
// e是invoke的時候拋出來的.應(yīng)該找它封裝的
String errorMsg = "";
try {
errorMsg = getErrorMsg(e);
} catch (Exception e1) {
// 說明沒有這個屬性,就不用了
}
RemoteException remoteException = null;
if (StringUtils.isNotBlank(errorMsg)) {
remoteException = new RemoteException(errorMsg);
remoteException.setErrorMsg(errorMsg);
} else {
remoteException = new RemoteException(
RemoteMsgUtils.INVOKE_ERROR_TYPE);
}
if (StringUtils.isNotBlank(errorMsg)) {
}
throw remoteException;
}
return result;
}
ok!問題解決。
總結(jié)
- 上一篇: git 基本命令记录
- 下一篇: Hessian使用记录