@Test
  public void listenersInApplicationContextWithNestedChild() {
    StaticApplicationContext context = new StaticApplicationContext();
    RootBeanDefinition nestedChild = new RootBeanDefinition(StaticApplicationContext.class);
    nestedChild.getPropertyValues().add("parent", context);
    nestedChild.setInitMethodName("refresh");
    context.registerBeanDefinition("nestedChild", nestedChild);
    RootBeanDefinition listener1Def = new RootBeanDefinition(MyOrderedListener1.class);
    listener1Def.setDependsOn(new String[] {"nestedChild"});
    context.registerBeanDefinition("listener1", listener1Def);
    context.refresh();

    MyOrderedListener1 listener1 = context.getBean("listener1", MyOrderedListener1.class);
    MyEvent event1 = new MyEvent(context);
    context.publishEvent(event1);
    assertTrue(listener1.seenEvents.contains(event1));

    SimpleApplicationEventMulticaster multicaster =
        context.getBean(
            AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
            SimpleApplicationEventMulticaster.class);
    assertFalse(multicaster.getApplicationListeners().isEmpty());

    context.close();
    assertTrue(multicaster.getApplicationListeners().isEmpty());
  }
  @Test
  public void resolveChannelNameFromContext() {
    StaticApplicationContext context = new StaticApplicationContext();
    RootBeanDefinition routerBeanDefinition = new RootBeanDefinition(HeaderValueRouter.class);
    routerBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue("testHeaderName");
    routerBeanDefinition.getPropertyValues().addPropertyValue("resolutionRequired", "true");
    context.registerBeanDefinition("router", routerBeanDefinition);
    context.registerBeanDefinition("testChannel", new RootBeanDefinition(QueueChannel.class));
    context.registerBeanDefinition("newChannel", new RootBeanDefinition(QueueChannel.class));
    context.refresh();
    MessageHandler handler = (MessageHandler) context.getBean("router");
    Message<?> message =
        MessageBuilder.withPayload("test").setHeader("testHeaderName", "testChannel").build();
    handler.handleMessage(message);
    QueueChannel channel = (QueueChannel) context.getBean("testChannel");
    Message<?> result = channel.receive(1000);
    assertNotNull(result);
    assertSame(message, result);

    // validate dynamics
    HeaderValueRouter router = (HeaderValueRouter) context.getBean("router");
    router.setChannelMapping("testChannel", "newChannel");
    router.handleMessage(message);
    QueueChannel newChannel = (QueueChannel) context.getBean("newChannel");
    result = newChannel.receive(10);
    assertNotNull(result);

    router.removeChannelMapping("testChannel");
    router.handleMessage(message);
    result = channel.receive(1000);
    assertNotNull(result);
    assertSame(message, result);
    context.close();
  }
 @Test
 public void dynamicChannelCache() {
   StaticApplicationContext context = new StaticApplicationContext();
   RootBeanDefinition routerBeanDefinition = new RootBeanDefinition(HeaderValueRouter.class);
   routerBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue("testHeaderName");
   routerBeanDefinition.getPropertyValues().addPropertyValue("resolutionRequired", "true");
   routerBeanDefinition.getPropertyValues().addPropertyValue("dynamicChannelLimit", "2");
   context.registerBeanDefinition("router", routerBeanDefinition);
   context.registerBeanDefinition("channel1", new RootBeanDefinition(QueueChannel.class));
   context.registerBeanDefinition("channel2", new RootBeanDefinition(QueueChannel.class));
   context.registerBeanDefinition("channel3", new RootBeanDefinition(QueueChannel.class));
   context.refresh();
   MessageHandler handler = (MessageHandler) context.getBean("router");
   String channels = "channel1, channel2, channel1, channel3";
   Message<?> message =
       MessageBuilder.withPayload("test").setHeader("testHeaderName", channels).build();
   handler.handleMessage(message);
   QueueChannel channel1 = (QueueChannel) context.getBean("channel1");
   QueueChannel channel2 = (QueueChannel) context.getBean("channel2");
   QueueChannel channel3 = (QueueChannel) context.getBean("channel3");
   assertThat(channel1.getQueueSize(), equalTo(2));
   assertThat(channel2.getQueueSize(), equalTo(1));
   assertThat(channel3.getQueueSize(), equalTo(1));
   assertThat(
       context.getBean(HeaderValueRouter.class).getDynamicChannelNames(),
       contains("channel1", "channel3"));
   context.close();
 }
 @Test
 public void resolveMultipleChannelsWithCommaDelimitedString() {
   StaticApplicationContext context = new StaticApplicationContext();
   RootBeanDefinition routerBeanDefinition = new RootBeanDefinition(HeaderValueRouter.class);
   routerBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue("testHeaderName");
   routerBeanDefinition.getPropertyValues().addPropertyValue("resolutionRequired", "true");
   context.registerBeanDefinition("router", routerBeanDefinition);
   context.registerBeanDefinition("channel1", new RootBeanDefinition(QueueChannel.class));
   context.registerBeanDefinition("channel2", new RootBeanDefinition(QueueChannel.class));
   context.refresh();
   MessageHandler handler = (MessageHandler) context.getBean("router");
   String channels = "channel1, channel2";
   Message<?> message =
       MessageBuilder.withPayload("test").setHeader("testHeaderName", channels).build();
   handler.handleMessage(message);
   QueueChannel channel1 = (QueueChannel) context.getBean("channel1");
   QueueChannel channel2 = (QueueChannel) context.getBean("channel2");
   Message<?> result1 = channel1.receive(1000);
   Message<?> result2 = channel2.receive(1000);
   assertNotNull(result1);
   assertNotNull(result2);
   assertSame(message, result1);
   assertSame(message, result2);
   context.close();
 }
 @Test
 @SuppressWarnings({"unchecked", "rawtypes"})
 public void resolveChannelNameFromMapAndCustomeResolver() {
   final StaticApplicationContext context = new StaticApplicationContext();
   ManagedMap channelMappings = new ManagedMap();
   channelMappings.put("testKey", "testChannel");
   RootBeanDefinition routerBeanDefinition = new RootBeanDefinition(HeaderValueRouter.class);
   routerBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue("testHeaderName");
   routerBeanDefinition.getPropertyValues().addPropertyValue("resolutionRequired", "true");
   routerBeanDefinition.getPropertyValues().addPropertyValue("channelMappings", channelMappings);
   routerBeanDefinition.getPropertyValues().addPropertyValue("beanFactory", context);
   routerBeanDefinition
       .getPropertyValues()
       .addPropertyValue(
           "channelResolver",
           (DestinationResolver<MessageChannel>)
               channelName -> context.getBean("anotherChannel", MessageChannel.class));
   context.registerBeanDefinition("router", routerBeanDefinition);
   context.registerBeanDefinition("testChannel", new RootBeanDefinition(QueueChannel.class));
   context.registerBeanDefinition("anotherChannel", new RootBeanDefinition(QueueChannel.class));
   context.refresh();
   MessageHandler handler = (MessageHandler) context.getBean("router");
   Message<?> message =
       MessageBuilder.withPayload("test").setHeader("testHeaderName", "testKey").build();
   handler.handleMessage(message);
   QueueChannel channel = (QueueChannel) context.getBean("anotherChannel");
   Message<?> result = channel.receive(1000);
   assertNotNull(result);
   assertSame(message, result);
   context.close();
 }
  @Test
  public void innerBeanAsListener() {
    StaticApplicationContext context = new StaticApplicationContext();
    RootBeanDefinition listenerDef = new RootBeanDefinition(TestBean.class);
    listenerDef.getPropertyValues().add("friends", new RootBeanDefinition(BeanThatListens.class));
    context.registerBeanDefinition("listener", listenerDef);
    context.refresh();

    context.publishEvent(new MyEvent(this));
    context.publishEvent(new MyEvent(this));
    TestBean listener = context.getBean(TestBean.class);
    assertEquals(3, ((BeanThatListens) listener.getFriends().iterator().next()).getEventCount());

    context.close();
  }
  @Test
  public void listenerAndBroadcasterWithCircularReference() {
    StaticApplicationContext context = new StaticApplicationContext();
    context.registerBeanDefinition("broadcaster", new RootBeanDefinition(BeanThatBroadcasts.class));
    RootBeanDefinition listenerDef = new RootBeanDefinition(BeanThatListens.class);
    listenerDef
        .getConstructorArgumentValues()
        .addGenericArgumentValue(new RuntimeBeanReference("broadcaster"));
    context.registerBeanDefinition("listener", listenerDef);
    context.refresh();

    BeanThatBroadcasts broadcaster = context.getBean("broadcaster", BeanThatBroadcasts.class);
    context.publishEvent(new MyEvent(context));
    assertEquals("The event was not received by the listener", 2, broadcaster.receivedCount);

    context.close();
  }
 @Test
 public void channelAsHeaderValue() {
   StaticApplicationContext context = new StaticApplicationContext();
   RootBeanDefinition routerBeanDefinition = new RootBeanDefinition(HeaderValueRouter.class);
   routerBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue("testHeaderName");
   routerBeanDefinition.getPropertyValues().addPropertyValue("resolutionRequired", "true");
   context.registerBeanDefinition("router", routerBeanDefinition);
   context.refresh();
   MessageHandler handler = (MessageHandler) context.getBean("router");
   QueueChannel testChannel = new QueueChannel();
   Message<?> message =
       MessageBuilder.withPayload("test").setHeader("testHeaderName", testChannel).build();
   handler.handleMessage(message);
   Message<?> result = testChannel.receive(1000);
   assertNotNull(result);
   assertSame(message, result);
   context.close();
 }
  @Test
  public void listenersInApplicationContext() {
    StaticApplicationContext context = new StaticApplicationContext();
    context.registerBeanDefinition("listener1", new RootBeanDefinition(MyOrderedListener1.class));
    RootBeanDefinition listener2 = new RootBeanDefinition(MyOrderedListener2.class);
    listener2
        .getConstructorArgumentValues()
        .addGenericArgumentValue(new RuntimeBeanReference("listener1"));
    listener2.setLazyInit(true);
    context.registerBeanDefinition("listener2", listener2);
    context.refresh();
    assertFalse(context.getDefaultListableBeanFactory().containsSingleton("listener2"));

    MyOrderedListener1 listener1 = context.getBean("listener1", MyOrderedListener1.class);
    MyOtherEvent event1 = new MyOtherEvent(context);
    context.publishEvent(event1);
    assertFalse(context.getDefaultListableBeanFactory().containsSingleton("listener2"));
    MyEvent event2 = new MyEvent(context);
    context.publishEvent(event2);
    assertTrue(context.getDefaultListableBeanFactory().containsSingleton("listener2"));
    MyEvent event3 = new MyEvent(context);
    context.publishEvent(event3);
    MyOtherEvent event4 = new MyOtherEvent(context);
    context.publishEvent(event4);
    assertTrue(listener1.seenEvents.contains(event1));
    assertTrue(listener1.seenEvents.contains(event2));
    assertTrue(listener1.seenEvents.contains(event3));
    assertTrue(listener1.seenEvents.contains(event4));

    listener1.seenEvents.clear();
    context.publishEvent(event1);
    context.publishEvent(event2);
    context.publishEvent(event3);
    context.publishEvent(event4);
    assertTrue(listener1.seenEvents.contains(event1));
    assertTrue(listener1.seenEvents.contains(event2));
    assertTrue(listener1.seenEvents.contains(event3));
    assertTrue(listener1.seenEvents.contains(event4));

    context.close();
  }
  @Test
  public void nonSingletonListenerInApplicationContext() {
    StaticApplicationContext context = new StaticApplicationContext();
    RootBeanDefinition listener = new RootBeanDefinition(MyNonSingletonListener.class);
    listener.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
    context.registerBeanDefinition("listener", listener);
    context.refresh();

    MyEvent event1 = new MyEvent(context);
    context.publishEvent(event1);
    MyOtherEvent event2 = new MyOtherEvent(context);
    context.publishEvent(event2);
    MyEvent event3 = new MyEvent(context);
    context.publishEvent(event3);
    MyOtherEvent event4 = new MyOtherEvent(context);
    context.publishEvent(event4);
    assertTrue(MyNonSingletonListener.seenEvents.contains(event1));
    assertTrue(MyNonSingletonListener.seenEvents.contains(event2));
    assertTrue(MyNonSingletonListener.seenEvents.contains(event3));
    assertTrue(MyNonSingletonListener.seenEvents.contains(event4));
    MyNonSingletonListener.seenEvents.clear();

    context.close();
  }
  @Test
  public void testContextClose() throws Exception {
    MessageFactory messageFactory = MessageFactory.newInstance();
    int port = FreePortScanner.getFreePort();
    Server jettyServer = new Server(port);
    Context jettyContext = new Context(jettyServer, "/");
    jettyContext.addServlet(new ServletHolder(new EchoServlet()), "/");
    jettyServer.start();
    WebServiceConnection connection = null;
    try {

      StaticApplicationContext appContext = new StaticApplicationContext();
      appContext.registerSingleton("messageSender", CommonsHttpMessageSender.class);
      appContext.refresh();

      CommonsHttpMessageSender messageSender =
          appContext.getBean("messageSender", CommonsHttpMessageSender.class);
      connection = messageSender.createConnection(new URI("http://localhost:" + port));

      appContext.close();

      connection.send(new SaajSoapMessage(messageFactory.createMessage()));
      connection.receive(new SaajSoapMessageFactory(messageFactory));
    } finally {
      if (connection != null) {
        try {
          connection.close();
        } catch (IOException ex) {
          // ignore
        }
      }
      if (jettyServer.isRunning()) {
        jettyServer.stop();
      }
    }
  }