protected @Autowired method can be overridden with non-annotated method to suppress injection; private @Autowired methods with same signature will be called individually across a hierarchy (SPR-6112)
This commit is contained in:
parent
fa2bb722f0
commit
fd81aa205d
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -21,7 +21,7 @@ import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -83,7 +83,7 @@ public class InjectionMetadata {
|
||||||
doRegisterConfigMembers(beanDefinition, this.injectedMethods);
|
doRegisterConfigMembers(beanDefinition, this.injectedMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doRegisterConfigMembers(RootBeanDefinition beanDefinition, Set<InjectedElement> members) {
|
private void doRegisterConfigMembers(RootBeanDefinition beanDefinition, Collection<InjectedElement> members) {
|
||||||
for (Iterator<InjectedElement> it = members.iterator(); it.hasNext();) {
|
for (Iterator<InjectedElement> it = members.iterator(); it.hasNext();) {
|
||||||
Member member = it.next().getMember();
|
Member member = it.next().getMember();
|
||||||
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
||||||
|
@ -231,15 +231,7 @@ public class InjectionMetadata {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
InjectedElement otherElement = (InjectedElement) other;
|
InjectedElement otherElement = (InjectedElement) other;
|
||||||
if (this.isField) {
|
return this.member.equals(otherElement.member);
|
||||||
return this.member.equals(otherElement.member);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return (otherElement.member instanceof Method &&
|
|
||||||
this.member.getName().equals(otherElement.member.getName()) &&
|
|
||||||
Arrays.equals(((Method) this.member).getParameterTypes(),
|
|
||||||
((Method) otherElement.member).getParameterTypes()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -146,6 +146,32 @@ public final class AutowiredAnnotationBeanPostProcessorTests {
|
||||||
bf.destroySingletons();
|
bf.destroySingletons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtendedResourceInjectionWithSkippedOverriddenMethods() {
|
||||||
|
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||||
|
bf.registerResolvableDependency(BeanFactory.class, bf);
|
||||||
|
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||||
|
bpp.setBeanFactory(bf);
|
||||||
|
bf.addBeanPostProcessor(bpp);
|
||||||
|
RootBeanDefinition annotatedBd = new RootBeanDefinition(OverriddenExtendedResourceInjectionBean.class);
|
||||||
|
bf.registerBeanDefinition("annotatedBean", annotatedBd);
|
||||||
|
TestBean tb = new TestBean();
|
||||||
|
bf.registerSingleton("testBean", tb);
|
||||||
|
NestedTestBean ntb = new NestedTestBean();
|
||||||
|
bf.registerSingleton("nestedTestBean", ntb);
|
||||||
|
|
||||||
|
OverriddenExtendedResourceInjectionBean bean = (OverriddenExtendedResourceInjectionBean) 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
|
@Test
|
||||||
public void testExtendedResourceInjectionWithAtRequired() {
|
public void testExtendedResourceInjectionWithAtRequired() {
|
||||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||||
|
@ -934,7 +960,9 @@ public final class AutowiredAnnotationBeanPostProcessorTests {
|
||||||
|
|
||||||
private ITestBean testBean4;
|
private ITestBean testBean4;
|
||||||
|
|
||||||
private BeanFactory beanFactory;
|
protected BeanFactory beanFactory;
|
||||||
|
|
||||||
|
public boolean baseInjected = false;
|
||||||
|
|
||||||
public ExtendedResourceInjectionBean() {
|
public ExtendedResourceInjectionBean() {
|
||||||
}
|
}
|
||||||
|
@ -950,6 +978,11 @@ public final class AutowiredAnnotationBeanPostProcessorTests {
|
||||||
this.nestedTestBean = nestedTestBean;
|
this.nestedTestBean = nestedTestBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private void inject(ITestBean testBean4) {
|
||||||
|
this.baseInjected = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected void initBeanFactory(BeanFactory beanFactory) {
|
protected void initBeanFactory(BeanFactory beanFactory) {
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
|
@ -978,6 +1011,27 @@ public final class AutowiredAnnotationBeanPostProcessorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class OverriddenExtendedResourceInjectionBean extends ExtendedResourceInjectionBean<NestedTestBean> {
|
||||||
|
|
||||||
|
public boolean subInjected = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTestBean2(TestBean testBean2) {
|
||||||
|
super.setTestBean2(testBean2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initBeanFactory(BeanFactory beanFactory) {
|
||||||
|
this.beanFactory = beanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private void inject(ITestBean testBean4) {
|
||||||
|
this.subInjected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class OptionalResourceInjectionBean extends ResourceInjectionBean {
|
public static class OptionalResourceInjectionBean extends ResourceInjectionBean {
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
|
|
|
@ -689,16 +689,18 @@ public abstract class ClassUtils {
|
||||||
* <code>targetClass</code> doesn't implement it or is <code>null</code>
|
* <code>targetClass</code> doesn't implement it or is <code>null</code>
|
||||||
*/
|
*/
|
||||||
public static Method getMostSpecificMethod(Method method, Class targetClass) {
|
public static Method getMostSpecificMethod(Method method, Class targetClass) {
|
||||||
if (method != null && targetClass != null && !targetClass.equals(method.getDeclaringClass())) {
|
Method result = method;
|
||||||
|
if (method != null && !Modifier.isPrivate(method.getModifiers()) &&
|
||||||
|
targetClass != null && !targetClass.equals(method.getDeclaringClass())) {
|
||||||
try {
|
try {
|
||||||
method = targetClass.getMethod(method.getName(), method.getParameterTypes());
|
result = targetClass.getDeclaredMethod(method.getName(), method.getParameterTypes());
|
||||||
}
|
}
|
||||||
catch (NoSuchMethodException ex) {
|
catch (NoSuchMethodException ex) {
|
||||||
// Perhaps the target class doesn't implement this method:
|
// Perhaps the target class doesn't implement this method:
|
||||||
// that's fine, just use the original method.
|
// that's fine, just use the original method.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return method;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue