fixed BeanPostProcessor invocation for null bean (SPR-6700)

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2832 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Juergen Hoeller 2010-01-18 18:51:28 +00:00
parent 09ae925ee2
commit b35b9fdc5c
4 changed files with 41 additions and 25 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -509,8 +509,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
Object exposedObject = bean; Object exposedObject = bean;
try { try {
populateBean(beanName, mbd, instanceWrapper); populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd); exposedObject = initializeBean(beanName, exposedObject, mbd);
} }
}
catch (Throwable ex) { catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex; throw (BeanCreationException) ex;
@ -928,7 +930,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
final BeanFactory parent = this; final BeanFactory parent = this;
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() { public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent); return getInstantiationStrategy().instantiate(mbd, beanName, parent);
} }
@ -937,7 +938,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
else { else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
} }
BeanWrapper bw = new BeanWrapperImpl(beanInstance); BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw); initBeanWrapper(bw);
return bw; return bw;
@ -1376,7 +1376,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #applyBeanPostProcessorsAfterInitialization * @see #applyBeanPostProcessorsAfterInitialization
*/ */
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() { AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() { public Object run() {
@ -1413,11 +1412,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (bean instanceof BeanNameAware) { if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName); ((BeanNameAware) bean).setBeanName(beanName);
} }
if (bean instanceof BeanClassLoaderAware) { if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
} }
if (bean instanceof BeanFactoryAware) { if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
} }
@ -1443,7 +1440,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
} }
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
try { try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@ -1452,7 +1448,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return null; return null;
} }
}, getAccessControlContext()); }, getAccessControlContext());
} catch (PrivilegedActionException pae) { }
catch (PrivilegedActionException pae) {
throw pae.getException(); throw pae.getException();
} }
} }
@ -1508,12 +1505,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return null; return null;
} }
}); });
try { try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception { public Object run() throws Exception {
initMethod.invoke(bean, (Object[]) null); initMethod.invoke(bean);
return null; return null;
} }
}, getAccessControlContext()); }, getAccessControlContext());
@ -1526,7 +1521,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
else { else {
try { try {
ReflectionUtils.makeAccessible(initMethod); ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean, (Object[]) null); initMethod.invoke(bean);
} }
catch (InvocationTargetException ex) { catch (InvocationTargetException ex) {
throw ex.getTargetException(); throw ex.getTargetException();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -1410,8 +1410,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
*/ */
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) { protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean instanceof DisposableBean || mbd.getDestroyMethodName() != null || return (bean != null &&
hasDestructionAwareBeanPostProcessors()); (bean instanceof DisposableBean || mbd.getDestroyMethodName() != null ||
hasDestructionAwareBeanPostProcessors()));
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -38,12 +38,12 @@ import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
* Adapter that implements the {@link DisposableBean} interface * Adapter that implements the {@link DisposableBean} and {@link Runnable} interfaces
* performing various destruction steps on a given bean instance: * performing various destruction steps on a given bean instance:
* <ul> * <ul>
* <li>DestructionAwareBeanPostProcessors * <li>DestructionAwareBeanPostProcessors;
* <li>the bean implementing DisposableBean itself * <li>the bean implementing DisposableBean itself;
* <li>a custom destroy method specified on the bean definition * <li>a custom destroy method specified on the bean definition.
* </ul> * </ul>
* *
* @author Juergen Hoeller * @author Juergen Hoeller
@ -83,10 +83,10 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
* @param postProcessors the List of BeanPostProcessors * @param postProcessors the List of BeanPostProcessors
* (potentially DestructionAwareBeanPostProcessor), if any * (potentially DestructionAwareBeanPostProcessor), if any
*/ */
public DisposableBeanAdapter(final Object bean, String beanName, RootBeanDefinition beanDefinition, public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, AccessControlContext acc) { List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
Assert.notNull(bean, "Bean must not be null"); Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean; this.bean = bean;
this.beanName = beanName; this.beanName = beanName;
this.invokeDisposableBean = this.invokeDisposableBean =

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2010 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.
@ -103,6 +103,18 @@ public class CommonAnnotationBeanPostProcessorTests {
assertTrue(bean.destroyCalled); assertTrue(bean.destroyCalled);
} }
@Test
public void testPostProcessorWithNullBean() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
RootBeanDefinition rbd = new RootBeanDefinition(NullFactory.class);
rbd.setFactoryMethodName("create");
bf.registerBeanDefinition("bean", rbd);
assertNull(bf.getBean("bean"));
bf.destroySingletons();
}
@Test @Test
public void testSerialization() throws Exception { public void testSerialization() throws Exception {
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor(); CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
@ -578,4 +590,12 @@ public class CommonAnnotationBeanPostProcessorTests {
private INestedTestBean testBean; private INestedTestBean testBean;
} }
private static class NullFactory {
public static Object create() {
return null;
}
}
} }