protected void processAmqpListener(RabbitListener rabbitListener, Method method, Object bean, String beanName) { Method methodToUse = checkProxy(method, bean); MethodRabbitListenerEndpoint endpoint = new MethodRabbitListenerEndpoint(); endpoint.setMethod(methodToUse); processListener(endpoint, rabbitListener, bean, methodToUse, beanName); }
@Bean(name = RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public RabbitListenerAnnotationBeanPostProcessor rabbitListenerAnnotationProcessor() { return new RabbitListenerAnnotationBeanPostProcessor(); }
private String[] registerBeansForDeclaration(RabbitListener rabbitListener) { List<String> queues = new ArrayList<String>(); if (this.beanFactory instanceof ConfigurableBeanFactory) { for (QueueBinding binding : rabbitListener.bindings()) { String queueName = declareQueue(binding.value()); queues.add(queueName); declareExchangeAndBinding(binding, queueName); } } return queues.toArray(new String[queues.size()]); }
@Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { Class<?> targetClass = AopUtils.getTargetClass(bean); final TypeMetadata metadata = this.typeCache.computeIfAbsent(targetClass, this::buildMetadata); for (ListenerMethod lm : metadata.listenerMethods) { for (RabbitListener rabbitListener : lm.annotations) { processAmqpListener(rabbitListener, lm.method, bean, beanName); } } if (metadata.handlerMethods.length > 0) { processMultiMethodListeners(metadata.classAnnotations, metadata.handlerMethods, bean, beanName); } return bean; }
endpoint.setBean(bean); endpoint.setMessageHandlerMethodFactory(this.messageHandlerMethodFactory); endpoint.setId(getEndpointId(rabbitListener)); endpoint.setQueueNames(resolveQueues(rabbitListener)); endpoint.setConcurrency(resolveExpressionAsStringOrInteger(rabbitListener.concurrency(), "concurrency")); endpoint.setBeanFactory(this.beanFactory); endpoint.setReturnExceptions(resolveExpressionAsBoolean(rabbitListener.returnExceptions())); Object errorHandler = resolveExpression(rabbitListener.errorHandler()); if (errorHandler instanceof RabbitListenerErrorHandler) { endpoint.setErrorHandler((RabbitListenerErrorHandler) errorHandler); Object resolvedGroup = resolveExpression(group); if (resolvedGroup instanceof String) { endpoint.setGroup((String) resolvedGroup); endpoint.setAutoStartup(resolveExpressionAsBoolean(autoStartup)); String priority = resolve(rabbitListener.priority()); if (StringUtils.hasText(priority)) { try { resolveAdmin(endpoint, rabbitListener, adminTarget); RabbitListenerContainerFactory<?> factory = resolveContainerFactory(rabbitListener, adminTarget, beanName);
private String[] resolveQueues(RabbitListener rabbitListener) { String[] queues = rabbitListener.queues(); QueueBinding[] bindings = rabbitListener.bindings(); org.springframework.amqp.rabbit.annotation.Queue[] queuesToDeclare = rabbitListener.queuesToDeclare(); List<String> result = new ArrayList<String>(); if (queues.length > 0) { for (int i = 0; i < queues.length; i++) { resolveAsString(resolveExpression(queues[i]), result); } } if (queuesToDeclare.length > 0) { if (queues.length > 0) { throw new BeanInitializationException( "@RabbitListener can have only one of 'queues', 'queuesToDeclare', or 'bindings'"); } for (int i = 0; i < queuesToDeclare.length; i++) { result.add(declareQueue(queuesToDeclare[i])); } } if (bindings.length > 0) { if (queues.length > 0 || queuesToDeclare.length > 0) { throw new BeanInitializationException( "@RabbitListener can have only one of 'queues', 'queuesToDeclare', or 'bindings'"); } return registerBeansForDeclaration(rabbitListener); } return result.toArray(new String[result.size()]); }
private Map<String, Object> resolveArguments(Argument[] arguments) { Map<String, Object> map = new HashMap<String, Object>(); for (Argument arg : arguments) { String key = resolveExpressionAsString(arg.name(), "@Argument.name"); if (StringUtils.hasText(key)) { Object value = resolveExpression(arg.value()); Object type = resolveExpression(arg.type()); Class<?> typeClass; String typeName; addToMap(map, key, value, typeClass, typeName);
@Bean public RabbitListenerAnnotationBeanPostProcessor postProcessor() { RabbitListenerAnnotationBeanPostProcessor postProcessor = new RabbitListenerAnnotationBeanPostProcessor(); postProcessor.setEndpointRegistry(rabbitListenerEndpointRegistry()); postProcessor.setContainerFactoryBeanName("testFactory"); return postProcessor; }
@Override protected void processListener(MethodRabbitListenerEndpoint endpoint, RabbitListener rabbitListener, Object bean, Object adminTarget, String beanName) { Object proxy = bean; String id = rabbitListener.id(); if (StringUtils.hasText(id)) { if (this.attributes.getBoolean("spy")) { proxy = Mockito.spy(proxy); this.listeners.put(id, proxy); } if (this.attributes.getBoolean("capture")) { try { ProxyFactoryBean pfb = new ProxyFactoryBean(); pfb.setProxyTargetClass(true); pfb.setTarget(proxy); CaptureAdvice advice = new CaptureAdvice(); pfb.addAdvice(advice); proxy = pfb.getObject(); this.listenerCapture.put(id, advice); } catch (Exception e) { throw new AmqpException("Failed to proxy @RabbitListener with id: " + id, e); } } } else { logger.info("The test harness can only proxy @RabbitListeners with an 'id' attribute"); } super.processListener(endpoint, rabbitListener, proxy, adminTarget, beanName); }
private TypeMetadata buildMetadata(Class<?> targetClass) { Collection<RabbitListener> classLevelListeners = findListenerAnnotations(targetClass); final boolean hasClassLevelListeners = classLevelListeners.size() > 0; final List<ListenerMethod> methods = new ArrayList<>(); final List<Method> multiMethods = new ArrayList<>(); ReflectionUtils.doWithMethods(targetClass, method -> { Collection<RabbitListener> listenerAnnotations = findListenerAnnotations(method); if (listenerAnnotations.size() > 0) { methods.add(new ListenerMethod(method, listenerAnnotations.toArray(new RabbitListener[listenerAnnotations.size()]))); } if (hasClassLevelListeners) { RabbitHandler rabbitHandler = AnnotationUtils.findAnnotation(method, RabbitHandler.class); if (rabbitHandler != null) { multiMethods.add(method); } } }, ReflectionUtils.USER_DECLARED_METHODS); if (methods.isEmpty() && multiMethods.isEmpty()) { return TypeMetadata.EMPTY; } return new TypeMetadata( methods.toArray(new ListenerMethod[methods.size()]), multiMethods.toArray(new Method[multiMethods.size()]), classLevelListeners.toArray(new RabbitListener[classLevelListeners.size()])); }
endpoint.setBean(bean); endpoint.setMessageHandlerMethodFactory(this.messageHandlerMethodFactory); endpoint.setId(getEndpointId(rabbitListener)); endpoint.setQueueNames(resolveQueues(rabbitListener)); endpoint.setConcurrency(resolveExpressionAsStringOrInteger(rabbitListener.concurrency(), "concurrency")); endpoint.setBeanFactory(this.beanFactory); endpoint.setReturnExceptions(resolveExpressionAsBoolean(rabbitListener.returnExceptions())); Object errorHandler = resolveExpression(rabbitListener.errorHandler()); if (errorHandler instanceof RabbitListenerErrorHandler) { endpoint.setErrorHandler((RabbitListenerErrorHandler) errorHandler); Object resolvedGroup = resolveExpression(group); if (resolvedGroup instanceof String) { endpoint.setGroup((String) resolvedGroup); endpoint.setAutoStartup(resolveExpressionAsBoolean(autoStartup)); String priority = resolve(rabbitListener.priority()); if (StringUtils.hasText(priority)) { try { resolveAdmin(endpoint, rabbitListener, adminTarget); RabbitListenerContainerFactory<?> factory = resolveContainerFactory(rabbitListener, adminTarget, beanName);
private String[] resolveQueues(RabbitListener rabbitListener) { String[] queues = rabbitListener.queues(); QueueBinding[] bindings = rabbitListener.bindings(); org.springframework.amqp.rabbit.annotation.Queue[] queuesToDeclare = rabbitListener.queuesToDeclare(); List<String> result = new ArrayList<String>(); if (queues.length > 0) { for (int i = 0; i < queues.length; i++) { resolveAsString(resolveExpression(queues[i]), result); } } if (queuesToDeclare.length > 0) { if (queues.length > 0) { throw new BeanInitializationException( "@RabbitListener can have only one of 'queues', 'queuesToDeclare', or 'bindings'"); } for (int i = 0; i < queuesToDeclare.length; i++) { result.add(declareQueue(queuesToDeclare[i])); } } if (bindings.length > 0) { if (queues.length > 0 || queuesToDeclare.length > 0) { throw new BeanInitializationException( "@RabbitListener can have only one of 'queues', 'queuesToDeclare', or 'bindings'"); } return registerBeansForDeclaration(rabbitListener); } return result.toArray(new String[result.size()]); }
private Map<String, Object> resolveArguments(Argument[] arguments) { Map<String, Object> map = new HashMap<String, Object>(); for (Argument arg : arguments) { String key = resolveExpressionAsString(arg.name(), "@Argument.name"); if (StringUtils.hasText(key)) { Object value = resolveExpression(arg.value()); Object type = resolveExpression(arg.type()); Class<?> typeClass; String typeName; addToMap(map, key, value, typeClass, typeName);
@Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { Class<?> targetClass = AopUtils.getTargetClass(bean); final TypeMetadata metadata = this.typeCache.computeIfAbsent(targetClass, this::buildMetadata); for (ListenerMethod lm : metadata.listenerMethods) { for (RabbitListener rabbitListener : lm.annotations) { processAmqpListener(rabbitListener, lm.method, bean, beanName); } } if (metadata.handlerMethods.length > 0) { processMultiMethodListeners(metadata.classAnnotations, metadata.handlerMethods, bean, beanName); } return bean; }
@Override protected void processListener(MethodRabbitListenerEndpoint endpoint, RabbitListener rabbitListener, Object bean, Object adminTarget, String beanName) { Object proxy = bean; String id = rabbitListener.id(); if (StringUtils.hasText(id)) { if (this.attributes.getBoolean("spy")) { proxy = Mockito.spy(proxy); this.listeners.put(id, proxy); } if (this.attributes.getBoolean("capture")) { try { ProxyFactoryBean pfb = new ProxyFactoryBean(); pfb.setProxyTargetClass(true); pfb.setTarget(proxy); CaptureAdvice advice = new CaptureAdvice(); pfb.addAdvice(advice); proxy = pfb.getObject(); this.listenerCapture.put(id, advice); } catch (Exception e) { throw new AmqpException("Failed to proxy @RabbitListener with id: " + id, e); } } } else { logger.info("The test harness can only proxy @RabbitListeners with an 'id' attribute"); } super.processListener(endpoint, rabbitListener, proxy, adminTarget, beanName); }
private TypeMetadata buildMetadata(Class<?> targetClass) { Collection<RabbitListener> classLevelListeners = findListenerAnnotations(targetClass); final boolean hasClassLevelListeners = classLevelListeners.size() > 0; final List<ListenerMethod> methods = new ArrayList<>(); final List<Method> multiMethods = new ArrayList<>(); ReflectionUtils.doWithMethods(targetClass, method -> { Collection<RabbitListener> listenerAnnotations = findListenerAnnotations(method); if (listenerAnnotations.size() > 0) { methods.add(new ListenerMethod(method, listenerAnnotations.toArray(new RabbitListener[listenerAnnotations.size()]))); } if (hasClassLevelListeners) { RabbitHandler rabbitHandler = AnnotationUtils.findAnnotation(method, RabbitHandler.class); if (rabbitHandler != null) { multiMethods.add(method); } } }, ReflectionUtils.USER_DECLARED_METHODS); if (methods.isEmpty() && multiMethods.isEmpty()) { return TypeMetadata.EMPTY; } return new TypeMetadata( methods.toArray(new ListenerMethod[methods.size()]), multiMethods.toArray(new Method[multiMethods.size()]), classLevelListeners.toArray(new RabbitListener[classLevelListeners.size()])); }
protected void processAmqpListener(RabbitListener rabbitListener, Method method, Object bean, String beanName) { Method methodToUse = checkProxy(method, bean); MethodRabbitListenerEndpoint endpoint = new MethodRabbitListenerEndpoint(); endpoint.setMethod(methodToUse); processListener(endpoint, rabbitListener, bean, methodToUse, beanName); }
private String[] registerBeansForDeclaration(RabbitListener rabbitListener) { List<String> queues = new ArrayList<String>(); if (this.beanFactory instanceof ConfigurableBeanFactory) { for (QueueBinding binding : rabbitListener.bindings()) { String queueName = declareQueue(binding.value()); queues.add(queueName); declareExchangeAndBinding(binding, queueName); } } return queues.toArray(new String[queues.size()]); }
@Bean(name = RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public RabbitListenerAnnotationBeanPostProcessor rabbitListenerAnnotationProcessor() { return new RabbitListenerAnnotationBeanPostProcessor(); }
private void processMultiMethodListeners(RabbitListener[] classLevelListeners, Method[] multiMethods, Object bean, String beanName) { List<Method> checkedMethods = new ArrayList<Method>(); Method defaultMethod = null; for (Method method : multiMethods) { Method checked = checkProxy(method, bean); if (AnnotationUtils.findAnnotation(method, RabbitHandler.class).isDefault()) { // NOSONAR never null final Method toAssert = defaultMethod; Assert.state(toAssert == null, () -> "Only one @RabbitHandler can be marked 'isDefault', found: " + toAssert.toString() + " and " + method.toString()); defaultMethod = checked; } checkedMethods.add(checked); } for (RabbitListener classLevelListener : classLevelListeners) { MultiMethodRabbitListenerEndpoint endpoint = new MultiMethodRabbitListenerEndpoint(checkedMethods, defaultMethod, bean); processListener(endpoint, classLevelListener, bean, bean.getClass(), beanName); } }