java.lang.reflect.Method (java反射机制)

公司Vac方法过滤器使用到反射机制,读取xml配置文件过滤用户访问的方法名是否合法。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
@SuppressWarnings("unchecked")
Map<Object, Object> requestData = (Map<Object, Object>) httpRequest.getAttribute("requestData");
String methodName = (String) requestData.get(METHOD);
//获得bean的配置
String beanName = mapProtocol.get(methodName).get(BEAN);
// 去除.符号
methodName = getMethod(methodName);
//从spring context中获得bean
Object instance = getContext(filterConfig).getBean(beanName);
Class<? extends Object> clazz = instance.getClass();
Object resultContent = null;
try {
Method method = clazz
.getDeclaredMethod(methodName, getParamTypes());
Map params = removeSysParams(requestData);
resultContent = method.invoke(instance, params);
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof BusinessException) {
BusinessException serviceExp = (BusinessException) e
.getTargetException();
Assert.throwBPException(serviceExp.getMessageKey(),
serviceExp.getMessage());
}
e.printStackTrace();
Assert.throwBPException(INVOCATION_TARGET_EXP, e);
} catch (NoSuchMethodException e) {
e.printStackTrace();
Assert.throwBPException(ILLEGAL_ARGUMENT_EXP, e);

}
catch (IllegalAccessException e) {
e.printStackTrace();
Assert.throwBPException(ILLEGAL_ARGUMENT_EXP, e);

}
Enumeration enumeration = httpRequest.getAttributeNames();
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement().toString();
httpRequest.removeAttribute(name);
}
httpRequest.setAttribute(RESPONSEDATA, resultContent);

}

