@ -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,19 +16,24 @@
@@ -16,19 +16,24 @@
package org.springframework.beans.factory ;
import static org.junit.Assert.assertEquals ;
import static org.junit.Assert.assertNull ;
import static org.junit.Assert.assertSame ;
import static org.springframework.tests.TestResourceUtils.qualifiedResource ;
import java.util.HashMap ;
import java.util.Map ;
import java.util.concurrent.atomic.AtomicInteger ;
import org.junit.Test ;
import org.springframework.beans.BeansException ;
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.xml.XmlBeanDefinitionReader ;
import org.springframework.core.io.Resource ;
import org.springframework.stereotype.Component ;
import org.springframework.util.Assert ;
import static org.junit.Assert.* ;
import static org.springframework.tests.TestResourceUtils.* ;
/ * *
* @author Rob Harrop
* @author Juergen Hoeller
@ -40,6 +45,7 @@ public final class FactoryBeanTests {
@@ -40,6 +45,7 @@ public final class FactoryBeanTests {
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 ABSTRACT_CONTEXT = qualifiedResource ( CLASS , "abstract.xml" ) ;
private static final Resource CIRCULAR_CONTEXT = qualifiedResource ( CLASS , "circular.xml" ) ;
@Test
public void testFactoryBeanReturnsNull ( ) throws Exception {
@ -96,6 +102,23 @@ public final class FactoryBeanTests {
@@ -96,6 +102,23 @@ public final class FactoryBeanTests {
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 > {
@ -193,7 +216,114 @@ public final class FactoryBeanTests {
@@ -193,7 +216,114 @@ public final class FactoryBeanTests {
}
}
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 ;
}
}
}