Browse Source

DefaultListableBeanFactory efficiently accesses current bean names and exposes them via getBeanNamesIterator()

Issue: SPR-12404
pull/692/head
Juergen Hoeller 10 years ago
parent
commit
965bea7b3e
  1. 18
      spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableListableBeanFactory.java
  2. 177
      spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
  3. 22
      spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
  4. 18
      spring-beans/src/test/java/org/springframework/beans/factory/DefaultSingletonBeanRegistryTests.java

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 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.
@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.beans.factory.config;
import java.util.Iterator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@ -105,6 +107,20 @@ public interface ConfigurableListableBeanFactory @@ -105,6 +107,20 @@ public interface ConfigurableListableBeanFactory
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* Return a unified view over all bean names managed by this factory.
* <p>Includes bean definition names as well as names of manually registered
* singleton instances, with bean definition names consistently coming first,
* analogous to how type/annotation specific retrieval of bean names works.
* @return the composite iterator for the bean names view
* @since 4.1.2
* @see #containsBeanDefinition
* @see #registerSingleton
* @see #getBeanNamesForType
* @see #getBeanNamesForAnnotation
*/
Iterator<String> getBeanNamesIterator();
/**
* Freeze all bean definitions, signalling that the registered bean definitions
* will not be modified or post-processed any further.

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

@ -34,7 +34,9 @@ import java.util.Collections; @@ -34,7 +34,9 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -68,6 +70,7 @@ import org.springframework.core.annotation.AnnotationUtils; @@ -68,6 +70,7 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.UsesJava8;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CompositeIterator;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@ -156,14 +159,17 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -156,14 +159,17 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
/** Map of singleton and non-singleton bean names keyed by dependency type */
/** Map of singleton and non-singleton bean names, keyed by dependency type */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** Map of singleton-only bean names keyed by dependency type */
/** Map of singleton-only bean names, keyed by dependency type */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** List of bean definition names, in registration order */
private final List<String> beanDefinitionNames = new ArrayList<String>();
private final List<String> beanDefinitionNames = new ArrayList<String>(64);
/** List of names of manually registered singletons, in registration order */
private final Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
/** Whether bean definition metadata may be cached for all beans */
private boolean configurationFrozen = false;
@ -202,6 +208,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -202,6 +208,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
this.serializationId = serializationId;
}
/**
* Return an id for serialization purposes, if specified, allowing this BeanFactory
* to be deserialized from this id back into the BeanFactory object, if needed.
* @since 4.1.2
*/
public String getSerializationId() {
return this.serializationId;
}
/**
* Set whether it should be allowed to override bean definitions by registering
* a different definition with the same name, automatically replacing the former.
@ -213,6 +228,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -213,6 +228,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding;
}
/**
* Return whether it should be allowed to override bean definitions by registering
* a different definition with the same name, automatically replacing the former.
* @since 4.1.2
*/
public boolean isAllowBeanDefinitionOverriding() {
return this.allowBeanDefinitionOverriding;
}
/**
* Set whether the factory is allowed to eagerly load bean classes
* even for bean definitions that are marked as "lazy-init".
@ -227,6 +251,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -227,6 +251,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
this.allowEagerClassLoading = allowEagerClassLoading;
}
/**
* Return whether the factory is allowed to eagerly load bean classes
* even for bean definitions that are marked as "lazy-init".
* @since 4.1.2
*/
public boolean isAllowEagerClassLoading() {
return this.allowEagerClassLoading;
}
/**
* Set a {@link java.util.Comparator} for dependency Lists and arrays.
* @see org.springframework.core.OrderComparator
@ -352,13 +385,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -352,13 +385,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
@Override
public String[] getBeanDefinitionNames() {
synchronized (this.beanDefinitionMap) {
if (this.frozenBeanDefinitionNames != null) {
return this.frozenBeanDefinitionNames;
}
else {
return StringUtils.toStringArray(this.beanDefinitionNames);
}
if (this.frozenBeanDefinitionNames != null) {
return this.frozenBeanDefinitionNames;
}
else {
return StringUtils.toStringArray(this.beanDefinitionNames);
}
}
@ -389,8 +420,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -389,8 +420,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
List<String> result = new ArrayList<String>();
// Check all bean definitions.
String[] beanDefinitionNames = getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
if (!isAlias(beanName)) {
@ -398,7 +428,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -398,7 +428,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
((mbd.hasBeanClass() || !mbd.isLazyInit() || this.allowEagerClassLoading)) &&
((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
// In case of FactoryBean, match object created by FactoryBean.
boolean isFactoryBean = isFactoryBean(beanName, mbd);
@ -437,9 +467,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -437,9 +467,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
// Check singletons too, to catch manually registered singletons.
String[] singletonNames = getSingletonNames();
for (String beanName : singletonNames) {
// Check manually registered singletons too.
for (String beanName : this.manualSingletonNames) {
// Only check if manually registered.
if (!containsBeanDefinition(beanName)) {
// In case of FactoryBean, match object created by FactoryBean.
@ -512,13 +541,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -512,13 +541,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
@Override
public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
List<String> results = new ArrayList<String>();
for (String beanName : getBeanDefinitionNames()) {
for (String beanName : this.beanDefinitionNames) {
BeanDefinition beanDefinition = getBeanDefinition(beanName);
if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) {
results.add(beanName);
}
}
for (String beanName : getSingletonNames()) {
for (String beanName : this.manualSingletonNames) {
if (!results.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) {
results.add(beanName);
}
@ -529,13 +558,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -529,13 +558,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
@Override
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
Map<String, Object> results = new LinkedHashMap<String, Object>();
for (String beanName : getBeanDefinitionNames()) {
for (String beanName : this.beanDefinitionNames) {
BeanDefinition beanDefinition = getBeanDefinition(beanName);
if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) {
results.put(beanName, getBean(beanName));
}
}
for (String beanName : getSingletonNames()) {
for (String beanName : this.manualSingletonNames) {
if (!results.containsKey(beanName) && findAnnotationOnBean(beanName, annotationType) != null) {
results.put(beanName, getBean(beanName));
}
@ -662,12 +691,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -662,12 +691,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return bd;
}
@Override
public Iterator<String> getBeanNamesIterator() {
CompositeIterator<String> iterator = new CompositeIterator<String>();
iterator.add(this.beanDefinitionNames.iterator());
iterator.add(this.manualSingletonNames.iterator());
return iterator;
}
@Override
public void freezeConfiguration() {
this.configurationFrozen = true;
synchronized (this.beanDefinitionMap) {
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
@Override
@ -691,12 +726,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -691,12 +726,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
this.logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
synchronized (this.beanDefinitionMap) {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
@ -772,35 +804,34 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -772,35 +804,34 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
BeanDefinition oldBeanDefinition;
synchronized (this.beanDefinitionMap) {
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
" with a framework-generated bean definition ': replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
" with a framework-generated bean definition ': replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else {
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
this.frozenBeanDefinitionNames = null;
}
this.beanDefinitionMap.put(beanName, beanDefinition);
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
@ -811,17 +842,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -811,17 +842,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
Assert.hasText(beanName, "'beanName' must not be empty");
synchronized (this.beanDefinitionMap) {
BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
this.beanDefinitionNames.remove(beanName);
this.frozenBeanDefinitionNames = null;
throw new NoSuchBeanDefinitionException(beanName);
}
this.beanDefinitionNames.remove(beanName);
this.frozenBeanDefinitionNames = null;
resetBeanDefinition(beanName);
}
@ -856,18 +885,22 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -856,18 +885,22 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
*/
@Override
protected boolean allowAliasOverriding() {
return this.allowBeanDefinitionOverriding;
return isAllowBeanDefinitionOverriding();
}
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
super.registerSingleton(beanName, singletonObject);
if (!this.beanDefinitionMap.containsKey(beanName)) {
this.manualSingletonNames.add(beanName);
}
clearByTypeCache();
}
@Override
public void destroySingleton(String beanName) {
super.destroySingleton(beanName);
this.manualSingletonNames.remove(beanName);
clearByTypeCache();
}
@ -940,7 +973,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -940,7 +973,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (this.dependencyComparator != null && result instanceof Object[]) {
if (getDependencyComparator() != null && result instanceof Object[]) {
Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
}
return result;
@ -967,7 +1000,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -967,7 +1000,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (this.dependencyComparator != null && result instanceof List) {
if (getDependencyComparator() != null && result instanceof List) {
Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
}
return result;
@ -1030,12 +1063,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -1030,12 +1063,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
private Comparator<Object> adaptDependencyComparator(Map<String, Object> matchingBeans) {
if (this.dependencyComparator instanceof OrderComparator) {
return ((OrderComparator) this.dependencyComparator).withSourceProvider(
Comparator<Object> comparator = getDependencyComparator();
if (comparator instanceof OrderComparator) {
return ((OrderComparator) comparator).withSourceProvider(
createFactoryAwareOrderSourceProvider(matchingBeans));
}
else {
return this.dependencyComparator;
return comparator;
}
}
@ -1223,8 +1257,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -1223,8 +1257,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
* @return the priority assigned to that bean or {@code null} if none is set
*/
protected Integer getPriority(Object beanInstance) {
if (this.dependencyComparator instanceof OrderComparator) {
return ((OrderComparator) this.dependencyComparator).getPriority(beanInstance);
Comparator<Object> comparator = getDependencyComparator();
if (comparator instanceof OrderComparator) {
return ((OrderComparator) comparator).getPriority(beanInstance);
}
return null;
}
@ -1266,7 +1301,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -1266,7 +1301,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
public String toString() {
StringBuilder sb = new StringBuilder(ObjectUtils.identityToString(this));
sb.append(": defining beans [");
sb.append(StringUtils.arrayToCommaDelimitedString(getBeanDefinitionNames()));
sb.append(StringUtils.collectionToCommaDelimitedString(this.beanDefinitionNames));
sb.append("]; ");
BeanFactory parent = getParentBeanFactory();
if (parent == null) {

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

@ -1000,6 +1000,16 @@ public class DefaultListableBeanFactoryTests { @@ -1000,6 +1000,16 @@ public class DefaultListableBeanFactoryTests {
beansOfType = lbf.getBeansOfType(null, false, true);
assertEquals(2, beansOfType.size());
Iterator<String> beanNames = lbf.getBeanNamesIterator();
assertEquals("test", beanNames.next());
assertEquals("singletonObject", beanNames.next());
assertFalse(beanNames.hasNext());
assertTrue(lbf.containsSingleton("test"));
assertTrue(lbf.containsSingleton("singletonObject"));
assertTrue(lbf.containsBeanDefinition("test"));
assertFalse(lbf.containsBeanDefinition("singletonObject"));
}
@Test
@ -1010,8 +1020,8 @@ public class DefaultListableBeanFactoryTests { @@ -1010,8 +1020,8 @@ public class DefaultListableBeanFactoryTests {
p.setProperty("test.name", "Tony");
p.setProperty("test.age", "48");
p.setProperty("test.spouse(ref)", "singletonObject");
p.setProperty("singletonObject.(class)", org.springframework.beans.factory.config.PropertiesFactoryBean.class.getName());
(new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
lbf.registerBeanDefinition("singletonObject", new RootBeanDefinition(PropertiesFactoryBean.class));
Object singletonObject = new TestBean();
lbf.registerSingleton("singletonObject", singletonObject);
lbf.preInstantiateSingletons();
@ -1028,7 +1038,17 @@ public class DefaultListableBeanFactoryTests { @@ -1028,7 +1038,17 @@ public class DefaultListableBeanFactoryTests {
assertTrue(beansOfType.containsValue(singletonObject));
beansOfType = lbf.getBeansOfType(null, false, true);
Iterator<String> beanNames = lbf.getBeanNamesIterator();
assertEquals("test", beanNames.next());
assertEquals("singletonObject", beanNames.next());
assertFalse(beanNames.hasNext());
assertEquals(2, beansOfType.size());
assertTrue(lbf.containsSingleton("test"));
assertTrue(lbf.containsSingleton("singletonObject"));
assertTrue(lbf.containsBeanDefinition("test"));
assertTrue(lbf.containsBeanDefinition("singletonObject"));
}
@Test

18
spring-beans/src/test/java/org/springframework/beans/factory/SharedBeanRegistryTests.java → spring-beans/src/test/java/org/springframework/beans/factory/DefaultSingletonBeanRegistryTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@ -16,8 +16,6 @@ @@ -16,8 +16,6 @@
package org.springframework.beans.factory;
import java.util.Arrays;
import org.junit.Test;
import org.springframework.beans.BeansException;
@ -32,7 +30,7 @@ import static org.junit.Assert.*; @@ -32,7 +30,7 @@ import static org.junit.Assert.*;
* @author Chris Beams
* @since 04.07.2006
*/
public final class SharedBeanRegistryTests {
public class DefaultSingletonBeanRegistryTests {
@Test
public void testSingletons() {
@ -53,9 +51,10 @@ public final class SharedBeanRegistryTests { @@ -53,9 +51,10 @@ public final class SharedBeanRegistryTests {
assertSame(tb, beanRegistry.getSingleton("tb"));
assertSame(tb2, beanRegistry.getSingleton("tb2"));
assertEquals(2, beanRegistry.getSingletonCount());
assertEquals(2, beanRegistry.getSingletonNames().length);
assertTrue(Arrays.asList(beanRegistry.getSingletonNames()).contains("tb"));
assertTrue(Arrays.asList(beanRegistry.getSingletonNames()).contains("tb2"));
String[] names = beanRegistry.getSingletonNames();
assertEquals(2, names.length);
assertEquals("tb", names[0]);
assertEquals("tb2", names[1]);
beanRegistry.destroySingletons();
assertEquals(0, beanRegistry.getSingletonCount());
@ -73,8 +72,9 @@ public final class SharedBeanRegistryTests { @@ -73,8 +72,9 @@ public final class SharedBeanRegistryTests {
assertSame(tb, beanRegistry.getSingleton("tb"));
assertEquals(1, beanRegistry.getSingletonCount());
assertEquals(1, beanRegistry.getSingletonNames().length);
assertTrue(Arrays.asList(beanRegistry.getSingletonNames()).contains("tb"));
String[] names = beanRegistry.getSingletonNames();
assertEquals(1, names.length);
assertEquals("tb", names[0]);
assertFalse(tb.wasDestroyed());
beanRegistry.destroySingletons();
Loading…
Cancel
Save