LoadTimeWeaverAware beans are consistently being created early for JPA weaving to work reliably
Includes a change for factory methods that declare their return type as FactoryBean: When asked for a specific type match (e.g. LoadTimeWeaverAware), we do check early singleton instances as well (reusing the instances that we create for getObjectType checks). This is necessary in order to make @Bean method introspection as capable as XML bean definition introspection, even in case of the @Bean method using a generic FactoryBean declaration for its return type (instead of the FactoryBean impl class). Issue: SPR-9857
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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,14 +16,17 @@
|
||||
|
||||
package org.springframework.context.annotation.configuration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.TestBean;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
|
||||
@@ -32,6 +35,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ListFactoryBean;
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
@@ -46,8 +50,7 @@ import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.TestBean;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Miscellaneous system tests covering {@link Bean} naming, aliases, scoping and error
|
||||
@@ -65,7 +68,7 @@ public class ConfigurationClassProcessingTests {
|
||||
* When complete, the factory is ready to service requests for any {@link Bean} methods
|
||||
* declared by <var>configClasses</var>.
|
||||
*/
|
||||
private BeanFactory initBeanFactory(Class<?>... configClasses) {
|
||||
private ListableBeanFactory initBeanFactory(Class<?>... configClasses) {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
for (Class<?> configClass : configClasses) {
|
||||
String configBeanName = configClass.getName();
|
||||
@@ -126,6 +129,42 @@ public class ConfigurationClassProcessingTests {
|
||||
assertEquals(stringBean, "foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configWithObjectReturnType() {
|
||||
BeanFactory factory = initBeanFactory(ConfigWithNonSpecificReturnTypes.class);
|
||||
assertEquals(Object.class, factory.getType("stringBean"));
|
||||
assertFalse(factory.isTypeMatch("stringBean", String.class));
|
||||
String stringBean = factory.getBean("stringBean", String.class);
|
||||
assertEquals(stringBean, "foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configWithFactoryBeanReturnType() {
|
||||
ListableBeanFactory factory = initBeanFactory(ConfigWithNonSpecificReturnTypes.class);
|
||||
assertEquals(List.class, factory.getType("factoryBean"));
|
||||
assertTrue(factory.isTypeMatch("factoryBean", List.class));
|
||||
assertEquals(FactoryBean.class, factory.getType("&factoryBean"));
|
||||
assertTrue(factory.isTypeMatch("&factoryBean", FactoryBean.class));
|
||||
assertTrue(factory.isTypeMatch("&factoryBean", BeanClassLoaderAware.class));
|
||||
assertTrue(factory.isTypeMatch("&factoryBean", ListFactoryBean.class));
|
||||
assertTrue(factory.getBean("factoryBean") instanceof List);
|
||||
|
||||
String[] beanNames = factory.getBeanNamesForType(FactoryBean.class);
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("&factoryBean", beanNames[0]);
|
||||
|
||||
beanNames = factory.getBeanNamesForType(BeanClassLoaderAware.class);
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("&factoryBean", beanNames[0]);
|
||||
|
||||
beanNames = factory.getBeanNamesForType(ListFactoryBean.class);
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("&factoryBean", beanNames[0]);
|
||||
|
||||
beanNames = factory.getBeanNamesForType(List.class);
|
||||
assertEquals("factoryBean", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithPrototypeScopedBeans() {
|
||||
BeanFactory factory = initBeanFactory(ConfigWithPrototypeBean.class);
|
||||
@@ -186,6 +225,19 @@ public class ConfigurationClassProcessingTests {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class ConfigWithNonSpecificReturnTypes {
|
||||
public @Bean Object stringBean() {
|
||||
return "foo";
|
||||
}
|
||||
public @Bean FactoryBean factoryBean() {
|
||||
ListFactoryBean fb = new ListFactoryBean();
|
||||
fb.setSourceList(Arrays.asList("element1", "element2"));
|
||||
return fb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class ConfigWithBeanWithAliases {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user