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");
* you may not use this file except in compliance with the License.
@ -509,7 +509,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
@ -928,7 +930,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
@ -937,7 +938,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
@ -1376,7 +1376,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
@ -1413,11 +1412,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
@ -1443,7 +1440,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@ -1451,8 +1447,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
((InitializingBean) bean).afterPropertiesSet();
return null;
}
},getAccessControlContext());
} catch (PrivilegedActionException pae) {
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
@ -1508,12 +1505,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return null;
}
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
initMethod.invoke(bean, (Object[]) null);
initMethod.invoke(bean);
return null;
}
}, getAccessControlContext());
@ -1526,7 +1521,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
else {
try {
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean, (Object[]) null);
initMethod.invoke(bean);
}
catch (InvocationTargetException ex) {
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");
* 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
*/
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean instanceof DisposableBean || mbd.getDestroyMethodName() != null ||
hasDestructionAwareBeanPostProcessors());
return (bean != null &&
(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");
* 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;
/**
* 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:
* <ul>
* <li>DestructionAwareBeanPostProcessors
* <li>the bean implementing DisposableBean itself
* <li>a custom destroy method specified on the bean definition
* <li>DestructionAwareBeanPostProcessors;
* <li>the bean implementing DisposableBean itself;
* <li>a custom destroy method specified on the bean definition.
* </ul>
*
* @author Juergen Hoeller
@ -83,10 +83,10 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
* @param postProcessors the List of BeanPostProcessors
* (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) {
Assert.notNull(bean, "Bean must not be null");
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
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");
* you may not use this file except in compliance with the License.
@ -103,6 +103,18 @@ public class CommonAnnotationBeanPostProcessorTests {
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
public void testSerialization() throws Exception {
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
@ -578,4 +590,12 @@ public class CommonAnnotationBeanPostProcessorTests {
private INestedTestBean testBean;
}
private static class NullFactory {
public static Object create() {
return null;
}
}
}