Browse Source

Added "destroyBean(Object)" method to AutowireCapableBeanFactory

Driven by the need for implementing Bean Validation 1.1's "releaseInstance" method in SpringConstraintValidatorFactory, as a direct counterpart to the use of AutowireCapableBeanFactory's "createBean(Class)" in "getInstance".

Issue: SPR-8199
pull/268/head
Juergen Hoeller 13 years ago
parent
commit
23bf5f563b
  1. 12
      spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java
  2. 4
      spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
  3. 22
      spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
  4. 19
      spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

12
spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@ -302,6 +302,16 @@ public interface AutowireCapableBeanFactory extends BeanFactory { @@ -302,6 +302,16 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
/**
* Destroy the given bean instance (typically coming from {@link #createBean}),
* applying the {@link org.springframework.beans.factory.DisposableBean} contract as well as
* registered {@link DestructionAwareBeanPostProcessor DestructionAwareBeanPostProcessors}.
* <p>Any exception that arises during destruction should be caught
* and logged instead of propagated to the caller of this method.
* @param existingBean the bean instance to destroy
*/
void destroyBean(Object existingBean);
/**
* Resolve the specified dependency against the beans defined in this factory.
* @param descriptor the descriptor for the dependency

4
spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

@ -417,6 +417,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac @@ -417,6 +417,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return result;
}
public void destroyBean(Object existingBean) {
new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
}
//---------------------------------------------------------------------
// Implementation of relevant AbstractBeanFactory template methods

22
spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java

@ -85,14 +85,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -85,14 +85,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private final boolean nonPublicAccessAllowed;
private final AccessControlContext acc;
private String destroyMethodName;
private transient Method destroyMethod;
private List<DestructionAwareBeanPostProcessor> beanPostProcessors;
private final AccessControlContext acc;
/**
* Create a new DisposableBeanAdapter for the given bean.
@ -138,6 +138,22 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -138,6 +138,22 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
this.beanPostProcessors = filterPostProcessors(postProcessors);
}
/**
* Create a new DisposableBeanAdapter for the given bean.
* @param bean the bean instance (never {@code null})
* @param postProcessors the List of BeanPostProcessors
* (potentially DestructionAwareBeanPostProcessor), if any
*/
public DisposableBeanAdapter(Object bean, List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = null;
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
this.nonPublicAccessAllowed = true;
this.acc = acc;
this.beanPostProcessors = filterPostProcessors(postProcessors);
}
/**
* Create a new DisposableBeanAdapter for the given bean.
*/
@ -149,9 +165,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -149,9 +165,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
this.beanName = beanName;
this.invokeDisposableBean = invokeDisposableBean;
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
this.acc = null;
this.destroyMethodName = destroyMethodName;
this.beanPostProcessors = postProcessors;
this.acc = null;
}

19
spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

@ -32,7 +32,6 @@ import java.util.Locale; @@ -32,7 +32,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.security.auth.Subject;
import org.apache.commons.logging.Log;
@ -41,6 +40,7 @@ import org.junit.Ignore; @@ -41,6 +40,7 @@ import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
@ -1552,6 +1552,23 @@ public class DefaultListableBeanFactoryTests { @@ -1552,6 +1552,23 @@ public class DefaultListableBeanFactoryTests {
assertNull(tb.getSpouse());
}
@Test
public void testCreateBean() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
TestBean tb = lbf.createBean(TestBean.class);
assertSame(lbf, tb.getBeanFactory());
lbf.destroyBean(tb);
}
@Test
public void testCreateBeanWithDisposableBean() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
DerivedTestBean tb = lbf.createBean(DerivedTestBean.class);
assertSame(lbf, tb.getBeanFactory());
lbf.destroyBean(tb);
assertTrue(tb.wasDestroyed());
}
@Test
public void testConfigureBean() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();

Loading…
Cancel
Save