@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);
	}
	@Test
	public void testExtendedResourceInjection() {
		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);

		bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ExtendedResourceInjectionBean.class));
		bf.registerBeanDefinition("annotatedBean2", new RootBeanDefinition(NamedResourceInjectionBean.class));
		bf.registerBeanDefinition("annotatedBean3", new RootBeanDefinition(ConvertedResourceInjectionBean.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("value", "5");
		bf.registerSingleton("xy", tb6);
		bf.registerAlias("xy", "testBean9");

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

		NamedResourceInjectionBean bean2 = (NamedResourceInjectionBean) bf.getBean("annotatedBean2");
		assertSame(tb6, bean2.testBean);

		ConvertedResourceInjectionBean bean3 = (ConvertedResourceInjectionBean) bf.getBean("annotatedBean3");
		assertSame(5, bean3.value);

		bf.destroySingletons();
		assertTrue(bean.destroyCalled);
		assertTrue(bean.destroy2Called);
	}
	@Test
	public void testResourceInjectionWithResolvableDependencyType() {
		DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
		CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
		bpp.setBeanFactory(bf);
		bf.addBeanPostProcessor(bpp);
		RootBeanDefinition abd = new RootBeanDefinition(ExtendedResourceInjectionBean.class);
		abd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		bf.registerBeanDefinition("annotatedBean", abd);
		RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class);
		tbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		bf.registerBeanDefinition("testBean4", tbd);

		bf.registerResolvableDependency(BeanFactory.class, bf);
		bf.registerResolvableDependency(INestedTestBean.class, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				return new NestedTestBean();
			}
		});

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

		ExtendedResourceInjectionBean bean = (ExtendedResourceInjectionBean) bf.getBean("annotatedBean");
		INestedTestBean tb = bean.getTestBean6();
		assertNotNull(tb);

		ExtendedResourceInjectionBean anotherBean = (ExtendedResourceInjectionBean) bf.getBean("annotatedBean");
		assertNotSame(anotherBean, bean);
		assertNotSame(anotherBean.getTestBean6(), tb);

		String[] depBeans = bf.getDependenciesForBean("annotatedBean");
		assertEquals(1, depBeans.length);
		assertEquals("testBean4", depBeans[0]);
	}