通过反射执行方法

新入职,上级分配了个任务,通过hessian实现rpc,服务端接口接收参数封装成实体类,我实现了一个实体类RemoteParam,包括bean名称,method名称和参数列表,我通过class.getMethod(methodName,classes)来查找方法然后invoke执行它:


 public class RemoteParam implements Serializable{

    /**

*/
private static final long serialVersionUID = 114263984568171511L;
/* bean名称  */
private String beanName;
/* 方法名称 */
private String methodName;
/* 参数列表 */
private List<? extends Serializable> list;
/* 设置连接时间*/
private Long timeout;
/* 子站地址 */
private String website;



/**
* 无参构造方法
*/
public RemoteParam(){
}

/**
* 构造方法
* @param beanName 
* @param methodName
*/
public RemoteParam(String beanName,String methodName){
this.beanName=beanName;
this.methodName=methodName;
}
/**
* 构造方法
* @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;
}
}

/**
* 构造方法
* @param beanName
* @param methodName
* @param timeout
*/
public RemoteParam(String beanName,String methodName,Long timeout){
this.beanName=beanName;
this.methodName=methodName;
this.timeout=timeout;
}
/**
* 构造方法
* @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;
}


/**
* 构造方法
* @param beanName 
* @param methodName
*/
public RemoteParam(String beanName,String methodName,String website){
this.beanName=beanName;
this.methodName=methodName;
this.website=website;
}

/**
* 构造方法
* @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;
}

/**
* 构造方法
* @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;
}
/**
* 构造方法
* @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;
}

}

 @Override
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的时候抛出来的.应该找它封装的
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获取参数类型,然后传入执行方法,但是问题来了,如果传入的是一个引用类型例如User,ArrayList...我获取到的参数类型就不是method的了,因为method作为公用方法,那么入参肯定是Object,List这些了,先前的想法是客户端传入需要转换的class,但是正常Object可以了,但是List这种复杂对象就不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的时候抛出来的.应该找它封装的
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!问题解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值