@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 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 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);
  }