@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 testBeanNameAutoProxyCreator() {
    StaticApplicationContext sac = new StaticApplicationContext();
    sac.registerSingleton("testInterceptor", TestInterceptor.class);

    RootBeanDefinition proxyCreator = new RootBeanDefinition(BeanNameAutoProxyCreator.class);
    proxyCreator.getPropertyValues().add("interceptorNames", "testInterceptor");
    proxyCreator
        .getPropertyValues()
        .add("beanNames", "singletonToBeProxied,innerBean,singletonFactoryToBeProxied");
    sac.getDefaultListableBeanFactory()
        .registerBeanDefinition("beanNameAutoProxyCreator", proxyCreator);

    RootBeanDefinition bd =
        new RootBeanDefinition(TestBean.class, RootBeanDefinition.AUTOWIRE_BY_TYPE);
    RootBeanDefinition innerBean = new RootBeanDefinition(TestBean.class);
    bd.getPropertyValues().add("spouse", new BeanDefinitionHolder(innerBean, "innerBean"));
    sac.getDefaultListableBeanFactory().registerBeanDefinition("singletonToBeProxied", bd);

    sac.registerSingleton("singletonFactoryToBeProxied", DummyFactory.class);
    sac.registerSingleton("autowiredIndexedTestBean", IndexedTestBean.class);

    sac.refresh();

    MessageSource messageSource = (MessageSource) sac.getBean("messageSource");
    ITestBean singletonToBeProxied = (ITestBean) sac.getBean("singletonToBeProxied");
    assertFalse(Proxy.isProxyClass(messageSource.getClass()));
    assertTrue(Proxy.isProxyClass(singletonToBeProxied.getClass()));
    assertTrue(Proxy.isProxyClass(singletonToBeProxied.getSpouse().getClass()));

    // test whether autowiring succeeded with auto proxy creation
    assertEquals(
        sac.getBean("autowiredIndexedTestBean"), singletonToBeProxied.getNestedIndexedBean());

    TestInterceptor ti = (TestInterceptor) sac.getBean("testInterceptor");
    // already 2: getSpouse + getNestedIndexedBean calls above
    assertEquals(2, ti.nrOfInvocations);
    singletonToBeProxied.getName();
    singletonToBeProxied.getSpouse().getName();
    assertEquals(5, ti.nrOfInvocations);

    ITestBean tb = (ITestBean) sac.getBean("singletonFactoryToBeProxied");
    assertTrue(AopUtils.isJdkDynamicProxy(tb));
    assertEquals(5, ti.nrOfInvocations);
    tb.getAge();
    assertEquals(6, ti.nrOfInvocations);

    ITestBean tb2 = (ITestBean) sac.getBean("singletonFactoryToBeProxied");
    assertSame(tb, tb2);
    assertEquals(6, ti.nrOfInvocations);
    tb2.getAge();
    assertEquals(7, ti.nrOfInvocations);
  }
  @Test
  public void prototypeCreationReevaluatesExpressions() {
    GenericApplicationContext ac = new GenericApplicationContext();
    AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
    RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class);
    rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
    rbd.getPropertyValues().add("country", "#{systemProperties.country}");
    rbd.getPropertyValues().add("country2", new TypedStringValue("#{systemProperties.country}"));
    ac.registerBeanDefinition("test", rbd);
    ac.refresh();

    try {
      System.getProperties().put("name", "juergen1");
      System.getProperties().put("country", "UK1");
      PrototypeTestBean tb = (PrototypeTestBean) ac.getBean("test");
      assertEquals("juergen1", tb.getName());
      assertEquals("UK1", tb.getCountry());
      assertEquals("UK1", tb.getCountry2());

      System.getProperties().put("name", "juergen2");
      System.getProperties().put("country", "UK2");
      tb = (PrototypeTestBean) ac.getBean("test");
      assertEquals("juergen2", tb.getName());
      assertEquals("UK2", tb.getCountry());
      assertEquals("UK2", tb.getCountry2());
    } finally {
      System.getProperties().remove("name");
      System.getProperties().remove("country");
    }
  }
 protected void addResponseBodyAdvice(RootBeanDefinition beanDef) {
   if (jackson2Present) {
     beanDef
         .getPropertyValues()
         .add("responseBodyAdvice", new RootBeanDefinition(JsonViewResponseBodyAdvice.class));
   }
 }
  @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
 public void prototypeCreationIsFastEnough() {
   if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) {
     // Skip this test: Trace logging blows the time limit.
     return;
   }
   GenericApplicationContext ac = new GenericApplicationContext();
   RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
   rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
   rbd.getConstructorArgumentValues().addGenericArgumentValue("#{systemProperties.name}");
   rbd.getPropertyValues().add("country", "#{systemProperties.country}");
   ac.registerBeanDefinition("test", rbd);
   ac.refresh();
   StopWatch sw = new StopWatch();
   sw.start("prototype");
   System.getProperties().put("name", "juergen");
   System.getProperties().put("country", "UK");
   try {
     for (int i = 0; i < 100000; i++) {
       TestBean tb = (TestBean) ac.getBean("test");
       assertEquals("juergen", tb.getName());
       assertEquals("UK", tb.getCountry());
     }
     sw.stop();
   } finally {
     System.getProperties().remove("country");
     System.getProperties().remove("name");
   }
   assertTrue(
       "Prototype creation took too long: " + sw.getTotalTimeMillis(),
       sw.getTotalTimeMillis() < 6000);
 }
  @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());
  }
  private RootBeanDefinition parseAttributeSource(Element attrEle, ParserContext parserContext) {
    List<Element> methods = DomUtils.getChildElementsByTagName(attrEle, METHOD_ELEMENT);
    ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap =
        new ManagedMap<TypedStringValue, RuleBasedTransactionAttribute>(methods.size());
    transactionAttributeMap.setSource(parserContext.extractSource(attrEle));

    for (Element methodEle : methods) {
      String name = methodEle.getAttribute(METHOD_NAME_ATTRIBUTE);
      TypedStringValue nameHolder = new TypedStringValue(name);
      nameHolder.setSource(parserContext.extractSource(methodEle));

      RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute();
      String propagation = methodEle.getAttribute(PROPAGATION_ATTRIBUTE);
      String isolation = methodEle.getAttribute(ISOLATION_ATTRIBUTE);
      String timeout = methodEle.getAttribute(TIMEOUT_ATTRIBUTE);
      String readOnly = methodEle.getAttribute(READ_ONLY_ATTRIBUTE);
      if (StringUtils.hasText(propagation)) {
        attribute.setPropagationBehaviorName(
            RuleBasedTransactionAttribute.PREFIX_PROPAGATION + propagation);
      }
      if (StringUtils.hasText(isolation)) {
        attribute.setIsolationLevelName(RuleBasedTransactionAttribute.PREFIX_ISOLATION + isolation);
      }
      if (StringUtils.hasText(timeout)) {
        try {
          attribute.setTimeout(Integer.parseInt(timeout));
        } catch (NumberFormatException ex) {
          parserContext
              .getReaderContext()
              .error("Timeout must be an integer value: [" + timeout + "]", methodEle);
        }
      }
      if (StringUtils.hasText(readOnly)) {
        attribute.setReadOnly(Boolean.valueOf(methodEle.getAttribute(READ_ONLY_ATTRIBUTE)));
      }

      List<RollbackRuleAttribute> rollbackRules = new LinkedList<RollbackRuleAttribute>();
      if (methodEle.hasAttribute(ROLLBACK_FOR_ATTRIBUTE)) {
        String rollbackForValue = methodEle.getAttribute(ROLLBACK_FOR_ATTRIBUTE);
        addRollbackRuleAttributesTo(rollbackRules, rollbackForValue);
      }
      if (methodEle.hasAttribute(NO_ROLLBACK_FOR_ATTRIBUTE)) {
        String noRollbackForValue = methodEle.getAttribute(NO_ROLLBACK_FOR_ATTRIBUTE);
        addNoRollbackRuleAttributesTo(rollbackRules, noRollbackForValue);
      }
      attribute.setRollbackRules(rollbackRules);

      transactionAttributeMap.put(nameHolder, attribute);
    }

    RootBeanDefinition attributeSourceDefinition =
        new RootBeanDefinition(NameMatchTransactionAttributeSource.class);
    attributeSourceDefinition.setSource(parserContext.extractSource(attrEle));
    attributeSourceDefinition.getPropertyValues().add("nameMap", transactionAttributeMap);
    return attributeSourceDefinition;
  }
	@Test
	public void testExtendedResourceInjectionWithOverriding() {
		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
		CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
		bpp.setBeanFactory(bf);
		bf.addBeanPostProcessor(bpp);
		bf.registerResolvableDependency(BeanFactory.class, bf);

		PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
		Properties props = new Properties();
		props.setProperty("tb", "testBean3");
		ppc.setProperties(props);
		ppc.postProcessBeanFactory(bf);

		RootBeanDefinition annotatedBd = new RootBeanDefinition(ExtendedResourceInjectionBean.class);
		TestBean tb5 = new TestBean();
		annotatedBd.getPropertyValues().add("testBean2", tb5);
		bf.registerBeanDefinition("annotatedBean", annotatedBd);
		bf.registerBeanDefinition("annotatedBean2", new RootBeanDefinition(NamedResourceInjectionBean.class));
		TestBean tb = new TestBean();
		bf.registerSingleton("testBean", tb);
		TestBean tb2 = new TestBean();
		bf.registerSingleton("testBean2", tb2);
		TestBean tb3 = new TestBean();
		bf.registerSingleton("testBean3", tb3);
		TestBean tb4 = new TestBean();
		bf.registerSingleton("testBean4", tb4);
		NestedTestBean tb6 = new NestedTestBean();
		bf.registerSingleton("xy", tb6);

		ExtendedResourceInjectionBean bean = (ExtendedResourceInjectionBean) bf.getBean("annotatedBean");
		assertTrue(bean.initCalled);
		assertTrue(bean.init2Called);
		assertSame(tb, bean.getTestBean());
		assertSame(tb5, bean.getTestBean2());
		assertSame(tb4, bean.getTestBean3());
		assertSame(tb3, bean.getTestBean4());
		assertSame(tb6, bean.testBean5);
		assertSame(tb6, bean.testBean6);
		assertSame(bf, bean.beanFactory);

		try {
			bf.getBean("annotatedBean2");
		}
		catch (BeanCreationException ex) {
			assertTrue(ex.getRootCause() instanceof NoSuchBeanDefinitionException);
			NoSuchBeanDefinitionException innerEx = (NoSuchBeanDefinitionException) ex.getRootCause();
			assertEquals("testBean9", innerEx.getBeanName());
		}

		bf.destroySingletons();
		assertTrue(bean.destroyCalled);
		assertTrue(bean.destroy2Called);
	}
  private void configurePathMatchingProperties(
      RootBeanDefinition handlerMappingDef, Element element, ParserContext parserContext) {

    Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching");
    if (pathMatchingElement != null) {
      Object source = parserContext.extractSource(element);
      if (pathMatchingElement.hasAttribute("suffix-pattern")) {
        Boolean useSuffixPatternMatch =
            Boolean.valueOf(pathMatchingElement.getAttribute("suffix-pattern"));
        handlerMappingDef.getPropertyValues().add("useSuffixPatternMatch", useSuffixPatternMatch);
      }
      if (pathMatchingElement.hasAttribute("trailing-slash")) {
        Boolean useTrailingSlashMatch =
            Boolean.valueOf(pathMatchingElement.getAttribute("trailing-slash"));
        handlerMappingDef.getPropertyValues().add("useTrailingSlashMatch", useTrailingSlashMatch);
      }
      if (pathMatchingElement.hasAttribute("registered-suffixes-only")) {
        Boolean useRegisteredSuffixPatternMatch =
            Boolean.valueOf(pathMatchingElement.getAttribute("registered-suffixes-only"));
        handlerMappingDef
            .getPropertyValues()
            .add("useRegisteredSuffixPatternMatch", useRegisteredSuffixPatternMatch);
      }
      RuntimeBeanReference pathHelperRef = null;
      if (pathMatchingElement.hasAttribute("path-helper")) {
        pathHelperRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-helper"));
      }
      pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(pathHelperRef, parserContext, source);
      handlerMappingDef.getPropertyValues().add("urlPathHelper", pathHelperRef);

      RuntimeBeanReference pathMatcherRef = null;
      if (pathMatchingElement.hasAttribute("path-matcher")) {
        pathMatcherRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-matcher"));
      }
      pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(pathMatcherRef, parserContext, source);
      handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
    }
  }
  private void registerDomainBean(
      final Class<?> entityClass, BeanDefinitionRegistry targetRegistry, String messageSourceRef) {
    GenericBeanDefinition beanDef = new GenericBeanDefinition();
    beanDef.setBeanClass(entityClass);
    beanDef.setScope("prototype");

    RootBeanDefinition domainDef = new RootBeanDefinition(MethodInvokingFactoryBean.class);

    domainDef
        .getPropertyValues()
        .addPropertyValue(
            "targetObject", new RuntimeBeanReference(GrailsApplication.APPLICATION_ID));
    domainDef.getPropertyValues().addPropertyValue("targetMethod", "getArtefact");
    domainDef
        .getPropertyValues()
        .addPropertyValue(
            "arguments", Arrays.asList(DomainClassArtefactHandler.TYPE, entityClass.getName()));

    final String domainRef = entityClass.getName() + "Domain";
    if (StringUtils.hasText(messageSourceRef)) {
      GenericBeanDefinition validatorDef = new GenericBeanDefinition();
      validatorDef.setBeanClass(HibernateDomainClassValidator.class);
      validatorDef
          .getPropertyValues()
          .addPropertyValue("messageSource", new RuntimeBeanReference(messageSourceRef));
      validatorDef
          .getPropertyValues()
          .addPropertyValue("domainClass", new RuntimeBeanReference(domainRef));
      validatorDef
          .getPropertyValues()
          .addPropertyValue("sessionFactory", new RuntimeBeanReference("sessionFactory"));
      targetRegistry.registerBeanDefinition(entityClass.getName() + "Validator", validatorDef);
    }

    targetRegistry.registerBeanDefinition(entityClass.getName(), beanDef);
    targetRegistry.registerBeanDefinition(domainRef, domainDef);
  }
  @Test
  public void testBeanNameAutoProxyCreatorWithFactoryBeanProxy() {
    StaticApplicationContext sac = new StaticApplicationContext();
    sac.registerSingleton("testInterceptor", TestInterceptor.class);

    RootBeanDefinition proxyCreator = new RootBeanDefinition(BeanNameAutoProxyCreator.class);
    proxyCreator.getPropertyValues().add("interceptorNames", "testInterceptor");
    proxyCreator
        .getPropertyValues()
        .add("beanNames", "singletonToBeProxied,&singletonFactoryToBeProxied");
    sac.getDefaultListableBeanFactory()
        .registerBeanDefinition("beanNameAutoProxyCreator", proxyCreator);

    RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
    sac.getDefaultListableBeanFactory().registerBeanDefinition("singletonToBeProxied", bd);

    sac.registerSingleton("singletonFactoryToBeProxied", DummyFactory.class);

    sac.refresh();

    ITestBean singletonToBeProxied = (ITestBean) sac.getBean("singletonToBeProxied");
    assertTrue(Proxy.isProxyClass(singletonToBeProxied.getClass()));

    TestInterceptor ti = (TestInterceptor) sac.getBean("testInterceptor");
    int initialNr = ti.nrOfInvocations;
    singletonToBeProxied.getName();
    assertEquals(initialNr + 1, ti.nrOfInvocations);

    FactoryBean<?> factory = (FactoryBean<?>) sac.getBean("&singletonFactoryToBeProxied");
    assertTrue(Proxy.isProxyClass(factory.getClass()));
    TestBean tb = (TestBean) sac.getBean("singletonFactoryToBeProxied");
    assertFalse(AopUtils.isAopProxy(tb));
    assertEquals(initialNr + 3, ti.nrOfInvocations);
    tb.getAge();
    assertEquals(initialNr + 3, ti.nrOfInvocations);
  }
  @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 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();
 }
  private RuntimeBeanReference getContentNegotiationManager(
      Element element, Object source, ParserContext parserContext) {

    RuntimeBeanReference beanRef;
    if (element.hasAttribute("content-negotiation-manager")) {
      String name = element.getAttribute("content-negotiation-manager");
      beanRef = new RuntimeBeanReference(name);
    } else {
      RootBeanDefinition factoryBeanDef =
          new RootBeanDefinition(ContentNegotiationManagerFactoryBean.class);
      factoryBeanDef.setSource(source);
      factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes());

      String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
      parserContext.getReaderContext().getRegistry().registerBeanDefinition(name, factoryBeanDef);
      parserContext.registerComponent(new BeanComponentDefinition(factoryBeanDef, name));
      beanRef = new RuntimeBeanReference(name);
    }
    return beanRef;
  }
  protected BeanDefinition parseContainer(
      Element listenerEle, Element containerEle, ParserContext parserContext) {
    RootBeanDefinition containerDef = new RootBeanDefinition();
    containerDef.setSource(parserContext.extractSource(containerEle));

    parseListenerConfiguration(listenerEle, parserContext, containerDef);
    parseContainerConfiguration(containerEle, parserContext, containerDef);

    String containerType = containerEle.getAttribute(CONTAINER_TYPE_ATTRIBUTE);
    String containerClass = containerEle.getAttribute(CONTAINER_CLASS_ATTRIBUTE);
    if (!"".equals(containerClass)) {
      containerDef.setBeanClassName(containerClass);
    } else if ("".equals(containerType) || containerType.startsWith("default")) {
      containerDef.setBeanClassName(
          "org.springframework.jms.listener.DefaultMessageListenerContainer");
    } else if (containerType.startsWith("simple")) {
      containerDef.setBeanClassName(
          "org.springframework.jms.listener.SimpleMessageListenerContainer");
    } else {
      parserContext
          .getReaderContext()
          .error(
              "Invalid 'container-type' attribute: only \"default\" and \"simple\" supported.",
              containerEle);
    }

    String connectionFactoryBeanName = "connectionFactory";
    if (containerEle.hasAttribute(CONNECTION_FACTORY_ATTRIBUTE)) {
      connectionFactoryBeanName = containerEle.getAttribute(CONNECTION_FACTORY_ATTRIBUTE);
      if (!StringUtils.hasText(connectionFactoryBeanName)) {
        parserContext
            .getReaderContext()
            .error(
                "Listener container 'connection-factory' attribute contains empty value.",
                containerEle);
      }
    }
    if (StringUtils.hasText(connectionFactoryBeanName)) {
      containerDef
          .getPropertyValues()
          .add("connectionFactory", new RuntimeBeanReference(connectionFactoryBeanName));
    }

    String taskExecutorBeanName = containerEle.getAttribute(TASK_EXECUTOR_ATTRIBUTE);
    if (StringUtils.hasText(taskExecutorBeanName)) {
      containerDef
          .getPropertyValues()
          .add("taskExecutor", new RuntimeBeanReference(taskExecutorBeanName));
    }

    String errorHandlerBeanName = containerEle.getAttribute(ERROR_HANDLER_ATTRIBUTE);
    if (StringUtils.hasText(errorHandlerBeanName)) {
      containerDef
          .getPropertyValues()
          .add("errorHandler", new RuntimeBeanReference(errorHandlerBeanName));
    }

    String destinationResolverBeanName = containerEle.getAttribute(DESTINATION_RESOLVER_ATTRIBUTE);
    if (StringUtils.hasText(destinationResolverBeanName)) {
      containerDef
          .getPropertyValues()
          .add("destinationResolver", new RuntimeBeanReference(destinationResolverBeanName));
    }

    String cache = containerEle.getAttribute(CACHE_ATTRIBUTE);
    if (StringUtils.hasText(cache)) {
      if (containerType.startsWith("simple")) {
        if (!("auto".equals(cache) || "consumer".equals(cache))) {
          parserContext
              .getReaderContext()
              .warning(
                  "'cache' attribute not actively supported for listener container of type \"simple\". "
                      + "Effective runtime behavior will be equivalent to \"consumer\" / \"auto\".",
                  containerEle);
        }
      } else {
        containerDef.getPropertyValues().add("cacheLevelName", "CACHE_" + cache.toUpperCase());
      }
    }

    Integer acknowledgeMode = parseAcknowledgeMode(containerEle, parserContext);
    if (acknowledgeMode != null) {
      if (acknowledgeMode == Session.SESSION_TRANSACTED) {
        containerDef.getPropertyValues().add("sessionTransacted", Boolean.TRUE);
      } else {
        containerDef.getPropertyValues().add("sessionAcknowledgeMode", acknowledgeMode);
      }
    }

    String transactionManagerBeanName = containerEle.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE);
    if (StringUtils.hasText(transactionManagerBeanName)) {
      if (containerType.startsWith("simple")) {
        parserContext
            .getReaderContext()
            .error(
                "'transaction-manager' attribute not supported for listener container of type \"simple\".",
                containerEle);
      } else {
        containerDef
            .getPropertyValues()
            .add("transactionManager", new RuntimeBeanReference(transactionManagerBeanName));
      }
    }

    String concurrency = containerEle.getAttribute(CONCURRENCY_ATTRIBUTE);
    if (StringUtils.hasText(concurrency)) {
      containerDef.getPropertyValues().add("concurrency", concurrency);
    }

    String prefetch = containerEle.getAttribute(PREFETCH_ATTRIBUTE);
    if (StringUtils.hasText(prefetch)) {
      if (containerType.startsWith("default")) {
        containerDef.getPropertyValues().add("maxMessagesPerTask", new Integer(prefetch));
      }
    }

    String receiveTimeout = containerEle.getAttribute(RECEIVE_TIMEOUT_ATTRIBUTE);
    if (StringUtils.hasText(receiveTimeout)) {
      if (containerType.startsWith("default")) {
        containerDef.getPropertyValues().add("receiveTimeout", new Integer(receiveTimeout));
      }
    }

    String phase = containerEle.getAttribute(PHASE_ATTRIBUTE);
    if (StringUtils.hasText(phase)) {
      containerDef.getPropertyValues().add("phase", phase);
    }

    return containerDef;
  }
  private ManagedList<?> getMessageConverters(
      Element element, Object source, ParserContext parserContext) {
    Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
    ManagedList<? super Object> messageConverters = new ManagedList<Object>();
    if (convertersElement != null) {
      messageConverters.setSource(source);
      for (Element beanElement :
          DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {
        Object object = parserContext.getDelegate().parsePropertySubElement(beanElement, null);
        messageConverters.add(object);
      }
    }

    if (convertersElement == null
        || Boolean.valueOf(convertersElement.getAttribute("register-defaults"))) {
      messageConverters.setSource(source);
      messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));

      RootBeanDefinition stringConverterDef =
          createConverterDefinition(StringHttpMessageConverter.class, source);
      stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
      messageConverters.add(stringConverterDef);

      messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
      messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
      messageConverters.add(
          createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));

      if (romePresent) {
        messageConverters.add(
            createConverterDefinition(AtomFeedHttpMessageConverter.class, source));
        messageConverters.add(
            createConverterDefinition(RssChannelHttpMessageConverter.class, source));
      }

      if (jackson2XmlPresent) {
        RootBeanDefinition jacksonConverterDef =
            createConverterDefinition(MappingJackson2XmlHttpMessageConverter.class, source);
        GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
        jacksonFactoryDef.getPropertyValues().add("createXmlMapper", true);
        jacksonConverterDef
            .getConstructorArgumentValues()
            .addIndexedArgumentValue(0, jacksonFactoryDef);
        messageConverters.add(jacksonConverterDef);
      } else if (jaxb2Present) {
        messageConverters.add(
            createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
      }

      if (jackson2Present) {
        RootBeanDefinition jacksonConverterDef =
            createConverterDefinition(MappingJackson2HttpMessageConverter.class, source);
        GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
        jacksonConverterDef
            .getConstructorArgumentValues()
            .addIndexedArgumentValue(0, jacksonFactoryDef);
        messageConverters.add(jacksonConverterDef);
      } else if (gsonPresent) {
        messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source));
      }
    }
    return messageConverters;
  }
  @Override
  public BeanDefinition parse(Element element, ParserContext parserContext) {
    Object source = parserContext.extractSource(element);
    XmlReaderContext readerContext = parserContext.getReaderContext();

    CompositeComponentDefinition compDefinition =
        new CompositeComponentDefinition(element.getTagName(), source);
    parserContext.pushContainingComponent(compDefinition);

    RuntimeBeanReference contentNegotiationManager =
        getContentNegotiationManager(element, source, parserContext);

    RootBeanDefinition handlerMappingDef =
        new RootBeanDefinition(RequestMappingHandlerMapping.class);
    handlerMappingDef.setSource(source);
    handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    handlerMappingDef.getPropertyValues().add("order", 0);
    handlerMappingDef
        .getPropertyValues()
        .add("contentNegotiationManager", contentNegotiationManager);

    if (element.hasAttribute("enable-matrix-variables")) {
      Boolean enableMatrixVariables =
          Boolean.valueOf(element.getAttribute("enable-matrix-variables"));
      handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
    } else if (element.hasAttribute("enableMatrixVariables")) {
      Boolean enableMatrixVariables =
          Boolean.valueOf(element.getAttribute("enableMatrixVariables"));
      handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
    }

    configurePathMatchingProperties(handlerMappingDef, element, parserContext);
    readerContext
        .getRegistry()
        .registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);

    RuntimeBeanReference corsConfigurationsRef =
        MvcNamespaceUtils.registerCorsConfigurations(null, parserContext, source);
    handlerMappingDef.getPropertyValues().add("corsConfigurations", corsConfigurationsRef);

    RuntimeBeanReference conversionService = getConversionService(element, source, parserContext);
    RuntimeBeanReference validator = getValidator(element, source, parserContext);
    RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element);

    RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
    bindingDef.setSource(source);
    bindingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    bindingDef.getPropertyValues().add("conversionService", conversionService);
    bindingDef.getPropertyValues().add("validator", validator);
    bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);

    ManagedList<?> messageConverters = getMessageConverters(element, source, parserContext);
    ManagedList<?> argumentResolvers = getArgumentResolvers(element, parserContext);
    ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, parserContext);
    String asyncTimeout = getAsyncTimeout(element);
    RuntimeBeanReference asyncExecutor = getAsyncExecutor(element);
    ManagedList<?> callableInterceptors = getCallableInterceptors(element, source, parserContext);
    ManagedList<?> deferredResultInterceptors =
        getDeferredResultInterceptors(element, source, parserContext);

    RootBeanDefinition handlerAdapterDef =
        new RootBeanDefinition(RequestMappingHandlerAdapter.class);
    handlerAdapterDef.setSource(source);
    handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    handlerAdapterDef
        .getPropertyValues()
        .add("contentNegotiationManager", contentNegotiationManager);
    handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
    handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
    addRequestBodyAdvice(handlerAdapterDef);
    addResponseBodyAdvice(handlerAdapterDef);

    if (element.hasAttribute("ignore-default-model-on-redirect")) {
      Boolean ignoreDefaultModel =
          Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect"));
      handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel);
    } else if (element.hasAttribute("ignoreDefaultModelOnRedirect")) {
      // "ignoreDefaultModelOnRedirect" spelling is deprecated
      Boolean ignoreDefaultModel =
          Boolean.valueOf(element.getAttribute("ignoreDefaultModelOnRedirect"));
      handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel);
    }

    if (argumentResolvers != null) {
      handlerAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
    }
    if (returnValueHandlers != null) {
      handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
    }
    if (asyncTimeout != null) {
      handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout", asyncTimeout);
    }
    if (asyncExecutor != null) {
      handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor);
    }

    handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors);
    handlerAdapterDef
        .getPropertyValues()
        .add("deferredResultInterceptors", deferredResultInterceptors);
    readerContext
        .getRegistry()
        .registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);

    String uriCompContribName = MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME;
    RootBeanDefinition uriCompContribDef =
        new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class);
    uriCompContribDef.setSource(source);
    uriCompContribDef.getPropertyValues().addPropertyValue("handlerAdapter", handlerAdapterDef);
    uriCompContribDef.getPropertyValues().addPropertyValue("conversionService", conversionService);
    readerContext.getRegistry().registerBeanDefinition(uriCompContribName, uriCompContribDef);

    RootBeanDefinition csInterceptorDef =
        new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
    csInterceptorDef.setSource(source);
    csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
    RootBeanDefinition mappedCsInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
    mappedCsInterceptorDef.setSource(source);
    mappedCsInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null);
    mappedCsInterceptorDef
        .getConstructorArgumentValues()
        .addIndexedArgumentValue(1, csInterceptorDef);
    String mappedInterceptorName = readerContext.registerWithGeneratedName(mappedCsInterceptorDef);

    RootBeanDefinition exceptionHandlerExceptionResolver =
        new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
    exceptionHandlerExceptionResolver.setSource(source);
    exceptionHandlerExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    exceptionHandlerExceptionResolver
        .getPropertyValues()
        .add("contentNegotiationManager", contentNegotiationManager);
    exceptionHandlerExceptionResolver
        .getPropertyValues()
        .add("messageConverters", messageConverters);
    exceptionHandlerExceptionResolver.getPropertyValues().add("order", 0);
    addResponseBodyAdvice(exceptionHandlerExceptionResolver);

    String methodExceptionResolverName =
        readerContext.registerWithGeneratedName(exceptionHandlerExceptionResolver);

    RootBeanDefinition responseStatusExceptionResolver =
        new RootBeanDefinition(ResponseStatusExceptionResolver.class);
    responseStatusExceptionResolver.setSource(source);
    responseStatusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    responseStatusExceptionResolver.getPropertyValues().add("order", 1);
    String responseStatusExceptionResolverName =
        readerContext.registerWithGeneratedName(responseStatusExceptionResolver);

    RootBeanDefinition defaultExceptionResolver =
        new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
    defaultExceptionResolver.setSource(source);
    defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    defaultExceptionResolver.getPropertyValues().add("order", 2);
    String defaultExceptionResolverName =
        readerContext.registerWithGeneratedName(defaultExceptionResolver);

    parserContext.registerComponent(
        new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
    parserContext.registerComponent(
        new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
    parserContext.registerComponent(
        new BeanComponentDefinition(uriCompContribDef, uriCompContribName));
    parserContext.registerComponent(
        new BeanComponentDefinition(
            exceptionHandlerExceptionResolver, methodExceptionResolverName));
    parserContext.registerComponent(
        new BeanComponentDefinition(
            responseStatusExceptionResolver, responseStatusExceptionResolverName));
    parserContext.registerComponent(
        new BeanComponentDefinition(defaultExceptionResolver, defaultExceptionResolverName));
    parserContext.registerComponent(
        new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName));

    // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off"
    MvcNamespaceUtils.registerDefaultComponents(parserContext, source);

    parserContext.popAndRegisterContainingComponent();

    return null;
  }
  public BeanDefinition parse(Element elt, ParserContext pc) {
    String loginUrl = null;
    String defaultTargetUrl = null;
    String authenticationFailureUrl = null;
    String alwaysUseDefault = null;
    String successHandlerRef = null;
    String failureHandlerRef = null;
    // Only available with form-login
    String usernameParameter = null;
    String passwordParameter = null;
    String authDetailsSourceRef = null;

    Object source = null;

    if (elt != null) {
      source = pc.extractSource(elt);
      loginUrl = elt.getAttribute(ATT_LOGIN_URL);
      WebConfigUtils.validateHttpRedirect(loginUrl, pc, source);
      defaultTargetUrl = elt.getAttribute(ATT_FORM_LOGIN_TARGET_URL);
      WebConfigUtils.validateHttpRedirect(defaultTargetUrl, pc, source);
      authenticationFailureUrl = elt.getAttribute(ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL);
      WebConfigUtils.validateHttpRedirect(authenticationFailureUrl, pc, source);
      alwaysUseDefault = elt.getAttribute(ATT_ALWAYS_USE_DEFAULT_TARGET_URL);
      loginPage = elt.getAttribute(ATT_LOGIN_PAGE);
      successHandlerRef = elt.getAttribute(ATT_SUCCESS_HANDLER_REF);
      failureHandlerRef = elt.getAttribute(ATT_FAILURE_HANDLER_REF);
      authDetailsSourceRef =
          elt.getAttribute(AuthenticationConfigBuilder.ATT_AUTH_DETAILS_SOURCE_REF);

      if (!StringUtils.hasText(loginPage)) {
        loginPage = null;
      }
      WebConfigUtils.validateHttpRedirect(loginPage, pc, source);
      usernameParameter = elt.getAttribute(ATT_USERNAME_PARAMETER);
      passwordParameter = elt.getAttribute(ATT_PASSWORD_PARAMETER);
    }

    filterBean =
        createFilterBean(
            loginUrl,
            defaultTargetUrl,
            alwaysUseDefault,
            loginPage,
            authenticationFailureUrl,
            successHandlerRef,
            failureHandlerRef,
            authDetailsSourceRef);

    if (StringUtils.hasText(usernameParameter)) {
      filterBean.getPropertyValues().addPropertyValue("usernameParameter", usernameParameter);
    }
    if (StringUtils.hasText(passwordParameter)) {
      filterBean.getPropertyValues().addPropertyValue("passwordParameter", passwordParameter);
    }

    filterBean.setSource(source);

    BeanDefinitionBuilder entryPointBuilder =
        BeanDefinitionBuilder.rootBeanDefinition(LoginUrlAuthenticationEntryPoint.class);
    entryPointBuilder.getRawBeanDefinition().setSource(source);
    entryPointBuilder.addConstructorArgValue(loginPage != null ? loginPage : DEF_LOGIN_PAGE);
    entryPointBuilder.addPropertyValue("portMapper", portMapper);
    entryPointBuilder.addPropertyValue("portResolver", portResolver);
    entryPointBean = (RootBeanDefinition) entryPointBuilder.getBeanDefinition();

    return null;
  }