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
This commit is contained in:
parent
9f9dc34b53
commit
23bf5f563b
|
@ -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");
|
* 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.
|
||||||
|
@ -302,6 +302,16 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||||
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
|
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
|
||||||
throws BeansException;
|
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.
|
* Resolve the specified dependency against the beans defined in this factory.
|
||||||
* @param descriptor the descriptor for the dependency
|
* @param descriptor the descriptor for the dependency
|
||||||
|
|
|
@ -417,6 +417,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void destroyBean(Object existingBean) {
|
||||||
|
new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of relevant AbstractBeanFactory template methods
|
// Implementation of relevant AbstractBeanFactory template methods
|
||||||
|
|
|
@ -85,14 +85,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||||
|
|
||||||
private final boolean nonPublicAccessAllowed;
|
private final boolean nonPublicAccessAllowed;
|
||||||
|
|
||||||
|
private final AccessControlContext acc;
|
||||||
|
|
||||||
private String destroyMethodName;
|
private String destroyMethodName;
|
||||||
|
|
||||||
private transient Method destroyMethod;
|
private transient Method destroyMethod;
|
||||||
|
|
||||||
private List<DestructionAwareBeanPostProcessor> beanPostProcessors;
|
private List<DestructionAwareBeanPostProcessor> beanPostProcessors;
|
||||||
|
|
||||||
private final AccessControlContext acc;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new DisposableBeanAdapter for the given bean.
|
* Create a new DisposableBeanAdapter for the given bean.
|
||||||
|
@ -138,6 +138,22 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||||
this.beanPostProcessors = filterPostProcessors(postProcessors);
|
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.
|
* Create a new DisposableBeanAdapter for the given bean.
|
||||||
*/
|
*/
|
||||||
|
@ -149,9 +165,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||||
this.beanName = beanName;
|
this.beanName = beanName;
|
||||||
this.invokeDisposableBean = invokeDisposableBean;
|
this.invokeDisposableBean = invokeDisposableBean;
|
||||||
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
|
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
|
||||||
|
this.acc = null;
|
||||||
this.destroyMethodName = destroyMethodName;
|
this.destroyMethodName = destroyMethodName;
|
||||||
this.beanPostProcessors = postProcessors;
|
this.beanPostProcessors = postProcessors;
|
||||||
this.acc = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.security.auth.Subject;
|
import javax.security.auth.Subject;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -41,6 +40,7 @@ import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
import org.springframework.beans.NotWritablePropertyException;
|
import org.springframework.beans.NotWritablePropertyException;
|
||||||
|
@ -1552,6 +1552,23 @@ public class DefaultListableBeanFactoryTests {
|
||||||
assertNull(tb.getSpouse());
|
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
|
@Test
|
||||||
public void testConfigureBean() {
|
public void testConfigureBean() {
|
||||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||||
|
|
Loading…
Reference in New Issue