BeanPostProcessor
及子类介绍
/**
* Factory hook that allows for custom modification of new bean instances,
* e.g. checking for marker interfaces or wrapping them with proxies.
*
* <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
* bean definitions and apply them to any beans subsequently created.
* Plain bean factories allow for programmatic registration of post-processors,
* applying to all beans created through this factory.
*
* <p>Typically, post-processors that populate beans via marker interfaces
* or the like will implement {@link #postProcessBeforeInitialization},
* while post-processors that wrap beans with proxies will normally
* implement {@link #postProcessAfterInitialization}.
*
* @author Juergen Hoeller
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
BeanPostProcssor
是Spring提供的工厂钩子方法,用于拦截每一个Bean对象的创建过程,接口有两个方法,Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
和Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
,分别在Bean对象创建后初始化方法(比如init-method、InitializingBean#afterPropertiesSet)调用前后进行调用,此时Bean的属性值已经被设置好了。容器可以自动发现BeanPostProcessor
,我们只需要将其放入容器即可。他有一些提供更强功能的子类接口:
InstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
DestructionAwareBeanPostProcessor
/**
* Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
* and a callback after instantiation but before explicit properties are set or
* autowiring occurs.
*
* <p>Typically used to suppress default instantiation for specific target beans,
* for example to create proxies with special TargetSources (pooling targets,
* lazily initializing targets, etc), or to implement additional injection strategies
* such as field injection.
*
* <p><b>NOTE:</b> This interface is a special purpose interface, mainly for
* internal use within the framework. It is recommended to implement the plain
* {@link BeanPostProcessor} interface as far as possible, or to derive from
* {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
* from extensions to this interface.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @since 1.2
* @see org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#setCustomTargetSourceCreators
* @see org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator
*/
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>.
* The returned bean object may be a proxy to use instead of the target bean,
* effectively suppressing default instantiation of the target bean.
* <p>If a non-null object is returned by this method, the bean creation process
* will be short-circuited. The only further processing applied is the
* {@link #postProcessAfterInitialization} callback from the configured
* {@link BeanPostProcessor BeanPostProcessors}.
* <p>This callback will only be applied to bean definitions with a bean class.
* In particular, it will not be applied to beans with a "factory-method".
* <p>Post-processors may implement the extended
* {@link SmartInstantiationAwareBeanPostProcessor} interface in order
* to predict the type of the bean object that they are going to return here.
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return the bean object to expose instead of a default instance of the target bean,
* or {@code null} to proceed with default instantiation
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#hasBeanClass
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName
*/
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
/**
* Perform operations after the bean has been instantiated, via a constructor or factory method,
* but before Spring property population (from explicit properties or autowiring) occurs.
* <p>This is the ideal callback for performing custom field injection on the given bean
* instance, right before Spring's autowiring kicks in.
* @param bean the bean instance created, with properties not having been set yet
* @param beanName the name of the bean
* @return {@code true} if properties should be set on the bean; {@code false}
* if property population should be skipped. Normal implementations should return {@code true}.
* Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor
* instances being invoked on this bean instance.
* @throws org.springframework.beans.BeansException in case of errors
*/
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
/**
* Post-process the given property values before the factory applies them
* to the given bean. Allows for checking whether all dependencies have been
* satisfied, for example based on a "Required" annotation on bean property setters.
* <p>Also allows for replacing the property values to apply, typically through
* creating a new MutablePropertyValues instance based on the original PropertyValues,
* adding or removing specific values.
* @param pvs the property values that the factory is about to apply (never {@code null})
* @param pds the relevant property descriptors for the target bean (with ignored
* dependency types - which the factory handles specifically - already filtered out)
* @param bean the bean instance created, but whose properties have not yet been set
* @param beanName the name of the bean
* @return the actual property values to apply to the given bean
* (can be the passed-in PropertyValues instance), or {@code null}
* to skip property population
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.MutablePropertyValues
*/
PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
}
InstantiationAwareBeanPostProcessor
接口增加了Bean实例化之前的回调方法Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
和实例化之后但是属性值或者自动装配之前的回调方法boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
,以及PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
。
此类最典型的应用通常用于拦截特定目标bean的默认实例化,例如,创建特定TargetSources(pooling targets, lazily initializing targets, etc)的代理,或实施额外的注入策略比如按照Field注入。此接口主要用于框架自己,不建议程序猿使用。类似的其子类SmartInstantiationAwareBeanPostProcessor
提供了以下三个方法供框架使用。
/**
* Extension of the {@link InstantiationAwareBeanPostProcessor} interface,
* adding a callback for predicting the eventual type of a processed bean.
*
* <p><b>NOTE:</b> This interface is a special purpose interface, mainly for
* internal use within the framework. In general, application-provided
* post-processors should simply implement the plain {@link BeanPostProcessor}
* interface or derive from the {@link InstantiationAwareBeanPostProcessorAdapter}
* class. New methods might be added to this interface even in point releases.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see InstantiationAwareBeanPostProcessorAdapter
*/
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
/**
* Predict the type of the bean to be eventually returned from this
* processor's {@link #postProcessBeforeInstantiation} callback.
* @param beanClass the raw class of the bean
* @param beanName the name of the bean
* @return the type of the bean, or {@code null} if not predictable
* @throws org.springframework.beans.BeansException in case of errors
*/
Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException;
/**
* Determine the candidate constructors to use for the given bean.
* @param beanClass the raw class of the bean (never {@code null})
* @param beanName the name of the bean
* @return the candidate constructors, or {@code null} if none specified
* @throws org.springframework.beans.BeansException in case of errors
*/
Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException;
/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
* <p>This callback gives post-processors a chance to expose a wrapper
* early - that is, before the target bean instance is fully initialized.
* The exposed object should be equivalent to the what
* {@link #postProcessBeforeInitialization} / {@link #postProcessAfterInitialization}
* would expose otherwise. Note that the object returned by this method will
* be used as bean reference unless the post-processor returns a different
* wrapper from said post-process callbacks. In other words: Those post-process
* callbacks may either eventually expose the same reference or alternatively
* return the raw bean instance from those subsequent callbacks (if the wrapper
* for the affected bean has been built for a call to this method already,
* it will be exposes as final bean reference by default).
* @param bean the raw bean instance
* @param beanName the name of the bean
* @return the object to expose as bean reference
* (typically with the passed-in bean instance as default)
* @throws org.springframework.beans.BeansException in case of errors
*/
Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;
}
/**
* Post-processor callback interface for <i>merged</i> bean definitions at runtime.
* {@link BeanPostProcessor} implementations may implement this sub-interface in order
* to post-process the merged bean definition (a processed copy of the original bean
* definition) that the Spring {@code BeanFactory} uses to create a bean instance.
*
* <p>The {@link #postProcessMergedBeanDefinition} method may for example introspect
* the bean definition in order to prepare some cached metadata before post-processing
* actual instances of a bean. It is also allowed to modify the bean definition but
* <i>only</i> for definition properties which are actually intended for concurrent
* modification. Essentially, this only applies to operations defined on the
* {@link RootBeanDefinition} itself but not to the properties of its base classes.
*
* @author Juergen Hoeller
* @since 2.5
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getMergedBeanDefinition
*/
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
/**
* Post-process the given merged bean definition for the specified bean.
* @param beanDefinition the merged bean definition for the bean
* @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}
MergedBeanDefinitionPostProcessor
提供了运行时处理merged bean definitions的能力。这三个类的典型实现是RequiredAnnotationBeanPostProcessor
和AutowiredAnnotationBeanPostProcessor
,用于处理@Requied
和@Autowired
、@Value
注解。
/**
* Subinterface of {@link BeanPostProcessor} that adds a before-destruction callback.
*
* <p>The typical usage will be to invoke custom destruction callbacks on
* specific bean types, matching corresponding initialization callbacks.
*
* @author Juergen Hoeller
* @since 1.0.1
*/
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given bean instance before
* its destruction. Can invoke custom destruction callbacks.
* <p>Like DisposableBean's {@code destroy} and a custom destroy method,
* this callback just applies to singleton beans in the factory (including
* inner beans).
* @param bean the bean instance to be destroyed
* @param beanName the name of the bean
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.DisposableBean
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#setDestroyMethodName
*/
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
/**
* Determine whether the given bean instance requires destruction by this
* post-processor.
* <p><b>NOTE:</b> Even as a late addition, this method has been introduced on
* {@code DestructionAwareBeanPostProcessor} itself instead of on a SmartDABPP
* subinterface. This allows existing {@code DestructionAwareBeanPostProcessor}
* implementations to easily provide {@code requiresDestruction} logic while
* retaining compatibility with Spring <4.3, and it is also an easier onramp to
* declaring {@code requiresDestruction} as a Java 8 default method in Spring 5.
* <p>If an implementation of {@code DestructionAwareBeanPostProcessor} does
* not provide a concrete implementation of this method, Spring's invocation
* mechanism silently assumes a method returning {@code true} (the effective
* default before 4.3, and the to-be-default in the Java 8 method in Spring 5).
* @param bean the bean instance to check
* @return {@code true} if {@link #postProcessBeforeDestruction} is supposed to
* be called for this bean instance eventually, or {@code false} if not needed
* @since 4.3
*/
boolean requiresDestruction(Object bean);
}
DestructionAwareBeanPostProcessor
提供了Bean销毁之前的回调方法void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
其典型实现有ApplicationListenerDetector
用于处理ApplicationListener的添加和销毁、InitDestroyAnnotationBeanPostProcessor
用于处理@PostConstruct
和@PreDestroy
、ScheduledAnnotationBeanPostProcessor
用于处理@Scheduled
注解。
注册时机
BeanPostProcessor
的运行机制是先注册,后使用。注册是在AbstractApplicationContext#refresh
方法中。使用就是在Bean对象的初始化前后进行使用。
registerBeanPostProcessors方法委托给PostProcessorRegistrationDelegate#registerBeanPostProcessors(ConfigurableListableBeanFactory,AbstractApplicationContext)
。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(beanFactory, internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
按照实现了以下接口PriorityOrdered、Ordered和无顺序接口分别进行注册,其中实现了MergedBeanDefinitionPostProcessor
接口的还额外添加了一次。最后添加了一个ApplicationListenerDetector
,用于获取容器中的ApplicationListener进行注册。添加方法使用BeanFactory#addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
。此时容器中已经保存的是BeanPostProcessor
的实例,因为已经调用BeanFactory#getBean
方法。关于MergedBeanDefinitionPostProcessor
接口,虽然通过internalPostProcessors重新添加了一次,但是并不会重复添加,因为addBeanPostProcessor方法是先remove,再add,这些BeanPostProcessor
就会添加到最后。
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
介入时机
经过以上的步骤,此时容器中已经包含了所有的BeanPostProcessor
,在其他Bean创建的时候,这些BeanPostProcessor
就会介入工作。
在AbstractAutowireCapableBeanFactory#createBean
方法中,首先给InstantiationAwareBeanPostProcessor一个机会创建对象的代理。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
首先调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation创建对象,不为空则直接返回,所以,最多只有一个InstantiationAwareBeanPostProcessor会起作用。然后调用所有的BeanPostProcessor
的postProcessAfterInitialization方法。
如果以上方法返回null,则说明需要走Bean创建流程,就调用AbstractAutowireCapableBeanFactory#doCreateBean
方法。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
创建BeanWrapper
(这个类是对Bean实例的一次封装)之后。应用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
再给一次机会修改BeanDefinition
。
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
populateBean(beanName, mbd, instanceWrapper);
对Bean进行属性赋值,这个方法中如果有InstantiationAwareBeanPostProcessor
,会调用postProcessAfterInstantiation方法和postProcessPropertyValues方法。
之后进行对象的初始化,首先如果Bean实现了BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
,则分别注入这些,然后在初始化方法调用前后应用BeanPostProcessor#postProcessBeforeInitialization
、BeanPostProcessor#postProcessAfterInitialization
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}