Skip to content

Commit 8f90f65

Browse files
committed
Consistent equality check for parent name and indexed arguments
Closes gh-23593
1 parent 27a8831 commit 8f90f65

File tree

4 files changed

+66
-26
lines changed

4 files changed

+66
-26
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -408,7 +408,7 @@ public boolean equals(Object other) {
408408
for (Map.Entry<Integer, ValueHolder> entry : this.indexedArgumentValues.entrySet()) {
409409
ValueHolder vh1 = entry.getValue();
410410
ValueHolder vh2 = that.indexedArgumentValues.get(entry.getKey());
411-
if (!vh1.contentEquals(vh2)) {
411+
if (vh2 == null || !vh1.contentEquals(vh2)) {
412412
return false;
413413
}
414414
}

spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import org.springframework.beans.factory.config.BeanDefinition;
2020
import org.springframework.lang.Nullable;
21+
import org.springframework.util.ObjectUtils;
2122

2223
/**
2324
* GenericBeanDefinition is a one-stop shop for standard bean definition purposes.
@@ -84,7 +85,14 @@ public AbstractBeanDefinition cloneBeanDefinition() {
8485

8586
@Override
8687
public boolean equals(Object other) {
87-
return (this == other || (other instanceof GenericBeanDefinition && super.equals(other)));
88+
if (this == other) {
89+
return true;
90+
}
91+
if (!(other instanceof GenericBeanDefinition)) {
92+
return false;
93+
}
94+
GenericBeanDefinition that = (GenericBeanDefinition) other;
95+
return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
8896
}
8997

9098
@Override

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -812,26 +812,24 @@ public void testAliasCircle() {
812812
}
813813

814814
@Test
815-
public void testBeanDefinitionOverriding() {
815+
public void testAliasChaining() {
816816
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
817-
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
818817
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
819-
lbf.registerAlias("otherTest", "test2");
820-
lbf.registerAlias("test", "test2");
821-
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
822-
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
818+
lbf.registerAlias("test", "testAlias");
819+
lbf.registerAlias("testAlias", "testAlias2");
820+
lbf.registerAlias("testAlias2", "testAlias3");
821+
Object bean = lbf.getBean("test");
822+
assertSame(bean, lbf.getBean("testAlias"));
823+
assertSame(bean, lbf.getBean("testAlias2"));
824+
assertSame(bean, lbf.getBean("testAlias3"));
823825
}
824826

825827
@Test
826-
public void testBeanDefinitionRemoval() {
828+
public void testBeanDefinitionOverriding() {
827829
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
828-
lbf.setAllowBeanDefinitionOverriding(false);
829830
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
830-
lbf.registerAlias("test", "test2");
831-
lbf.preInstantiateSingletons();
832-
lbf.removeBeanDefinition("test");
833-
lbf.removeAlias("test2");
834831
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
832+
lbf.registerAlias("otherTest", "test2");
835833
lbf.registerAlias("test", "test2");
836834
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
837835
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
@@ -864,16 +862,31 @@ public void testBeanDefinitionOverridingWithAlias() {
864862
}
865863

866864
@Test
867-
public void testAliasChaining() {
865+
public void beanDefinitionOverridingWithConstructorArgumentMismatch() {
868866
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
867+
RootBeanDefinition bd1 = new RootBeanDefinition(NestedTestBean.class);
868+
bd1.getConstructorArgumentValues().addIndexedArgumentValue(1, "value1");
869+
lbf.registerBeanDefinition("test", bd1);
870+
RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
871+
bd2.getConstructorArgumentValues().addIndexedArgumentValue(0, "value0");
872+
lbf.registerBeanDefinition("test", bd2);
873+
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
874+
assertEquals("value0", lbf.getBean("test", NestedTestBean.class).getCompany());
875+
}
876+
877+
@Test
878+
public void testBeanDefinitionRemoval() {
879+
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
880+
lbf.setAllowBeanDefinitionOverriding(false);
881+
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
882+
lbf.registerAlias("test", "test2");
883+
lbf.preInstantiateSingletons();
884+
lbf.removeBeanDefinition("test");
885+
lbf.removeAlias("test2");
869886
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
870-
lbf.registerAlias("test", "testAlias");
871-
lbf.registerAlias("testAlias", "testAlias2");
872-
lbf.registerAlias("testAlias2", "testAlias3");
873-
Object bean = lbf.getBean("test");
874-
assertSame(bean, lbf.getBean("testAlias"));
875-
assertSame(bean, lbf.getBean("testAlias2"));
876-
assertSame(bean, lbf.getBean("testAlias3"));
887+
lbf.registerAlias("test", "test2");
888+
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
889+
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
877890
}
878891

879892
@Test

spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -100,6 +100,25 @@ public void beanDefinitionEqualityWithTypedConstructorArguments() {
100100
assertTrue(bd.hashCode() == otherBd.hashCode());
101101
}
102102

103+
@Test
104+
public void genericBeanDefinitionEquality() {
105+
GenericBeanDefinition bd = new GenericBeanDefinition();
106+
bd.setParentName("parent");
107+
bd.setScope("request");
108+
bd.setAbstract(true);
109+
bd.setLazyInit(true);
110+
GenericBeanDefinition otherBd = new GenericBeanDefinition();
111+
otherBd.setScope("request");
112+
otherBd.setAbstract(true);
113+
otherBd.setLazyInit(true);
114+
assertTrue(!bd.equals(otherBd));
115+
assertTrue(!otherBd.equals(bd));
116+
otherBd.setParentName("parent");
117+
assertTrue(bd.equals(otherBd));
118+
assertTrue(otherBd.equals(bd));
119+
assertTrue(bd.hashCode() == otherBd.hashCode());
120+
}
121+
103122
@Test
104123
public void beanDefinitionHolderEquality() {
105124
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);

0 commit comments

Comments
 (0)