From b35b9fdc5cb8260e8fb121c6f178957ca368e2bc Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 18 Jan 2010 18:51:28 +0000 Subject: [PATCH] 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 --- .../AbstractAutowireCapableBeanFactory.java | 23 ++++++++----------- .../factory/support/AbstractBeanFactory.java | 7 +++--- .../support/DisposableBeanAdapter.java | 14 +++++------ ...ommonAnnotationBeanPostProcessorTests.java | 22 +++++++++++++++++- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 324e6a13835..805e6808600 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -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() { - 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() { 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() { @@ -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() { - 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(); diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 4d3fa9cc553..9191bb9b63b 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -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())); } /** diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index 31c88151339..c9283b08274 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -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: *
    - *
  • DestructionAwareBeanPostProcessors - *
  • the bean implementing DisposableBean itself - *
  • a custom destroy method specified on the bean definition + *
  • DestructionAwareBeanPostProcessors; + *
  • the bean implementing DisposableBean itself; + *
  • a custom destroy method specified on the bean definition. *
* * @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 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 = diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java index 21bfcca268d..b510e257aa4 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java @@ -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; + } + } + }