Always preserve target class for configuration classes in case of auto-proxying

Issue: SPR-10561
This commit is contained in:
Juergen Hoeller 2013-12-02 14:42:17 +01:00
parent 8958912c94
commit 3e4b3cad6a
2 changed files with 29 additions and 2 deletions

View File

@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
import org.springframework.beans.PropertyValues; import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanDefinitionStoreException;
@ -253,8 +254,8 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
throw new IllegalStateException( throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor against " + beanFactory); "postProcessBeanFactory already called for this post-processor against " + beanFactory);
} }
this.factoriesPostProcessed.add((factoryId)); this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains((factoryId))) { if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported... // BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then. // Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
@ -359,7 +360,10 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer(); ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) { for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue(); AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
try { try {
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader); Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
Class<?> enhancedClass = enhancer.enhance(configClass); Class<?> enhancedClass = enhancer.enhance(configClass);
if (configClass != enhancedClass) { if (configClass != enhancedClass) {

View File

@ -20,6 +20,11 @@ import java.util.List;
import org.junit.Test; import org.junit.Test;
import org.springframework.aop.Pointcut;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -127,6 +132,16 @@ public class BeanMethodPolymorphismTests {
assertThat(ctx.getBean(String.class), equalTo("shadow")); assertThat(ctx.getBean(String.class), equalTo("shadow"));
} }
@Test
public void beanMethodThroughAopProxy() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(Config.class);
ctx.register(AnnotationAwareAspectJAutoProxyCreator.class);
ctx.register(TestAdvisor.class);
ctx.refresh();
ctx.getBean("testBean", TestBean.class);
}
@Configuration @Configuration
static class BaseConfig { static class BaseConfig {
@ -239,4 +254,12 @@ public class BeanMethodPolymorphismTests {
} }
} }
public static class TestAdvisor extends DefaultPointcutAdvisor {
public TestAdvisor() {
super(new SimpleTraceInterceptor());
}
}
} }