BeanFactoryUtils caches transformedBeanName results for factory beans
Issue: SPR-17151
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Arrays;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
@@ -51,6 +52,13 @@ public abstract class BeanFactoryUtils {
|
|||||||
*/
|
*/
|
||||||
public static final String GENERATED_BEAN_NAME_SEPARATOR = "#";
|
public static final String GENERATED_BEAN_NAME_SEPARATOR = "#";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache from name with factory bean prefix to stripped name without dereference.
|
||||||
|
* @since 5.1
|
||||||
|
* @see BeanFactory#FACTORY_BEAN_PREFIX
|
||||||
|
*/
|
||||||
|
private static final Map<String, String> transformedBeanNameCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the given name is a factory dereference
|
* Return whether the given name is a factory dereference
|
||||||
@@ -72,11 +80,16 @@ public abstract class BeanFactoryUtils {
|
|||||||
*/
|
*/
|
||||||
public static String transformedBeanName(String name) {
|
public static String transformedBeanName(String name) {
|
||||||
Assert.notNull(name, "'name' must not be null");
|
Assert.notNull(name, "'name' must not be null");
|
||||||
String beanName = name;
|
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
|
||||||
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
|
return name;
|
||||||
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
|
|
||||||
}
|
}
|
||||||
return beanName;
|
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
|
||||||
|
do {
|
||||||
|
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
|
||||||
|
}
|
||||||
|
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
|
||||||
|
return beanName;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2018 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.
|
||||||
@@ -42,30 +42,33 @@ import static org.junit.Assert.*;
|
|||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 09.11.2003
|
* @since 09.11.2003
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTests {
|
public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTests {
|
||||||
|
|
||||||
private DefaultListableBeanFactory parent;
|
private DefaultListableBeanFactory parent;
|
||||||
|
|
||||||
private DefaultListableBeanFactory factory;
|
private DefaultListableBeanFactory factory;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setup() {
|
||||||
parent = new DefaultListableBeanFactory();
|
parent = new DefaultListableBeanFactory();
|
||||||
Map m = new HashMap();
|
|
||||||
m.put("name", "Albert");
|
Map map = new HashMap();
|
||||||
|
map.put("name", "Albert");
|
||||||
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
||||||
bd1.setPropertyValues(new MutablePropertyValues(m));
|
bd1.setPropertyValues(new MutablePropertyValues(map));
|
||||||
parent.registerBeanDefinition("father", bd1);
|
parent.registerBeanDefinition("father", bd1);
|
||||||
m = new HashMap();
|
|
||||||
m.put("name", "Roderick");
|
map = new HashMap();
|
||||||
|
map.put("name", "Roderick");
|
||||||
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
||||||
bd2.setPropertyValues(new MutablePropertyValues(m));
|
bd2.setPropertyValues(new MutablePropertyValues(map));
|
||||||
parent.registerBeanDefinition("rod", bd2);
|
parent.registerBeanDefinition("rod", bd2);
|
||||||
|
|
||||||
this.factory = new DefaultListableBeanFactory(parent);
|
this.factory = new DefaultListableBeanFactory(parent);
|
||||||
new XmlBeanDefinitionReader(this.factory).loadBeanDefinitions(
|
new XmlBeanDefinitionReader(this.factory).loadBeanDefinitions(new ClassPathResource("test.xml", getClass()));
|
||||||
new ClassPathResource("test.xml", getClass()));
|
|
||||||
this.factory.addBeanPostProcessor(new BeanPostProcessor() {
|
this.factory.addBeanPostProcessor(new BeanPostProcessor() {
|
||||||
@Override
|
@Override
|
||||||
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
|
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
|
||||||
@@ -82,9 +85,10 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
|||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.factory.addBeanPostProcessor(new LifecycleBean.PostProcessor());
|
this.factory.addBeanPostProcessor(new LifecycleBean.PostProcessor());
|
||||||
this.factory.addBeanPostProcessor(new ProtectedLifecycleBean.PostProcessor());
|
this.factory.addBeanPostProcessor(new ProtectedLifecycleBean.PostProcessor());
|
||||||
//this.factory.preInstantiateSingletons();
|
// this.factory.preInstantiateSingletons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -92,6 +96,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
|||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Override
|
@Override
|
||||||
public void count() {
|
public void count() {
|
||||||
@@ -104,19 +109,19 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lifecycleMethods() throws Exception {
|
public void lifecycleMethods() {
|
||||||
LifecycleBean bean = (LifecycleBean) getBeanFactory().getBean("lifecycle");
|
LifecycleBean bean = (LifecycleBean) getBeanFactory().getBean("lifecycle");
|
||||||
bean.businessMethod();
|
bean.businessMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void protectedLifecycleMethods() throws Exception {
|
public void protectedLifecycleMethods() {
|
||||||
ProtectedLifecycleBean bean = (ProtectedLifecycleBean) getBeanFactory().getBean("protectedLifecycle");
|
ProtectedLifecycleBean bean = (ProtectedLifecycleBean) getBeanFactory().getBean("protectedLifecycle");
|
||||||
bean.businessMethod();
|
bean.businessMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void descriptionButNoProperties() throws Exception {
|
public void descriptionButNoProperties() {
|
||||||
TestBean validEmpty = (TestBean) getBeanFactory().getBean("validEmptyWithDescription");
|
TestBean validEmpty = (TestBean) getBeanFactory().getBean("validEmptyWithDescription");
|
||||||
assertEquals(0, validEmpty.getAge());
|
assertEquals(0, validEmpty.getAge());
|
||||||
}
|
}
|
||||||
@@ -125,7 +130,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
|||||||
* Test that properties with name as well as id creating an alias up front.
|
* Test that properties with name as well as id creating an alias up front.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void autoAliasing() throws Exception {
|
public void autoAliasing() {
|
||||||
List beanNames = Arrays.asList(getListableBeanFactory().getBeanDefinitionNames());
|
List beanNames = Arrays.asList(getListableBeanFactory().getBeanDefinitionNames());
|
||||||
|
|
||||||
TestBean tb1 = (TestBean) getBeanFactory().getBean("aliased");
|
TestBean tb1 = (TestBean) getBeanFactory().getBean("aliased");
|
||||||
@@ -224,7 +229,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void beanPostProcessor() throws Exception {
|
public void beanPostProcessor() {
|
||||||
TestBean kerry = (TestBean) getBeanFactory().getBean("kerry");
|
TestBean kerry = (TestBean) getBeanFactory().getBean("kerry");
|
||||||
TestBean kathy = (TestBean) getBeanFactory().getBean("kathy");
|
TestBean kathy = (TestBean) getBeanFactory().getBean("kathy");
|
||||||
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
|
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
|
||||||
|
|||||||
Reference in New Issue
Block a user