@Override public void afterPropertiesSet() throws Exception { Assert.notNull(BindableProxyFactory.this.channelFactory, "Channel Factory cannot be null"); ReflectionUtils.doWithMethods( this.type, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException { Input input = AnnotationUtils.findAnnotation(method, Input.class); if (input != null) { String name = BindingBeanDefinitionRegistryUtils.getChannelName(input, method); validateChannelType(method.getReturnType()); MessageChannel sharedChannel = locateSharedChannel(name); if (sharedChannel == null) { BindableProxyFactory.this.inputHolders.put( name, new ChannelHolder( BindableProxyFactory.this.channelFactory.createInputChannel(name), true)); } else { BindableProxyFactory.this.inputHolders.put( name, new ChannelHolder(sharedChannel, false)); } } } }); ReflectionUtils.doWithMethods( this.type, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException { Output output = AnnotationUtils.findAnnotation(method, Output.class); if (output != null) { String name = BindingBeanDefinitionRegistryUtils.getChannelName(output, method); validateChannelType(method.getReturnType()); MessageChannel sharedChannel = locateSharedChannel(name); if (sharedChannel == null) { BindableProxyFactory.this.outputHolders.put( name, new ChannelHolder( BindableProxyFactory.this.channelFactory.createOutputChannel(name), true)); } else { BindableProxyFactory.this.outputHolders.put( name, new ChannelHolder(sharedChannel, false)); } } } }); }
/** * Discover a {@link StepExecution} as a field in the test case or create one if none is * available. * * @param testContext the current test context * @return a {@link StepExecution} */ protected StepExecution getStepExecution(TestContext testContext) { Object target; try { Method method = TestContext.class.getMethod(GET_TEST_INSTANCE_METHOD); target = ReflectionUtils.invokeMethod(method, testContext); } catch (NoSuchMethodException e) { throw new IllegalStateException( "No such method " + GET_TEST_INSTANCE_METHOD + " on provided TestContext", e); } ExtractorMethodCallback method = new ExtractorMethodCallback(StepExecution.class, "getStepExecution"); ReflectionUtils.doWithMethods(target.getClass(), method); if (method.getName() != null) { HippyMethodInvoker invoker = new HippyMethodInvoker(); invoker.setTargetObject(target); invoker.setTargetMethod(method.getName()); try { invoker.prepare(); return (StepExecution) invoker.invoke(); } catch (Exception e) { throw new IllegalArgumentException( "Could not create step execution from method: " + method.getName(), e); } } return MetaDataInstanceFactory.createStepExecution(); }
@Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { Class<?> targetClass = AopUtils.getTargetClass(bean); final RabbitListener classLevelListener = AnnotationUtils.findAnnotation(bean.getClass(), RabbitListener.class); final List<Method> multiMethods = new ArrayList<Method>(); ReflectionUtils.doWithMethods( targetClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { RabbitListener rabbitListener = AnnotationUtils.getAnnotation(method, RabbitListener.class); if (rabbitListener != null) { processAmqpListener(rabbitListener, method, bean, beanName); } if (classLevelListener != null) { RabbitHandler rabbitHandler = AnnotationUtils.getAnnotation(method, RabbitHandler.class); if (rabbitHandler != null) { multiMethods.add(method); } } } }); if (classLevelListener != null) { processMultiMethodListener(classLevelListener, multiMethods, bean, beanName); } return bean; }
/** * Initialize a new HandlerMethodResolver for the specified handler type. * * @param handlerType the handler class to introspect */ public void init(Class<?> handlerType) { Class<?>[] handlerTypes = Proxy.isProxyClass(handlerType) ? handlerType.getInterfaces() : new Class<?>[] {handlerType}; for (final Class<?> currentHandlerType : handlerTypes) { ReflectionUtils.doWithMethods( currentHandlerType, new ReflectionUtils.MethodCallback() { public void doWith(Method method) { Method specificMethod = ClassUtils.getMostSpecificMethod(method, currentHandlerType); if (isHandlerMethod(method)) { handlerMethods.add(specificMethod); } else if (method.isAnnotationPresent(InitBinder.class)) { initBinderMethods.add(specificMethod); } else if (method.isAnnotationPresent(ModelAttribute.class)) { modelAttributeMethods.add(specificMethod); } } }, ReflectionUtils.NON_BRIDGED_METHODS); } this.typeLevelMapping = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); SessionAttributes sessionAttributes = handlerType.getAnnotation(SessionAttributes.class); this.sessionAttributesFound = (sessionAttributes != null); if (this.sessionAttributesFound) { this.sessionAttributeNames.addAll(Arrays.asList(sessionAttributes.value())); this.sessionAttributeTypes.addAll(Arrays.asList(sessionAttributes.types())); } }
@Override public Object postProcessAfterInitialization(final Object bean, String beanName) { if (!this.nonAnnotatedClasses.contains(bean.getClass())) { final Set<Method> annotatedMethods = new LinkedHashSet<Method>(1); Class<?> targetClass = AopUtils.getTargetClass(bean); ReflectionUtils.doWithMethods( targetClass, new MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { for (Scheduled scheduled : AnnotationUtils.getRepeatableAnnotation( method, Schedules.class, Scheduled.class)) { processScheduled(scheduled, method, bean); annotatedMethods.add(method); } } }); if (annotatedMethods.isEmpty()) { this.nonAnnotatedClasses.add(bean.getClass()); } } return bean; }
/** * Check that {@link #blogService} is advised for caching and that all methods relating to * published posts have the {@link Cacheable} annotation. Note that while more extensive mocking * and testing through {@code MockMvc} etc is possible, this approach is less fragile and much * more concise while still being likely to catch configuration errors. */ @Test public void blogServiceIsAdvisedForCaching() { assertThat("BlogService is not advised as expected", blogService, instanceOf(Advised.class)); boolean hasCachingAdvisor = false; for (Advisor advisor : ((Advised) blogService).getAdvisors()) { if (advisor instanceof BeanFactoryCacheOperationSourceAdvisor) { hasCachingAdvisor = true; break; } } assertTrue("BlogService is advised, but does not have caching advisor", hasCachingAdvisor); // @formatter:off ReflectionUtils.doWithMethods( BlogService.class, new ReflectionUtils.MethodCallback() { // TODO: lambda @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Cacheable cacheable = AnnotationUtils.findAnnotation(method, Cacheable.class); String methodName = method.getName(); if (methodName.matches("^get.*Published.*$")) { assertNotNull( "Method " + methodName + " was expected to have Cacheable annotation.", cacheable); String[] cacheName = cacheable.value(); assertThat(cacheName[0], equalTo(DatabaseConfig.CACHE_NAME)); } else { assertNull( "Method " + methodName + " was not expected to have Cacheable annotation.", cacheable); } } }); // @formatter:on }
@Test public void testGateway2() throws Exception { FtpOutboundGateway gateway = TestUtils.getPropertyValue(gateway2, "handler", FtpOutboundGateway.class); assertEquals( "X", TestUtils.getPropertyValue(gateway, "remoteFileTemplate.remoteFileSeparator")); assertNotNull(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory")); assertTrue( TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory") instanceof CachingSessionFactory); assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel")); assertEquals( "local-test-dir", TestUtils.getPropertyValue(gateway, "localDirectoryExpression.literalValue")); assertFalse((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory")); assertEquals(Command.GET, TestUtils.getPropertyValue(gateway, "command")); @SuppressWarnings("unchecked") Set<String> options = TestUtils.getPropertyValue(gateway, "options", Set.class); assertTrue(options.contains(Option.PRESERVE_TIMESTAMP)); gateway.handleMessage(new GenericMessage<String>("foo")); assertFalse(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class)); assertEquals(1, adviceCalled); // INT-3129 assertNotNull(TestUtils.getPropertyValue(gateway, "localFilenameGeneratorExpression")); final AtomicReference<Method> genMethod = new AtomicReference<Method>(); ReflectionUtils.doWithMethods( FtpOutboundGateway.class, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { if ("generateLocalFileName".equals(method.getName())) { method.setAccessible(true); genMethod.set(method); } } }); assertEquals( "FOO.afoo", genMethod.get().invoke(gateway, new GenericMessage<String>(""), "foo")); assertThat( TestUtils.getPropertyValue(gateway, "mputFilter"), Matchers.instanceOf(SimplePatternFileListFilter.class)); }
/** * Searches for {@link org.springframework.security.access.prepost.PreAuthorize} and {@link * org.springframework.security.access.prepost.PostAuthorize} annotations representing permissions * and parses them. Parsed annotations are used to find permissions. After that those permissions * are added to {@link org.motechproject.security.service.MotechPermissionService} * * @param bean to be processed * @param beanName name of the bean * @return processed bean */ @Override public Object postProcessAfterInitialization(final Object bean, final String beanName) { LOGGER.debug("Searching for security annotations in: {}", beanName); doWithMethods( bean.getClass(), new MethodCallback() { @Override public void doWith(Method method) throws IllegalAccessException { Method methodOfOriginalClassIfProxied = findMethod(getTargetClass(bean), method.getName(), method.getParameterTypes()); if (methodOfOriginalClassIfProxied != null) { PreAuthorize preAuthorize = findAnnotation(methodOfOriginalClassIfProxied, PreAuthorize.class); PostAuthorize postAuthorize = findAnnotation(methodOfOriginalClassIfProxied, PostAuthorize.class); List<String> annotations = new ArrayList<>(2); List<String> permissions = new ArrayList<>(); if (preAuthorize != null) { annotations.add(preAuthorize.value()); } if (postAuthorize != null) { annotations.add(postAuthorize.value()); } for (String annotation : annotations) { SpelExpression expression = (SpelExpression) annotationParser.parseExpression(annotation); permissions.addAll(findPermissions(expression.getAST())); } addRoleAndPermissions(permissions); } } }); LOGGER.debug("Searched for security annotations in: {}", beanName); return bean; }
/** * 检查上下文中的BOP服务方法 * * @throws org.springframework.beans.BeansException */ private void registerFromContext(final ApplicationContext context) throws BeansException { if (logger.isDebugEnabled()) { logger.debug("对Spring上下文中的Bean进行扫描,查找ROP服务方法: " + context); } String[] beanNames = context.getBeanNamesForType(Object.class); for (final String beanName : beanNames) { Class<?> handlerType = context.getType(beanName); ReflectionUtils.doWithMethods( handlerType, new ReflectionUtils.MethodCallback() { public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { ReflectionUtils.makeAccessible(method); ServiceMethod serviceMethod = method.getAnnotation(ServiceMethod.class); ServiceMethodGroup serviceMethodGroup = method.getDeclaringClass().getAnnotation(ServiceMethodGroup.class); ServiceMethodDefinition definition = null; if (serviceMethodGroup != null) { definition = buildServiceMethodDefinition(serviceMethodGroup, serviceMethod); } else { definition = buildServiceMethodDefinition(serviceMethod); } ServiceMethodHandler serviceMethodHandler = new ServiceMethodHandler(); serviceMethodHandler.setServiceMethodDefinition(definition); // 1.set handler serviceMethodHandler.setHandler(context.getBean(beanName)); // handler serviceMethodHandler.setHandlerMethod(method); // handler'method if (method.getParameterTypes().length > 0) { // handler method's parameter Class<?> aClass = method.getParameterTypes()[0]; Assert.isAssignable(RopRequest.class, aClass, "@ServiceMethod方法入参必须是RopRequest"); serviceMethodHandler.setRequestType((Class<? extends RopRequest>) aClass); } // 2.set sign fieldNames serviceMethodHandler.setIgnoreSignFieldNames( getIgnoreSignFieldNames(serviceMethodHandler.getRequestType())); addServiceMethod( serviceMethod.value(), serviceMethod.version(), serviceMethodHandler); if (logger.isDebugEnabled()) { logger.debug( "注册服务方法:" + method.getDeclaringClass().getCanonicalName() + "#" + method.getName() + "(..)"); } } }, new ReflectionUtils.MethodFilter() { public boolean matches(Method method) { return AnnotationUtils.findAnnotation(method, ServiceMethod.class) != null; } }); } if (context.getParent() != null) { registerFromContext(context.getParent()); } if (logger.isInfoEnabled()) { logger.info("共注册了" + serviceHandlerMap.size() + "个服务方法"); } }
@Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { Assert.notNull(this.beanFactory, "BeanFactory must not be null"); final Class<?> beanClass = this.getBeanClass(bean); if (this.requireComponentAnnotation && AnnotationUtils.findAnnotation(beanClass, Component.class) == null) { // we only post-process stereotype components return bean; } ReflectionUtils.doWithMethods( beanClass, new ReflectionUtils.MethodCallback() { @Override @SuppressWarnings({"unchecked", "rawtypes"}) public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Map<Class<? extends Annotation>, List<Annotation>> annotationChains = new HashMap<Class<? extends Annotation>, List<Annotation>>(); for (Class<? extends Annotation> annotationType : MessagingAnnotationPostProcessor.this.postProcessors.keySet()) { if (AnnotatedElementUtils.isAnnotated(method, annotationType.getName())) { List<Annotation> annotationChain = getAnnotationChain(method, annotationType); if (annotationChain.size() > 0) { annotationChains.put(annotationType, annotationChain); } } } for (Map.Entry<Class<? extends Annotation>, List<Annotation>> entry : annotationChains.entrySet()) { Class<? extends Annotation> annotationType = entry.getKey(); List<Annotation> annotations = entry.getValue(); MethodAnnotationPostProcessor postProcessor = MessagingAnnotationPostProcessor.this.postProcessors.get(annotationType); if (postProcessor != null && postProcessor.shouldCreateEndpoint(method, annotations)) { Method targetMethod = method; if (AopUtils.isJdkDynamicProxy(bean)) { try { targetMethod = bean.getClass().getMethod(method.getName(), method.getParameterTypes()); } catch (NoSuchMethodException e) { throw new IllegalArgumentException( "Service methods must be extracted to the service " + "interface for JdkDynamicProxy. The affected bean is: '" + beanName + "' " + "and its method: '" + method + "'", e); } } Object result = postProcessor.postProcess(bean, beanName, targetMethod, annotations); if (result != null && result instanceof AbstractEndpoint) { AbstractEndpoint endpoint = (AbstractEndpoint) result; String autoStartup = MessagingAnnotationUtils.resolveAttribute( annotations, "autoStartup", String.class); if (StringUtils.hasText(autoStartup)) { autoStartup = getBeanFactory().resolveEmbeddedValue(autoStartup); if (StringUtils.hasText(autoStartup)) { endpoint.setAutoStartup(Boolean.parseBoolean(autoStartup)); } } String phase = MessagingAnnotationUtils.resolveAttribute(annotations, "phase", String.class); if (StringUtils.hasText(phase)) { phase = getBeanFactory().resolveEmbeddedValue(phase); if (StringUtils.hasText(phase)) { endpoint.setPhase(Integer.parseInt(phase)); } } String endpointBeanName = generateBeanName(beanName, method, annotationType); endpoint.setBeanName(endpointBeanName); getBeanFactory().registerSingleton(endpointBeanName, endpoint); getBeanFactory().initializeBean(endpoint, endpointBeanName); Role role = AnnotationUtils.findAnnotation(method, Role.class); if (role != null) { MessagingAnnotationPostProcessor.this.lazyLifecycleRoles.add( role.value(), endpointBeanName); } } } } } }, ReflectionUtils.USER_DECLARED_METHODS); return bean; }
@Test public void testKafkaMessageDrivenChannelAdapterParser() throws Exception { assertFalse(this.kafkaListener.isAutoStartup()); assertFalse(this.kafkaListener.isRunning()); assertEquals(100, this.kafkaListener.getPhase()); assertSame(this.nullChannel, TestUtils.getPropertyValue(this.kafkaListener, "outputChannel")); assertSame(this.errorChannel, TestUtils.getPropertyValue(this.kafkaListener, "errorChannel")); assertSame(this.keyDecoder, TestUtils.getPropertyValue(this.kafkaListener, "keyDecoder")); assertSame( this.payloadDecoder, TestUtils.getPropertyValue(this.kafkaListener, "payloadDecoder")); KafkaMessageListenerContainer container = TestUtils.getPropertyValue( this.kafkaListener, "messageListenerContainer", KafkaMessageListenerContainer.class); assertSame( this.connectionFactory, TestUtils.getPropertyValue(container, "kafkaTemplate.connectionFactory")); assertSame(this.offsetManager, container.getOffsetManager()); assertSame(this.errorHandler, container.getErrorHandler()); assertSame(this.executor, container.getFetchTaskExecutor()); assertEquals(10, container.getConcurrency()); assertEquals(1000, container.getMaxFetch()); assertEquals(1024, container.getQueueSize()); assertEquals(5000, container.getStopTimeout()); assertArrayEquals( new String[] {"foo", "bar"}, TestUtils.getPropertyValue(container, "topics", String[].class)); assertOverrides(this.kafkaListener, false, false, false, true); assertOverrides(this.withMBFactoryOverrideAndId, true, true, false, false); assertOverrides(this.withMBFactoryOverrideAndTS, true, false, true, true); assertOverrides(this.withOverrideIdTS, false, true, true, true); final AtomicReference<Method> toMessage = new AtomicReference<Method>(); ReflectionUtils.doWithMethods( KafkaMessageDrivenChannelAdapter.class, new MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { method.setAccessible(true); toMessage.set(method); } }, new MethodFilter() { @Override public boolean matches(Method method) { return method.getName().equals("toMessage"); } }); Message<?> m = getAMessageFrom(this.kafkaListener, toMessage.get()); assertNull(m.getHeaders().getId()); assertNull(m.getHeaders().getTimestamp()); assertNull(m.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT)); assertRest(m); m = getAMessageFrom(this.withMBFactoryOverrideAndId, toMessage.get()); assertThat(m, Matchers.instanceOf(GenericMessage.class)); assertNotNull(m.getHeaders().getId()); assertNotNull(m.getHeaders().getTimestamp()); assertNotNull(m.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT)); assertRest(m); m = getAMessageFrom(this.withMBFactoryOverrideAndTS, toMessage.get()); assertThat(m, Matchers.instanceOf(GenericMessage.class)); assertNotNull(m.getHeaders().getId()); assertNotNull(m.getHeaders().getTimestamp()); assertNull(m.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT)); assertRest(m); m = getAMessageFrom(this.withOverrideIdTS, toMessage.get()); assertNotNull(m.getHeaders().getId()); assertNotNull(m.getHeaders().getTimestamp()); assertNull(m.getHeaders().get(KafkaHeaders.ACKNOWLEDGMENT)); assertRest(m); }
private Map<String, Map<Class<?>, HandlerMethod>> findHandlerMethodsForTarget( final Object targetObject, final Class<? extends Annotation> annotationType, final String methodName, final boolean requiresReply) { Map<String, Map<Class<?>, HandlerMethod>> handlerMethods = new HashMap<String, Map<Class<?>, HandlerMethod>>(); final Map<Class<?>, HandlerMethod> candidateMethods = new HashMap<Class<?>, HandlerMethod>(); final Map<Class<?>, HandlerMethod> candidateMessageMethods = new HashMap<Class<?>, HandlerMethod>(); final Map<Class<?>, HandlerMethod> fallbackMethods = new HashMap<Class<?>, HandlerMethod>(); final Map<Class<?>, HandlerMethod> fallbackMessageMethods = new HashMap<Class<?>, HandlerMethod>(); final AtomicReference<Class<?>> ambiguousFallbackType = new AtomicReference<Class<?>>(); final AtomicReference<Class<?>> ambiguousFallbackMessageGenericType = new AtomicReference<Class<?>>(); final Class<?> targetClass = this.getTargetClass(targetObject); MethodFilter methodFilter = new UniqueMethodFilter(targetClass); ReflectionUtils.doWithMethods( targetClass, new MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { boolean matchesAnnotation = false; if (method.isBridge()) { return; } if (isMethodDefinedOnObjectClass(method)) { return; } if (method.getDeclaringClass().equals(Proxy.class)) { return; } if (!Modifier.isPublic(method.getModifiers())) { return; } if (requiresReply && void.class.equals(method.getReturnType())) { return; } if (methodName != null && !methodName.equals(method.getName())) { return; } if (annotationType != null && AnnotationUtils.findAnnotation(method, annotationType) != null) { matchesAnnotation = true; } HandlerMethod handlerMethod = null; try { handlerMethod = new HandlerMethod(method, canProcessMessageList); } catch (IneligibleMethodException e) { if (logger.isDebugEnabled()) { logger.debug( "Method [" + method + "] is not eligible for Message handling " + e.getMessage() + "."); } return; } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Method [" + method + "] is not eligible for Message handling.", e); } return; } Class<?> targetParameterType = handlerMethod.getTargetParameterType(); if (matchesAnnotation || annotationType == null) { if (handlerMethod.isMessageMethod()) { if (candidateMessageMethods.containsKey(targetParameterType)) { throw new IllegalArgumentException( "Found more than one method match for type " + "[Message<" + targetParameterType + ">]"); } candidateMessageMethods.put(targetParameterType, handlerMethod); } else { if (candidateMethods.containsKey(targetParameterType)) { String exceptionMessage = "Found more than one method match for "; if (Void.class.equals(targetParameterType)) { exceptionMessage += "empty parameter for 'payload'"; } else { exceptionMessage += "type [" + targetParameterType + "]"; } throw new IllegalArgumentException(exceptionMessage); } candidateMethods.put(targetParameterType, handlerMethod); } } else { if (handlerMethod.isMessageMethod()) { if (fallbackMessageMethods.containsKey(targetParameterType)) { // we need to check for duplicate type matches, // but only if we end up falling back // and we'll only keep track of the first one ambiguousFallbackMessageGenericType.compareAndSet(null, targetParameterType); } fallbackMessageMethods.put(targetParameterType, handlerMethod); } else { if (fallbackMethods.containsKey(targetParameterType)) { // we need to check for duplicate type matches, // but only if we end up falling back // and we'll only keep track of the first one ambiguousFallbackType.compareAndSet(null, targetParameterType); } fallbackMethods.put(targetParameterType, handlerMethod); } } } }, methodFilter); if (!candidateMethods.isEmpty() || !candidateMessageMethods.isEmpty()) { handlerMethods.put(CANDIDATE_METHODS, candidateMethods); handlerMethods.put(CANDIDATE_MESSAGE_METHODS, candidateMessageMethods); return handlerMethods; } if ((ambiguousFallbackType.get() != null || ambiguousFallbackMessageGenericType.get() != null) && ServiceActivator.class.equals(annotationType)) { /* * When there are ambiguous fallback methods, * a Service Activator can finally fallback to RequestReplyExchanger.exchange(m). * Ambiguous means > 1 method that takes the same payload type, or > 1 method * that takes a Message with the same generic type. */ List<Method> frameworkMethods = new ArrayList<Method>(); Class<?>[] allInterfaces = org.springframework.util.ClassUtils.getAllInterfacesForClass(targetClass); for (Class<?> iface : allInterfaces) { try { if ("org.springframework.integration.gateway.RequestReplyExchanger" .equals(iface.getName())) { frameworkMethods.add(targetClass.getMethod("exchange", Message.class)); if (logger.isDebugEnabled()) { logger.debug( targetObject.getClass() + ": Ambiguous fallback methods; using RequestReplyExchanger.exchange()"); } } } catch (Exception e) { // should never happen (but would fall through to errors below) } } if (frameworkMethods.size() == 1) { HandlerMethod handlerMethod = new HandlerMethod(frameworkMethods.get(0), canProcessMessageList); handlerMethods.put( CANDIDATE_METHODS, Collections.<Class<?>, HandlerMethod>singletonMap(Object.class, handlerMethod)); handlerMethods.put(CANDIDATE_MESSAGE_METHODS, candidateMessageMethods); return handlerMethods; } } try { Assert.state( !fallbackMethods.isEmpty() || !fallbackMessageMethods.isEmpty(), "Target object of type [" + this.targetObject.getClass() + "] has no eligible methods for handling Messages."); } catch (Exception e) { // TODO backward compatibility throw new IllegalArgumentException(e.getMessage()); } Assert.isNull( ambiguousFallbackType.get(), "Found ambiguous parameter type [" + ambiguousFallbackType + "] for method match: " + fallbackMethods.values()); Assert.isNull( ambiguousFallbackMessageGenericType.get(), "Found ambiguous parameter type [" + ambiguousFallbackMessageGenericType + "] for method match: " + fallbackMethods.values()); handlerMethods.put(CANDIDATE_METHODS, fallbackMethods); handlerMethods.put(CANDIDATE_MESSAGE_METHODS, fallbackMessageMethods); return handlerMethods; }
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { // first sift through and get all the methods // then get all the annotations // then build the metadata and register the metadata final Class<?> targetClass = AopUtils.getTargetClass(bean); final org.activiti.spring.annotations.ActivitiComponent component = targetClass.getAnnotation(org.activiti.spring.annotations.ActivitiComponent.class); ReflectionUtils.doWithMethods( targetClass, new ReflectionUtils.MethodCallback() { @SuppressWarnings("unchecked") public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { State state = AnnotationUtils.getAnnotation(method, State.class); String processName = component.processKey(); if (StringUtils.hasText(state.process())) { processName = state.process(); } String stateName = state.state(); if (!StringUtils.hasText(stateName)) { stateName = state.value(); } Assert.notNull(stateName, "You must provide a stateName!"); Map<Integer, String> vars = new HashMap<Integer, String>(); Annotation[][] paramAnnotationsArray = method.getParameterAnnotations(); int ctr = 0; int pvMapIndex = -1; int procIdIndex = -1; for (Annotation[] paramAnnotations : paramAnnotationsArray) { ctr += 1; for (Annotation pa : paramAnnotations) { if (pa instanceof ProcessVariable) { ProcessVariable pv = (ProcessVariable) pa; String pvName = pv.value(); vars.put(ctr, pvName); } else if (pa instanceof ProcessVariables) { pvMapIndex = ctr; } else if (pa instanceof ProcessId) { procIdIndex = ctr; } } } ActivitiStateHandlerRegistration registration = new ActivitiStateHandlerRegistration( vars, method, bean, stateName, beanName, pvMapIndex, procIdIndex, processName); registry.registerActivitiStateHandler(registration); } }, new ReflectionUtils.MethodFilter() { public boolean matches(Method method) { return null != AnnotationUtils.getAnnotation(method, State.class); } }); return bean; }
private void createChannels(Class<?> type) throws Exception { ReflectionUtils.doWithMethods( type, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Input input = AnnotationUtils.findAnnotation(method, Input.class); if (input != null) { String name = BindingBeanDefinitionRegistryUtils.getChannelName(input, method); Class<?> inputChannelType = method.getReturnType(); MessageChannel sharedChannel = locateSharedChannel(name); if (sharedChannel == null) { MessageChannel inputChannel = createMessageChannel(inputChannelType); inputs.put(name, new ChannelHolder(inputChannel, true)); } else { if (inputChannelType.isAssignableFrom(sharedChannel.getClass())) { inputs.put(name, new ChannelHolder(sharedChannel, false)); } else { // handle the special case where the shared channel is of a different nature // (i.e. pollable vs subscribable) than the target channel final MessageChannel inputChannel = createMessageChannel(inputChannelType); if (isPollable(sharedChannel.getClass())) { bridgePollableToSubscribableChannel(sharedChannel, inputChannel); } else { bridgeSubscribableToPollableChannel( (SubscribableChannel) sharedChannel, inputChannel); } inputs.put(name, new ChannelHolder(inputChannel, false)); } } } Output output = AnnotationUtils.findAnnotation(method, Output.class); if (output != null) { String name = BindingBeanDefinitionRegistryUtils.getChannelName(output, method); Class<?> messageChannelType = method.getReturnType(); MessageChannel sharedChannel = locateSharedChannel(name); if (sharedChannel == null) { MessageChannel outputChannel = createMessageChannel(messageChannelType); outputs.put(name, new ChannelHolder(outputChannel, true)); } else { if (messageChannelType.isAssignableFrom(sharedChannel.getClass())) { outputs.put(name, new ChannelHolder(sharedChannel, false)); } else { // handle the special case where the shared channel is of a different nature // (i.e. pollable vs subscribable) than the target channel final MessageChannel outputChannel = createMessageChannel(messageChannelType); if (isPollable(messageChannelType)) { bridgePollableToSubscribableChannel(outputChannel, sharedChannel); } else { bridgeSubscribableToPollableChannel( (SubscribableChannel) outputChannel, sharedChannel); } outputs.put(name, new ChannelHolder(outputChannel, false)); } } } } }); }