/** * Invoke the method with the given {@code name} on the supplied target * object with the supplied arguments. * <p>This method traverses the class hierarchy in search of the desired * method. In addition, an attempt will be made to make non-{@code public} * methods <em>accessible</em>, thus allowing one to invoke {@code protected}, * {@code private}, and <em>package-private</em> methods. * @param target the target object on which to invoke the specified method * @param name the name of the method to invoke * @param args the arguments to provide to the method * @return the invocation result, if any * @see MethodInvoker * @see ReflectionUtils#makeAccessible(Method) * @see ReflectionUtils#invokeMethod(Method, Object, Object[]) * @see ReflectionUtils#handleReflectionException(Exception) */ @SuppressWarnings("unchecked") public static <T> T invokeMethod(Object target, String name, Object... args) { Assert.notNull(target, "Target object must not be null"); Assert.hasText(name, "Method name must not be empty"); try { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(target); methodInvoker.setTargetMethod(name); methodInvoker.setArguments(args); methodInvoker.prepare(); if (logger.isDebugEnabled()) { logger.debug("Invoking method '" + name + "' on target [" + target + "] with arguments [" + ObjectUtils.nullSafeToString(args) + "]"); } return (T) methodInvoker.invoke(); } catch (Exception ex) { ReflectionUtils.handleReflectionException(ex); throw new IllegalStateException("Should never get here"); } }
/** * Invoke the method with the given {@code name} on the supplied target * object with the supplied arguments. * * <p>This method traverses the class hierarchy in search of the desired * method. In addition, an attempt will be made to make non-{@code public} * methods <em>accessible</em>, thus allowing one to invoke {@code protected}, * {@code private}, and <em>package-private</em> methods. * * @param target the target object on which to invoke the specified method * @param name the name of the method to invoke * @param args the arguments to provide to the method * @return the invocation result, if any * @see MethodInvoker * @see ReflectionUtils#makeAccessible(Method) * @see ReflectionUtils#invokeMethod(Method, Object, Object[]) * @see ReflectionUtils#handleReflectionException(Exception) */ @SuppressWarnings("unchecked") public static <T> T invokeMethod(Object target, String name, Object... args) { Assert.notNull(target, "Target object must not be null"); Assert.hasText(name, "Method name must not be empty"); try { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(target); methodInvoker.setTargetMethod(name); methodInvoker.setArguments(args); methodInvoker.prepare(); if (logger.isDebugEnabled()) { logger.debug("Invoking method [" + name + "] on target [" + target + "] with arguments [" + ObjectUtils.nullSafeToString(args) + "]"); } return (T) methodInvoker.invoke(); } catch (Exception e) { ReflectionUtils.handleReflectionException(e); } throw new IllegalStateException("Should never get here"); }
/** * Checks if the specified <code>module</code> is really a valid module, * i.e. if it can be added to the loaded modules or not. * * @param id * the id of the module to be checked * @param module * the module to be checked * * @return <code>true</code> if the specified <code>module</code> should be * added, otherwise <code>false</code> */ protected boolean isModule(final String id, final Object module) { if (id == null || module == null) { return false; } else if (coreSettingsId.equals(id)) { return false; } else if (coreConfigurationId.equals(id)) { return false; } else if (corePropertyHolderId.equals(id)) { return false; } else if (coreExceptionRegistryId.equals(id)) { return false; } else if (isAnonymousId(id)) { return false; } else if (module instanceof ConfigurationCoreSettings) { return false; } // also don't add any factories or creation of those of Spring those are // helper beans else if (module instanceof MethodInvoker) { return false; } else { return true; } }
/** * Find a matching constructor with the specified arguments. * * @return a matching constructor, or {@code null} if none */ protected Constructor<?> findMatchingConstructor() { final int argCount = constArgs.length; // get all the available constructors Constructor<?>[] candidates = clazz.getConstructors(); // check the constructors Constructor<?> matchingConstructor = null; int minTypeDiffWeight = Integer.MAX_VALUE; for (final Constructor<?> candidate : candidates) { final Class<?>[] paramTypes = candidate.getParameterTypes(); if (paramTypes.length == argCount) { int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight( paramTypes, constArgs); if (typeDiffWeight < minTypeDiffWeight) { minTypeDiffWeight = typeDiffWeight; matchingConstructor = candidate; } } } return matchingConstructor; }
private Object invoke(CachedInvocation invocation) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { final MethodInvoker invoker = new MethodInvoker(); invoker.setTargetObject(invocation.getTargetBean()); invoker.setArguments(invocation.getArguments()); invoker.setTargetMethod(invocation.getTargetMethod().getName()); invoker.prepare(); return invoker.invoke(); }
public int getTypeDifferenceWeight(Class<?>[] paramTypes) { // If valid arguments found, determine type difference weight. // Try type difference weight on both the converted arguments and // the raw arguments. If the raw weight is better, use it. // Decrease raw weight by 1024 to prefer it over equal converted weight. int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments); int rawTypeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024; return (rawTypeDiffWeight < typeDiffWeight ? rawTypeDiffWeight : typeDiffWeight); }
@Test public void testInvokeWithNullArgument() throws Exception { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("nullArgument"); methodInvoker.setArguments(new Object[] {null}); methodInvoker.prepare(); methodInvoker.invoke(); }
@Bean(name = "log4jInitialization") public MethodInvoker log4j() { MethodInvokingFactoryBean methodInvoker = new MethodInvokingFactoryBean(); methodInvoker.setTargetClass(Log4jConfigurer.class); methodInvoker.setTargetMethod("initLogging"); methodInvoker.setArguments(getLog4jArgs()); return methodInvoker; }
private QuartzCronJob buildQuartzCronJob(CronTriggerImpl cronTrigger) { JobDataMap jobDataMap = cronTrigger.getJobDataMap(); JobDetail jobDetail = (JobDetail) jobDataMap.get("jobDetail"); // 要执行的类 MethodInvoker methodInvoker = (MethodInvoker) jobDetail.getJobDataMap().get("methodInvoker"); QuartzCronJob quartzCronJob = new QuartzCronJob(); quartzCronJob.setCronTrigger(cronTrigger); quartzCronJob.setMethodInvoker(methodInvoker); return quartzCronJob; }
/** * Computes the routing index for a given remote invocation. */ public static Object computeRouting(SpaceRemotingInvocation remotingEntry, RemoteRoutingHandler remoteRoutingHandler, MethodInvocation methodInvocation) throws Exception { Object routing = null; if (remoteRoutingHandler != null) { routing = remoteRoutingHandler.computeRouting(remotingEntry); } if (routing == null) { Annotation[][] parametersAnnotations = methodInvocation.getMethod().getParameterAnnotations(); for (int i = 0; i < parametersAnnotations.length; i++) { Annotation[] parameterAnnotations = parametersAnnotations[i]; for (Annotation parameterAnnotation : parameterAnnotations) { if (parameterAnnotation instanceof Routing) { Routing routingAnnotation = (Routing) parameterAnnotation; if (StringUtils.hasLength(routingAnnotation.value())) { Object parameter = methodInvocation.getArguments()[i]; if (parameter instanceof SpaceDocument){ routing = ((SpaceDocument)parameter).getProperty(routingAnnotation.value()); } else { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(parameter); methodInvoker.setTargetMethod(routingAnnotation.value()); methodInvoker.prepare(); routing = methodInvoker.invoke(); } } else { routing = methodInvocation.getArguments()[i]; } i = parametersAnnotations.length; break; } } } } if (routing == null) { routing = remotingEntry.hashCode(); } return routing; }
/** * @param args * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException { ITestAnnotation iTestAnnotation = new ITestAnnotation() { @Override public void test() { System.out.println("test test"); } }; ClassPathScanningCandidateComponentProviderExtend provider = new ClassPathScanningCandidateComponentProviderExtend(false); provider.addIncludeFilter(new AnnotationTypeFilter(TestAnnotation.class)); String basePackage = "com/doctor"; Set<ScannedGenericBeanDefinition> components = provider.findCandidateComponents(basePackage); for (ScannedGenericBeanDefinition component : components) { System.out.printf("Component: %s\n", component.getBeanClassName()); System.out.println(component.getMetadata().getAnnotationTypes()); Class<?> classT = Class.forName(component.getBeanClassName()); Set<MethodMetadata> annotatedMethods = component.getMetadata().getAnnotatedMethods("com.doctor.practice01.TestAnnotation"); for (MethodMetadata methodMetadata : annotatedMethods) { System.out.println(methodMetadata.getMethodName()); System.out.println(methodMetadata.getDeclaringClassName()); System.out.println(methodMetadata.getReturnTypeName()); System.out.println(methodMetadata.getAnnotationAttributes("com.doctor.practice01.TestAnnotation")); MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetMethod(methodMetadata.getMethodName()); methodInvoker.setTargetObject(iTestAnnotation); methodInvoker.prepare(); methodInvoker.invoke(); } } }
/** * Set the MethodInvoker to use. */ public void setMethodInvoker(MethodInvoker methodInvoker) { this.methodInvoker = methodInvoker; }
/** * @return the methodInvoker */ public MethodInvoker getMethodInvoker() { return methodInvoker; }
public MethodInvoker getMethodInvoker() { return methodInvoker; }
public void setMethodInvoker(MethodInvoker methodInvoker) { this.methodInvoker = methodInvoker; }
private Object invoke(String id, Class<?> type, String method, Object... arg) { Object catalog = this.deployer.getBean(id, type); if (catalog == null) { return null; } String name = this.ids.get(id); String prefix = name + "/"; if (arg.length == 1) { if (arg[0] instanceof String) { String specific = arg[0].toString(); if (specific.startsWith(prefix)) { arg[0] = specific.substring(prefix.length()); } else { return null; } } } try { MethodInvoker invoker = new MethodInvoker(); invoker.setTargetObject(catalog); invoker.setTargetMethod(method); invoker.setArguments(arg); invoker.prepare(); Object result = invoker.invoke(); if (result != null) { if (result instanceof Collection) { Set<String> results = new LinkedHashSet<>(); for (Object value : (Collection<?>) result) { results.add(prefix + value); } return results; } else if (result instanceof String) { if (logger.isDebugEnabled()) { logger.debug("Prefixed (from \" + name + \"): " + result); } return prefix + result; } else { if (logger.isDebugEnabled()) { logger.debug("Result (from " + name + "): " + result); } return result; } } } catch (Exception e) { throw new IllegalStateException("Cannot extract catalog", e); } return null; }
@Override public void execute(final JobExecutionContext inContext) throws JobExecutionException { final JobDataMap theJobDataMap = inContext.getJobDetail().getJobDataMap(); final String theTaskName = inContext.getJobDetail().getKey().getName(); final String theTaskGroupName = inContext.getJobDetail().getKey().getGroup(); LOGGER.info("Started executing task {} in group {}", theTaskName, theTaskGroupName); final Object theTargetObject = theJobDataMap.get(TARGET_OBJECT_KEY); final Object theTargetMethodNameObject = theJobDataMap.get(TARGET_METHOD_KEY); final Object theTargetMethodParamsObject = theJobDataMap.get(TARGET_METHOD_PARAMETERS_KEY); if (theTargetObject != null && theTargetMethodNameObject != null) { /* Cast parameters to appropriate types. */ final String theTargetMethodName = (String) theTargetMethodNameObject; Object[] theTargetMethodParams = new Object[0]; /* * Parameter array may be null, in which a no-params method * invocation will be performed. */ if (theTargetMethodParamsObject != null) { theTargetMethodParams = (Object[]) theTargetMethodParamsObject; } /* * Check if logging is enabled before applying conversions only * needed for logging purposes. */ if (LOGGER.isDebugEnabled()) { final Object[] theDebugLogArguments = new Object[] {theTargetMethodName, theTargetObject.getClass().getName(), Arrays.asList(theTargetMethodParams).toString()}; LOGGER.debug("Invoking the method {} on object of the type {} with the parameters {}", theDebugLogArguments); } /* Invoke the target method. */ try { MethodInvoker theMethodInvoker = new MethodInvoker(); theMethodInvoker.setTargetObject(theTargetObject); theMethodInvoker.setTargetMethod(theTargetMethodName); theMethodInvoker.setArguments(theTargetMethodParams); theMethodInvoker.prepare(); theMethodInvoker.invoke(); } catch (final Throwable theException) { /* * Catch all exceptions, in order to allow the program to * continue to run despite exceptions. */ LOGGER.error( "An error occurred invoking the method " + theTargetMethodName + " on object of" + " the type " + theTargetObject.getClass().getName() + " with the parameters " + Arrays.asList(theTargetMethodParams).toString(), theException); } LOGGER.info("Successfully completed executing task {} in group {}", theTaskName, theTaskGroupName); } }
/** {@inheritDoc} */ public Object execute(String method, @SuppressWarnings("unchecked") Vector params) throws Exception { log().debug("calling: "+method+'('+toArgList(params)+')'); MethodInvoker invoker = new ArgumentConvertingMethodInvoker(); invoker.setTargetObject(this.proxy); invoker.setTargetMethod(getMethodName(method)); invoker.setArguments(params.toArray()); invoker.prepare(); try { Object returnValue = invoker.invoke(); if (returnValue == null && invoker.getPreparedMethod().getReturnType() == Void.TYPE) { returnValue = "void"; } else if (returnValue instanceof Map<?,?> && !(returnValue instanceof Hashtable<?,?>)) { returnValue = new Hashtable<Object, Object>((Map<?, ?>)returnValue); } else if (returnValue instanceof Collection<?> && !(returnValue instanceof Vector<?>)) { returnValue = new Vector<Object>((Collection<?>)returnValue); } log().debug("returning from: "+method+'('+toArgList(params)+") result = "+returnValue); return returnValue; } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); if (targetException instanceof IllegalArgumentException) { throw new MsgPreservingXmlRpcException(XmlRpcConstants.FAULT_INVALID_DATA, targetException.getMessage()); } else if (targetException instanceof MalformedURLException) { throw new MsgPreservingXmlRpcException(XmlRpcConstants.FAULT_INVALID_URL, targetException.getMessage()); } else if (targetException instanceof Exception && targetException.toString() != null) { throw (Exception)targetException; } String msg = targetException.toString(); if (msg == null) msg = targetException.getClass().getName(); Exception ex = new Exception(msg, targetException); ex.setStackTrace(targetException.getStackTrace()); throw ex; } }
/** * Creates a MethodInvoker instance from the cached invocation object and * invokes it to get the return value * * @param invocation * @return Return value resulted from the method invocation * @throws NoSuchMethodException * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InvocationTargetException */ private Object execute(CachedInvocation invocation) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { final MethodInvoker invoker = new MethodInvoker(); invoker.setTargetObject(invocation.getTargetBean()); invoker.setArguments(invocation.getArguments()); invoker.setTargetMethod(invocation.getTargetMethod().getName()); invoker.prepare(); return invoker.invoke(); }
/** * Constructor for JobMethodInvocationFailedException. * @param methodInvoker the MethodInvoker used for reflective invocation * @param cause the root cause (as thrown from the target method) */ public JobMethodInvocationFailedException(MethodInvoker methodInvoker, Throwable cause) { super("Invocation of method '" + methodInvoker.getTargetMethod() + "' on target class [" + methodInvoker.getTargetClass() + "] failed", cause); }