Announcement Announcement Module
Collapse
No announcement yet.
Annotation config with PublisherAnnotationBeanPostProcessor Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Annotation config with PublisherAnnotationBeanPostProcessor

    using Spring 3.2.0.M1 and integration 2.1.3....

    Trying to set up a publish-subscribe channel with annotations. Idea is to wrap a couple CRUD services with an AOP @Around and send of in a message the service name in the header plus the object effected by the CRUD call in the payload. Can't get the @Publisher annotation to fire off a message, looking like the post processor isn't been run.

    Testing with JUnit so the Test class has:
    Code:
    @ContextConfiguration(classes = { ApplicationConfig.class, DevelopmentConfig.class, ProductionConfig.class }, loader = AnnotationConfigSDNContextLoader.class)
    The ApplicationConfig has the AOP @Around bean wired:
    Code:
    @Bean 
    public ElementCRUD elementCRUD() {
    	return new ElementCRUD();
    }
    And in the DevelopmentConfig (got my profile set to "development") the actual Publication-Subcribe channel named "crudElementChannel":
    Code:
    @Bean
    public PublishSubscribeChannel crudElementChannel() {
    	return new PublishSubscribeChannel();
    }
    Inside the AOP ElementCrud class I have the @Around aspect method which gets called after the proceed call it calls the "send" method in the same class:
    Code:
    @Publisher(channel = "crudElementChannel")
    	public Element send(@Payload Element element, @Header String function) {
    		....
    		return element;
    	}
    Read that the PublisherAnnotationBeanPostProcessor has to be added to the BeanFactory so I extended the AnnotationConfigContextLoader as:
    Code:
        @Override
        protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    		PublisherAnnotationBeanPostProcessor integrationPABPP = new PublisherAnnotationBeanPostProcessor();
    		integrationPABPP.setBeanFactory(beanFactory);
    		integrationPABPP.afterPropertiesSet();
    		
    		beanFactory.addBeanPostProcessor(integrationPABPP);
    	}
    Got "Advisor is null" error if the afterPropertiesSet method wasn't run with the passed beanFactory.

  • #2
    Hello!

    Try to define PublisherAnnotationBeanPostProcessor as bean in the application context, to allow to work normal bean processing and lifecycle.

    Cheers,
    Artem

    Comment


    • #3
      Had tried that....

      Inside the test class instead of my extended loader if I use the AnnotationConfigContextLoader annotation loader and in the ApplicationConfig add:
      Code:
      @Bean
      public PublisherAnnotationBeanPostProcessor publisherAnnotationBeanPostProcessor() {
      	return new PublisherAnnotationBeanPostProcessor();
      }
      Nothing happens. If I do a misspell on the channel name to aggravate an error nothing happens. Get nothing from logging DEBUG on the integration classes either.

      Comment


      • #4
        Got the configuration wired up now but the send fails due to no handlers in the dispatch phase of the broadcasting.

        The integration needed an interface (didn't think that was necessary from the docs...) so I broke apart the ElementCRUD class which was partially an AOP aspect and a Publisher into the following:
        Code:
        @Aspect
        @Order(200)
        public class ElementCRUD {
        	@Autowired
        	PublishCRUD crudPublisher;
        
        	@Around("execution(* com.klistret.sdn.service.ElementService.update(com.klistret.sdn.ci.commons.Element))")
        	public Object capture(ProceedingJoinPoint pjp) throws Throwable {
        		....
        		crudPublisher.send(element, function);
        	}
        }
        Side note for those using AOP the order must be lower than the Spring TX manager otherwise errors throw by publishing destroy the JTA transaction. Not what I wanted, but just a side note to this post.

        The publishing gets done in:
        Code:
        public class PublishCRUDImpl implements PublishCRUD {
        
        	@Publisher(channel = "crudElementChannel")
        	public Element send(@Payload Element element, @Header String function) {
        		....
        	}
        where the interface PublishCRUD has no integration annotations what so ever. The PublishCRUD is wired up as a bean in the ApplicationConfig.

        Odd thing is now the I get a message delivery failed. Have no subscribers to the channel but thought that was ok? In the dispatch phase there are no handlers and the method returns false which issues a MessageDeliveryException. Wasn't getting this (as I remember) when using the Spring XML config.

        Comment


        • #5
          Tried adding a dummy service activator but it isn't added as a handler:
          Code:
          @MessageEndpoint
          public class SubscribeDefaultImpl implements SubscribeDefault {
          
          	@ServiceActivator(inputChannel = "crudElementChannel")
          	public void eat(Element element, @Header String function) {
          		if (function != null)
          			System.out.println("stuff");
          	}
          }
          And the SubscribeDefault is wired up as normal. Is there a post processor for subscribers? Haven't seen one.

          Comment


          • #6
            Hello

            You should register MessagingAnnotationPostProcessor

            Cheers,
            Artem

            Comment


            • #7
              Perfect. That picked up my message subscriber. Thanks. Right now when I am developing I don't have a "real" subscriber. Thought that a published message had no subscribers on a channel that the message could be trashed. Anyway to configure so? Could be situations where you have a channel that may or may not have subscribers but it should work either way when publishing.

              @Artem, didn't find any reference to the MessagingAnnotationPostProcessor call in the documentation.

              Comment


              • #8
                didn't find any reference to the MessagingAnnotationPostProcessor call in the documentation
                The note is here http://static.springsource.org/sprin...ml#annotations.
                However for more info you should read framework sources.
                For all custom tags there are some parsers and processors behind the scene. And they are registered in the Application context as regular beans. E.g. for <int:annotation-config/> there is a AnnotationConfigParser which registers beans for MessagingAnnotationPostProcessor and PublisherAnnotationBeanPostProcessor.
                Now about your task:
                Could be situations where you have a channel that may or may not have subscribers but it should work either way when publishing.
                Your channel must an instance of PollableChannel. This type of channels doesn't require subscribers, because they are queue-like.

                Hope that helps

                Comment


                • #9
                  Thanks for the explanation and will look into the PollabelChannel. Very pleased with the integration and ease of use once you get it going. Thanks for all the great work!

                  Comment

                  Working...
                  X