Skip to content

Commit 5d58676

Browse files
committed
Consistent equality check for parent name and indexed arguments
Closes gh-23593
1 parent 18ae379 commit 5d58676

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-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.
@@ -401,7 +401,7 @@ public boolean equals(Object other) {
401401
for (Map.Entry<Integer, ValueHolder> entry : this.indexedArgumentValues.entrySet()) {
402402
ValueHolder vh1 = entry.getValue();
403403
ValueHolder vh2 = that.indexedArgumentValues.get(entry.getKey());
404-
if (!vh1.contentEquals(vh2)) {
404+
if (vh2 == null || !vh1.contentEquals(vh2)) {
405405
return false;
406406
}
407407
}

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-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.
@@ -17,6 +17,7 @@
1717
package org.springframework.beans.factory.support;
1818

1919
import org.springframework.beans.factory.config.BeanDefinition;
20+
import org.springframework.util.ObjectUtils;
2021

2122
/**
2223
* GenericBeanDefinition is a one-stop shop for standard bean definition purposes.
@@ -81,7 +82,14 @@ public AbstractBeanDefinition cloneBeanDefinition() {
8182

8283
@Override
8384
public boolean equals(Object other) {
84-
return (this == other || (other instanceof GenericBeanDefinition && super.equals(other)));
85+
if (this == other) {
86+
return true;
87+
}
88+
if (!(other instanceof GenericBeanDefinition)) {
89+
return false;
90+
}
91+
GenericBeanDefinition that = (GenericBeanDefinition) other;
92+
return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
8593
}
8694

8795
@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.
@@ -811,26 +811,24 @@ public void testAliasCircle() {
811811
}
812812

813813
@Test
814-
public void testBeanDefinitionOverriding() {
814+
public void testAliasChaining() {
815815
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
816-
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
817816
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
818-
lbf.registerAlias("otherTest", "test2");
819-
lbf.registerAlias("test", "test2");
820-
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
821-
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
817+
lbf.registerAlias("test", "testAlias");
818+
lbf.registerAlias("testAlias", "testAlias2");
819+
lbf.registerAlias("testAlias2", "testAlias3");
820+
Object bean = lbf.getBean("test");
821+
assertSame(bean, lbf.getBean("testAlias"));
822+
assertSame(bean, lbf.getBean("testAlias2"));
823+
assertSame(bean, lbf.getBean("testAlias3"));
822824
}
823825

824826
@Test
825-
public void testBeanDefinitionRemoval() {
827+
public void testBeanDefinitionOverriding() {
826828
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
827-
lbf.setAllowBeanDefinitionOverriding(false);
828829
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
829-
lbf.registerAlias("test", "test2");
830-
lbf.preInstantiateSingletons();
831-
lbf.removeBeanDefinition("test");
832-
lbf.removeAlias("test2");
833830
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
831+
lbf.registerAlias("otherTest", "test2");
834832
lbf.registerAlias("test", "test2");
835833
assertTrue(lbf.getBean("test") instanceof NestedTestBean);
836834
assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
@@ -863,16 +861,31 @@ public void testBeanDefinitionOverridingWithAlias() {
863861
}
864862

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

878891
@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)