下面是Method类的源代码及说明:

  1. packagejava.lang.reflect;
  2. importsun.reflect.MethodAccessor;
  3. importsun.reflect.Reflection;
  4. /**
  5. *
  6. *描述方法的类
  7. *
  8. *注意使用反射的方式是首先通过
  9. *Class.getMethod(Stringname,Class[]parameterTypes)获得一个Method对象
  10. *String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得
  11. *Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Objectobj,Object[]args)
  12. *这里obj指调用方法的对象,args表示每个参数对应的值
  13. *
  14. *例子,一下两种方式的效果是一样的(当然性能不同)
  15. *Stringost="lqtest";
  16. *Stringnst=ost.substring(2,6);
  17. *
  18. *Stringost2="lqtest";
  19. *Class[]types={int.class,int.class};
  20. *Methodmed=String.class.getMethod("substring",types);
  21. *Object[]values={newInteger(2),newInteger(6)};
  22. *Stringnst2=(String)med.invoke(ost2,values);
  23. *
  24. *使用反射一切都是变化的,类名,方法名,参数列表,都是变量,而不是写死的,他们
  25. *在运行时才知道具体值,而不是编译期
  26. *
  27. *commentbyliqiang
  28. *
  29. *@authorKennethRussell
  30. *@authorNakulSaraiya
  31. */
  32. publicfinal
  33. classMethodextendsAccessibleObjectimplementsMember{
  34. //定义此方法的类对象
  35. privateClassclazz;
  36. privateintslot;
  37. //方法名,从1.4开始它变成intern的形式
  38. privateStringname;
  39. //返回类型
  40. privateClassreturnType;
  41. //参数列表
  42. privateClass[]parameterTypes;
  43. //异常列表
  44. privateClass[]exceptionTypes;
  45. //方法的描述符
  46. privateintmodifiers;
  47. //处理方法的实际对象
  48. privatevolatileMethodAccessormethodAccessor;
  49. //如果当前对象是通过拷贝得到的,则root指向拷贝前的对象
  50. privateMethodroot;
  51. //调用对象的安全检查的缓存,保存上一个通过检查的调用对象,如果当前的调用对象
  52. //不是上一个调用对象则做安全检查
  53. privatevolatileClasssecurityCheckTargetClassCache;
  54. //构造函数
  55. Method(ClassdeclaringClass,
  56. Stringname,
  57. Class[]parameterTypes,
  58. ClassreturnType,
  59. Class[]checkedExceptions,
  60. intmodifiers,
  61. intslot)
  62. {
  63. this.clazz=declaringClass;
  64. this.name=name;
  65. this.parameterTypes=parameterTypes;
  66. this.returnType=returnType;
  67. this.exceptionTypes=checkedExceptions;
  68. this.modifiers=modifiers;
  69. this.slot=slot;
  70. }
  71. //通过本对象的数据生成一个新对象
  72. Methodcopy(){
  73. //通过本对象的数据生成一个新对象
  74. Methodres=newMethod(clazz,name,parameterTypes,returnType,
  75. exceptionTypes,modifiers,slot);
  76. //新对象的root指向原对象
  77. res.root=this;
  78. //新对象与原对象公用一个MethodAccessor
  79. res.methodAccessor=methodAccessor;
  80. returnres;
  81. }
  82. //返回声明此函数的类
  83. publicClassgetDeclaringClass(){
  84. returnclazz;
  85. }
  86. //返回方法名
  87. publicStringgetName(){
  88. returnname;
  89. }
  90. //返回描述符
  91. publicintgetModifiers(){
  92. returnmodifiers;
  93. }
  94. //取得返回类型
  95. publicClassgetReturnType(){
  96. returnreturnType;
  97. }
  98. //返回参数列表
  99. publicClass[]getParameterTypes(){
  100. returncopy(parameterTypes);
  101. }
  102. //返回异常列表
  103. publicClass[]getExceptionTypes(){
  104. returncopy(exceptionTypes);
  105. }
  106. //判断obj是否与当前方法对象相等
  107. publicbooleanequals(Objectobj){
  108. if(obj!=null&&objinstanceofMethod){//如果是方法对象
  109. //转型
  110. Methodother=(Method)obj;
  111. //定义此方法的类和方法名相等
  112. if((getDeclaringClass()==other.getDeclaringClass())
  113. &&(getName()==other.getName())){
  114. /*Avoidunnecessarycloning*/
  115. Class[]params1=parameterTypes;
  116. Class[]params2=other.parameterTypes;
  117. //比较参数列表
  118. if(params1.length==params2.length){
  119. for(inti=0;i<params1.length;i++){
  120. if(params1[i]!=params2[i])
  121. returnfalse;
  122. }
  123. returntrue;
  124. }
  125. }
  126. }
  127. returnfalse;
  128. }
  129. //返回hashCode
  130. publicinthashCode(){
  131. returngetDeclaringClass().getName().hashCode()^getName().hashCode();
  132. }
  133. //方法对象的字符串表示
  134. publicStringtoString(){
  135. try{
  136. StringBuffersb=newStringBuffer();
  137. intmod=getModifiers();
  138. if(mod!=0){
  139. //标志符
  140. sb.append(Modifier.toString(mod)+"");
  141. }
  142. //注意它这里用的是Field方法中显示类的名字,这个方法显示数组类型跟Class.getName()不同
  143. //添加返回类型
  144. sb.append(Field.getTypeName(getReturnType())+"");
  145. //添加类名
  146. sb.append(Field.getTypeName(getDeclaringClass())+".");
  147. //添加方法名
  148. sb.append(getName()+"(");
  149. //参数列表
  150. Class[]params=parameterTypes;//avoidclone
  151. for(intj=0;j<params.length;j++){
  152. sb.append(Field.getTypeName(params[j]));
  153. if(j<(params.length-1))
  154. sb.append(",");
  155. }
  156. sb.append(")");
  157. //异常列表
  158. Class[]exceptions=exceptionTypes;//avoidclone
  159. if(exceptions.length>0){
  160. sb.append("throws");
  161. for(intk=0;k<exceptions.length;k++){
  162. sb.append(exceptions[k].getName());
  163. if(k<(exceptions.length-1))
  164. sb.append(",");
  165. }
  166. }
  167. returnsb.toString();
  168. }catch(Exceptione){
  169. return"<"+e+">";
  170. }
  171. }
  172. /**
  173. *
  174. *注意使用反射的方式是首先通过
  175. *Class.getMethod(Stringname,Class[]parameterTypes)获得一个Method对象
  176. *String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得
  177. *Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Objectobj,Object[]args)
  178. *如果调用的方法是static的则obj对象为null,如果方法没有参数,则args的长度为0或为null
  179. *如果返回值是原始类型则返回它的封装类,如果返回值是void则返回null
  180. */
  181. publicObjectinvoke(Objectobj,Object[]args)
  182. throwsIllegalAccessException,IllegalArgumentException,
  183. InvocationTargetException
  184. {
  185. if(!override){
  186. if(!Reflection.quickCheckMemberAccess(clazz,modifiers)){
  187. //获得调用对象的Class对象
  188. Classcaller=Reflection.getCallerClass(1);
  189. ClasstargetClass=((obj==null||!Modifier.isProtected(modifiers))
  190. ?clazz
  191. :obj.getClass());
  192. //调用此操作的对象或方法调用作用的对象与缓存不同,则做安全检查
  193. if(securityCheckCache!=caller||
  194. targetClass!=securityCheckTargetClassCache){
  195. Reflection.ensureMemberAccess(caller,clazz,obj,modifiers);
  196. securityCheckCache=caller;
  197. //通过安全检查的调用对象,缓存它供下次调用时使用
  198. securityCheckTargetClassCache=targetClass;
  199. }
  200. }
  201. }
  202. if(methodAccessor==null)acquireMethodAccessor();
  203. returnmethodAccessor.invoke(obj,args);
  204. }
  205. //如果此对象是由copy生成的,则对象与生成此对象的对象使用同一个MethodAccessor
  206. privatevoidacquireMethodAccessor(){
  207. MethodAccessortmp=null;
  208. if(root!=null)tmp=root.getMethodAccessor();
  209. if(tmp!=null){
  210. methodAccessor=tmp;
  211. return;
  212. }
  213. //不是由copy得来创建MethodAccessor对象
  214. tmp=reflectionFactory.newMethodAccessor(this);
  215. setMethodAccessor(tmp);
  216. }
  217. //返回MethodAccessor对象
  218. MethodAccessorgetMethodAccessor(){
  219. returnmethodAccessor;
  220. }
  221. //设置MethodAccessor对象
  222. voidsetMethodAccessor(MethodAccessoraccessor){
  223. methodAccessor=accessor;
  224. if(root!=null){//如果此对象是由copy的来
  225. //递归调用其上级
  226. root.setMethodAccessor(accessor);
  227. }
  228. }
  229. //生成一个新的Class数组并将原数组内容考到新数组中
  230. staticClass[]copy(Class[]in){
  231. intl=in.length;
  232. if(l==0)
  233. returnin;
  234. Class[]out=newClass[l];
  235. for(inti=0;i<l;i++)
  236. out[i]=in[i];
  237. returnout;
  238. }
  239. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值