Consistent support for Java 8 default methods (in interfaces implemented by user classes)

Covers ReflectionUtils.doWithMethods as well as affected annotation post-processors.
Includes an extension of MethodMetadata for the detection of @Bean default methods.

Issue: SPR-12822
Issue: SPR-10919
This commit is contained in:
Juergen Hoeller
2015-03-19 16:50:15 +01:00
parent 778a01943b
commit 192462902e
14 changed files with 605 additions and 240 deletions

View File

@@ -189,6 +189,32 @@ public class AutowiredAnnotationBeanPostProcessorTests {
bf.destroySingletons();
}
@Test
public void testExtendedResourceInjectionWithDefaultMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerResolvableDependency(BeanFactory.class, bf);
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
RootBeanDefinition annotatedBd = new RootBeanDefinition(DefaultMethodResourceInjectionBean.class);
bf.registerBeanDefinition("annotatedBean", annotatedBd);
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
NestedTestBean ntb = new NestedTestBean();
bf.registerSingleton("nestedTestBean", ntb);
DefaultMethodResourceInjectionBean bean = (DefaultMethodResourceInjectionBean) bf.getBean("annotatedBean");
assertSame(tb, bean.getTestBean());
assertNull(bean.getTestBean2());
assertSame(tb, bean.getTestBean3());
assertSame(tb, bean.getTestBean4());
assertSame(ntb, bean.getNestedTestBean());
assertNull(bean.getBeanFactory());
assertTrue(bean.baseInjected);
assertTrue(bean.subInjected);
bf.destroySingletons();
}
@Test
public void testExtendedResourceInjectionWithAtRequired() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -1876,6 +1902,42 @@ public class AutowiredAnnotationBeanPostProcessorTests {
}
public interface InterfaceWithDefaultMethod {
@Autowired
void setTestBean2(TestBean testBean2);
@Autowired
default void injectDefault(ITestBean testBean4) {
markSubInjected();
}
void markSubInjected();
}
public static class DefaultMethodResourceInjectionBean extends NonPublicResourceInjectionBean<NestedTestBean>
implements InterfaceWithDefaultMethod {
public boolean subInjected = false;
@Override
public void setTestBean2(TestBean testBean2) {
super.setTestBean2(testBean2);
}
@Override
protected void initBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public void markSubInjected() {
subInjected = true;
}
}
public static class OptionalResourceInjectionBean extends ResourceInjectionBean {
@Autowired(required = false)