From 070103b17ee403d7b6ddfd68599fa7a4771dfbdf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 15 May 2013 16:41:32 +0200 Subject: [PATCH] Fixed type detection to avoid reuse of parent bean's targetType on child definition merge Issue: SPR-10374 --- .../AbstractAutowireCapableBeanFactory.java | 10 +++++----- .../beans/factory/support/ChildBeanDefinition.java | 7 +++---- .../beans/factory/support/RootBeanDefinition.java | 13 +++++-------- .../factory/DefaultListableBeanFactoryTests.java | 14 ++++++++++++++ 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index b9694d3cf9..a36ec9009c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -308,12 +308,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac RootBeanDefinition bd = null; if (mbd instanceof RootBeanDefinition) { RootBeanDefinition rbd = (RootBeanDefinition) mbd; - if (rbd.isPrototype()) { - bd = rbd; - } + bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition()); } - if (bd == null) { - bd = new RootBeanDefinition(mbd); + if (!mbd.isPrototype()) { + if (bd == null) { + bd = new RootBeanDefinition(mbd); + } bd.setScope(BeanDefinition.SCOPE_PROTOTYPE); bd.allowCaching = false; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java index cbc43acfbe..87fc66ba87 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.beans.factory.support; import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.util.ObjectUtils; @@ -98,7 +97,7 @@ public class ChildBeanDefinition extends AbstractBeanDefinition { * @param pvs the property values to apply */ public ChildBeanDefinition( - String parentName, Class beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs) { + String parentName, Class beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs) { super(cargs, pvs); this.parentName = parentName; @@ -128,7 +127,7 @@ public class ChildBeanDefinition extends AbstractBeanDefinition { * @param original the original bean definition to copy from */ public ChildBeanDefinition(ChildBeanDefinition original) { - super((BeanDefinition) original); + super(original); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java index e187e5c728..f029c1a8f3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java @@ -171,7 +171,11 @@ public class RootBeanDefinition extends AbstractBeanDefinition { * @param original the original bean definition to copy from */ public RootBeanDefinition(RootBeanDefinition original) { - this((BeanDefinition) original); + super(original); + this.decoratedDefinition = original.decoratedDefinition; + this.allowCaching = original.allowCaching; + this.targetType = original.targetType; + this.isFactoryMethodUnique = original.isFactoryMethodUnique; } /** @@ -181,13 +185,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition { */ RootBeanDefinition(BeanDefinition original) { super(original); - if (original instanceof RootBeanDefinition) { - RootBeanDefinition originalRbd = (RootBeanDefinition) original; - this.decoratedDefinition = originalRbd.decoratedDefinition; - this.allowCaching = originalRbd.allowCaching; - this.targetType = originalRbd.targetType; - this.isFactoryMethodUnique = originalRbd.isFactoryMethodUnique; - } } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index 97c069bb76..c8a2815ca8 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -712,6 +712,20 @@ public class DefaultListableBeanFactoryTests { factory.getMergedBeanDefinition("child"), factory.getMergedBeanDefinition("child")); } + @Test + public void testGetTypeWorksAfterParentChildMerging() { + RootBeanDefinition parentDefinition = new RootBeanDefinition(TestBean.class); + ChildBeanDefinition childDefinition = new ChildBeanDefinition("parent", DerivedTestBean.class, null, null); + + DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); + factory.registerBeanDefinition("parent", parentDefinition); + factory.registerBeanDefinition("child", childDefinition); + factory.freezeConfiguration(); + + assertEquals(TestBean.class, factory.getType("parent")); + assertEquals(DerivedTestBean.class, factory.getType("child")); + } + @Test public void testNameAlreadyBound() { DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();