|
|
@ -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"); |
|
|
|
* 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. |
|
|
@ -16,19 +16,24 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.beans.factory; |
|
|
|
package org.springframework.beans.factory; |
|
|
|
|
|
|
|
|
|
|
|
import static org.junit.Assert.assertEquals; |
|
|
|
import java.util.HashMap; |
|
|
|
import static org.junit.Assert.assertNull; |
|
|
|
import java.util.Map; |
|
|
|
import static org.junit.Assert.assertSame; |
|
|
|
import java.util.concurrent.atomic.AtomicInteger; |
|
|
|
import static org.springframework.tests.TestResourceUtils.qualifiedResource; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.Test; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.BeansException; |
|
|
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; |
|
|
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; |
|
|
|
|
|
|
|
import org.springframework.beans.factory.config.BeanPostProcessor; |
|
|
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
|
|
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
|
|
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; |
|
|
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; |
|
|
|
import org.springframework.core.io.Resource; |
|
|
|
import org.springframework.core.io.Resource; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.junit.Assert.*; |
|
|
|
|
|
|
|
import static org.springframework.tests.TestResourceUtils.*; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @author Rob Harrop |
|
|
|
* @author Rob Harrop |
|
|
|
* @author Juergen Hoeller |
|
|
|
* @author Juergen Hoeller |
|
|
@ -40,6 +45,7 @@ public final class FactoryBeanTests { |
|
|
|
private static final Resource RETURNS_NULL_CONTEXT = qualifiedResource(CLASS, "returnsNull.xml"); |
|
|
|
private static final Resource RETURNS_NULL_CONTEXT = qualifiedResource(CLASS, "returnsNull.xml"); |
|
|
|
private static final Resource WITH_AUTOWIRING_CONTEXT = qualifiedResource(CLASS, "withAutowiring.xml"); |
|
|
|
private static final Resource WITH_AUTOWIRING_CONTEXT = qualifiedResource(CLASS, "withAutowiring.xml"); |
|
|
|
private static final Resource ABSTRACT_CONTEXT = qualifiedResource(CLASS, "abstract.xml"); |
|
|
|
private static final Resource ABSTRACT_CONTEXT = qualifiedResource(CLASS, "abstract.xml"); |
|
|
|
|
|
|
|
private static final Resource CIRCULAR_CONTEXT = qualifiedResource(CLASS, "circular.xml"); |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void testFactoryBeanReturnsNull() throws Exception { |
|
|
|
public void testFactoryBeanReturnsNull() throws Exception { |
|
|
@ -96,6 +102,23 @@ public final class FactoryBeanTests { |
|
|
|
factory.getBeansOfType(AbstractFactoryBean.class); |
|
|
|
factory.getBeansOfType(AbstractFactoryBean.class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void testCircularReferenceWithPostProcessor() { |
|
|
|
|
|
|
|
DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); |
|
|
|
|
|
|
|
new XmlBeanDefinitionReader(factory).loadBeanDefinitions(CIRCULAR_CONTEXT); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CountingPostProcessor counter = new CountingPostProcessor(); |
|
|
|
|
|
|
|
factory.addBeanPostProcessor(counter); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BeanImpl1 impl1 = factory.getBean(BeanImpl1.class); |
|
|
|
|
|
|
|
assertNotNull(impl1); |
|
|
|
|
|
|
|
assertNotNull(impl1.getImpl2()); |
|
|
|
|
|
|
|
assertNotNull(impl1.getImpl2()); |
|
|
|
|
|
|
|
assertSame(impl1, impl1.getImpl2().getImpl1()); |
|
|
|
|
|
|
|
assertEquals(1, counter.getCount("bean1")); |
|
|
|
|
|
|
|
assertEquals(1, counter.getCount("bean2")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class NullReturningFactoryBean implements FactoryBean<Object> { |
|
|
|
public static class NullReturningFactoryBean implements FactoryBean<Object> { |
|
|
|
|
|
|
|
|
|
|
@ -193,7 +216,114 @@ public final class FactoryBeanTests { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public abstract static class AbstractFactoryBean implements FactoryBean<Object> { |
|
|
|
public abstract static class AbstractFactoryBean implements FactoryBean<Object> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class PassThroughFactoryBean<T> implements FactoryBean<T>, BeanFactoryAware { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Class<T> type; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String instanceName; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private BeanFactory beanFactory; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private T instance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public PassThroughFactoryBean(Class<T> type) { |
|
|
|
|
|
|
|
this.type = type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setInstanceName(String instanceName) { |
|
|
|
|
|
|
|
this.instanceName = instanceName; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
|
|
|
|
|
|
|
this.beanFactory = beanFactory; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public T getObject() { |
|
|
|
|
|
|
|
if (instance == null) { |
|
|
|
|
|
|
|
instance = beanFactory.getBean(instanceName, type); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return instance; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public Class<?> getObjectType() { |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean isSingleton() { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class CountingPostProcessor implements BeanPostProcessor { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<String, AtomicInteger> count = new HashMap<String, AtomicInteger>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public Object postProcessBeforeInitialization(Object bean, String beanName) { |
|
|
|
|
|
|
|
return bean; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public Object postProcessAfterInitialization(Object bean, String beanName) { |
|
|
|
|
|
|
|
if (bean instanceof FactoryBean) { |
|
|
|
|
|
|
|
return bean; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
AtomicInteger c = count.get(beanName); |
|
|
|
|
|
|
|
if (c == null) { |
|
|
|
|
|
|
|
c = new AtomicInteger(0); |
|
|
|
|
|
|
|
count.put(beanName, c); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
c.incrementAndGet(); |
|
|
|
|
|
|
|
return bean; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int getCount(String beanName) { |
|
|
|
|
|
|
|
AtomicInteger c = count.get(beanName); |
|
|
|
|
|
|
|
if (c != null) { |
|
|
|
|
|
|
|
return c.intValue(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class BeanImpl1 { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private BeanImpl2 impl2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public BeanImpl2 getImpl2() { |
|
|
|
|
|
|
|
return impl2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setImpl2(BeanImpl2 impl2) { |
|
|
|
|
|
|
|
this.impl2 = impl2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class BeanImpl2 { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private BeanImpl1 impl1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public BeanImpl1 getImpl1() { |
|
|
|
|
|
|
|
return impl1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setImpl1(BeanImpl1 impl1) { |
|
|
|
|
|
|
|
this.impl1 = impl1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|