Browse Source

BeanFactoryUtils caches transformedBeanName results for factory beans

Issue: SPR-17151
pull/1918/merge
Juergen Hoeller 8 years ago
parent
commit
eddbf13d5d
  1. 21
      spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java
  2. 39
      spring-beans/src/test/java/org/springframework/beans/factory/xml/XmlListableBeanFactoryTests.java

21
spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java

@ -22,6 +22,7 @@ import java.util.Arrays; @@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
@ -51,6 +52,13 @@ public abstract class BeanFactoryUtils { @@ -51,6 +52,13 @@ public abstract class BeanFactoryUtils {
*/
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
@ -72,11 +80,16 @@ public abstract class BeanFactoryUtils { @@ -72,11 +80,16 @@ public abstract class BeanFactoryUtils {
*/
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
String beanName = name;
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
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;
});
}
/**

39
spring-beans/src/test/java/org/springframework/beans/factory/xml/XmlListableBeanFactoryTests.java

@ -1,5 +1,5 @@ @@ -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");
* you may not use this file except in compliance with the License.
@ -42,30 +42,33 @@ import static org.junit.Assert.*; @@ -42,30 +42,33 @@ import static org.junit.Assert.*;
* @author Juergen Hoeller
* @since 09.11.2003
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTests {
private DefaultListableBeanFactory parent;
private DefaultListableBeanFactory factory;
@Before
public void setUp() {
public void setup() {
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);
bd1.setPropertyValues(new MutablePropertyValues(m));
bd1.setPropertyValues(new MutablePropertyValues(map));
parent.registerBeanDefinition("father", bd1);
m = new HashMap();
m.put("name", "Roderick");
map = new HashMap();
map.put("name", "Roderick");
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
bd2.setPropertyValues(new MutablePropertyValues(m));
bd2.setPropertyValues(new MutablePropertyValues(map));
parent.registerBeanDefinition("rod", bd2);
this.factory = new DefaultListableBeanFactory(parent);
new XmlBeanDefinitionReader(this.factory).loadBeanDefinitions(
new ClassPathResource("test.xml", getClass()));
new XmlBeanDefinitionReader(this.factory).loadBeanDefinitions(new ClassPathResource("test.xml", getClass()));
this.factory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
@ -82,9 +85,10 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest @@ -82,9 +85,10 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
return bean;
}
});
this.factory.addBeanPostProcessor(new LifecycleBean.PostProcessor());
this.factory.addBeanPostProcessor(new ProtectedLifecycleBean.PostProcessor());
//this.factory.preInstantiateSingletons();
// this.factory.preInstantiateSingletons();
}
@Override
@ -92,6 +96,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest @@ -92,6 +96,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
return factory;
}
@Test
@Override
public void count() {
@ -104,19 +109,19 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest @@ -104,19 +109,19 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
}
@Test
public void lifecycleMethods() throws Exception {
public void lifecycleMethods() {
LifecycleBean bean = (LifecycleBean) getBeanFactory().getBean("lifecycle");
bean.businessMethod();
}
@Test
public void protectedLifecycleMethods() throws Exception {
public void protectedLifecycleMethods() {
ProtectedLifecycleBean bean = (ProtectedLifecycleBean) getBeanFactory().getBean("protectedLifecycle");
bean.businessMethod();
}
@Test
public void descriptionButNoProperties() throws Exception {
public void descriptionButNoProperties() {
TestBean validEmpty = (TestBean) getBeanFactory().getBean("validEmptyWithDescription");
assertEquals(0, validEmpty.getAge());
}
@ -125,7 +130,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest @@ -125,7 +130,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
* Test that properties with name as well as id creating an alias up front.
*/
@Test
public void autoAliasing() throws Exception {
public void autoAliasing() {
List beanNames = Arrays.asList(getListableBeanFactory().getBeanDefinitionNames());
TestBean tb1 = (TestBean) getBeanFactory().getBean("aliased");
@ -224,7 +229,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest @@ -224,7 +229,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
}
@Test
public void beanPostProcessor() throws Exception {
public void beanPostProcessor() {
TestBean kerry = (TestBean) getBeanFactory().getBean("kerry");
TestBean kathy = (TestBean) getBeanFactory().getBean("kathy");
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");

Loading…
Cancel
Save