Spring BeanPostProcessor接口

[[Spring IOC 源码学习总笔记]]

BeanPostProcessor

BeanPostProcessor是 Spring 框架提供的一个扩展点接口,它允许开发者在 Spring 容器完成 Bean 的实例化、依赖注入之后,在初始化阶段的前后“拦截”并自定义 Bean 的逻辑。

package org.springframework.beans.factory.config;  import org.springframework.beans.BeansException; import org.springframework.lang.Nullable;  public interface BeanPostProcessor {  	/** 	 * Apply this {@code 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. 	 * <p>The default implementation returns the given {@code bean} as-is. 	 * 	 *这个是在 Bean 实例化并且填充属性之后调用, 但是 Bean 中一些生命周期方法如 InitializingBean 接口的 	 * afterPropertiesSet 方法、自定义的 init-method 方法等都尚未执行,在这些方法执行之前触发 postProcessBeforeInitialization 方法。 	 * 	 * @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 	 */ 	@Nullable 	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 		return bean; 	}  	/** 	 * Apply this {@code 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 {@code BeanPostProcessor} callbacks. 	 * <p>The default implementation returns the given {@code bean} as-is. 	 *  	 *  在 InitializingBean 接口的 afterPropertiesSet 和自定义的 init-method 之后触发该方法。 	 * 	 * @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 	 */ 	@Nullable 	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 		return bean; 	}  }  

接口中的两个方法都要将传入的 bean 返回,而不能返回 null,如果返回的是 null 那么我们通过 getBean() 方法将得不到目标对象。
可见:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization 的源码调用逻辑

@Deprecated(since = "6.1") @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) 		throws BeansException {  	Object result = existingBean; 	for (BeanPostProcessor processor : getBeanPostProcessors()) { 		Object current = processor.postProcessBeforeInitialization(result, beanName); 		if (current == null) { 			return result; 		} 		result = current; 	} 	return result; }  

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

 @Deprecated(since = "6.1") @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 		throws BeansException {  	Object result = existingBean; 	for (BeanPostProcessor processor : getBeanPostProcessors()) { 		Object current = processor.postProcessAfterInitialization(result, beanName); 		if (current == null) { 			return result; 		} 		result = current; 	} 	return result; }  

BeanPostProcessor 的子接口

另外 BeanPostProcessor 粗粒度太大, Spring 还细分一些子接口:

Spring BeanPostProcessor接口

AutowiredAnnotationBeanPostProcessor

@Autowired、@Inject 等就是根据这个回调来实现最终注入依赖的属性的。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { 	// BeanPostProcessor 接口方法 	@Nullable 	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { 		return null; 	} 	// BeanPostProcessor 接口方法 	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { 		return true; 	}  	/** 	 * Post-process the given property values before the factory applies them 	 * to the given bean. 	 * <p>The default implementation returns the given {@code pvs} as-is. 	 * 	 * 将给定的属性值应用到指定的bean之前进行回调 	 * 可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中 	 * 	`@Autowired、@Resource` 在Spring中 就是根据这个回调来实现最终注入依赖的属性的 	 * 	 	 * @param pvs the property values that the factory is about to apply (never {@code null}) 	 * @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 	 * @since 5.1 	 */ 	@Nullable 	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) 			throws BeansException { 		return pvs; 	}  } 

postProcessProperties 在哪里调用呢?

相关源码

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 填充Bean属性方法

/** 	 * Populate the bean instance in the given BeanWrapper with the property values 	 * from the bean definition. 	 * @param beanName the name of the bean 	 * @param mbd the bean definition for the bean 	 * @param bw the BeanWrapper with bean instance 	 */ 	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { 		// 验证一下入参 		if (bw == null) { 			if (mbd.hasPropertyValues()) { 				throw new BeanCreationException( 						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); 			} 			else { 				// Skip property population phase for null instance. 				return; 			} 		}  		if (bw.getWrappedClass().isRecord()) { 			if (mbd.hasPropertyValues()) { 				throw new BeanCreationException( 						mbd.getResourceDescription(), beanName, "Cannot apply property values to a record"); 			} 			else { 				// Skip property population phase for records since they are immutable. 				return; 			} 		}  		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the 		// state of the bean before properties are set. This can be used, for example, 		// to support styles of field injection. 		/** 		 * 如果是AOP, pointcut, advice相关的, synthetic 会配置为 true 		 */ 		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { 				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { 					return; 				} 			} 		} 		/** 		 * 包含一个或多个{@link PropertyValue}对象的Holder,通常针对特定目标bean的一次更新 		 * 可以理解为: 该bean所有属性的描述 		 */ 		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);  		/** 		 * 获取自动注入的方式 		 */ 		int resolvedAutowireMode = mbd.getResolvedAutowireMode(); 		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { 			/** 			 * 该分支处理通过 名称或者类型 注入的属性 			 * (有注解才会走这个分支) 			 * =============================== 			 */ 			MutablePropertyValues newPvs = new MutablePropertyValues(pvs); 			// Add property values based on autowire by name if applicable. 			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { 				/** 				 * 通过名称注入 				 */ 				autowireByName(beanName, mbd, bw, newPvs); 			} 			// Add property values based on autowire by type if applicable. 			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { 				/** 				 * 通过类型注入 				 */ 				autowireByType(beanName, mbd, bw, newPvs); 			} 			pvs = newPvs; 		} 		/** 		 *  <!> 回调所有 InstantiationAwareBeanPostProcessor#postProcessProperties 方法 		 *  比如, `@Autowired` 的处理对应实现类: {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor} 		 *  (作用是: 在工厂将属性值应用到给定bean之前,对它们进行处理) 		 * 		 */ 		if (hasInstantiationAwareBeanPostProcessors()) { 			if (pvs == null) { 				pvs = mbd.getPropertyValues(); 			} 			// <!> 回调InstantiationAwareBeanPostProcessor#postProcessProperties 方法 			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { 				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); 				if (pvsToUse == null) { 					return; 				} 				pvs = pvsToUse; 			} 		}  .... 

<!> 回调InstantiationAwareBeanPostProcessor#postProcessProperties 方法

后面注入在: org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties

@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { 	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); 	try { 		// 注入 		metadata.inject(bean, beanName, pvs); 	} 	catch (BeanCreationException ex) { 		throw ex; 	} 	catch (Throwable ex) { 		throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); 	} 	return pvs; } 

InstantiationAwareBeanPostProcessor & SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor 它提供了更高级的Bean实例化控制方法。主要作用在于允许对Bean的实例化过程进行更精细的控制和定制。

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {     //用来返回目标对象的类型(比如代理对象通过raw class获取proxy type 用于类型匹配)     @Nullable     default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {         return null;     }     //这里提供一个拓展点用来解析获取用来实例化的构造器(比如未通过bean定义构造器以及参数的情况下,会根据这个回调来确定构造器)     @Nullable     default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)             throws BeansException {         return null;     }     //获取要提前暴露的bean的引用,用来支持单例对象的循环引用(一般是bean自身,如果是代理对象则需要取用代理引用)     default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {         return bean;     } } 

相关源码

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

 	@Override 	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 			throws BeanCreationException {  		if (logger.isTraceEnabled()) { 			logger.trace("Creating instance of bean '" + beanName + "'"); 		} 		RootBeanDefinition mbdToUse = mbd; 		/** 		 * 1. 解析到 BeanDefinition 的 Class 		 */ 		Class<?> resolvedClass = resolveBeanClass(mbd, beanName); 		/** 		 * 2. 创建BeanDefinition 复制一份 RootBeanDefinition 		 */ 		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { 			mbdToUse = new RootBeanDefinition(mbd); 			mbdToUse.setBeanClass(resolvedClass); 		} 		// Prepare method overrides. 		try { 			/** 			 * 3. 准备和验证 lookup-method 和 replace-method; 			 * 注意: 这里只是标记, 真正处理是在实例化时, 选择策略生成一个CgLib的代理对象 {@link org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy} 			 * 关于它们的作用见笔记 [[Spring lookup-method 和 replace-method.md]] 			 */ 			mbdToUse.prepareMethodOverrides(); 		} 		catch (BeanDefinitionValidationException ex) { 			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), 					beanName, "Validation of method overrides failed", ex); 		}  		try { 			/** 			 * 给 BeanPostProcessors 一个返回代理实例的机会; 			 * 注意, 这里的逻辑: 			 * 如果其 BeanPostProcessors的子接口返回不为null, 则直接使用这个bean实例返回了, 不走 doCreateBean流程了 			 * (注意的注意! 如果有用户自定义的拦截创建, 甚至优先Spring的AOP代理创建) 			 */ 			Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 			if (bean != null) { 				return bean; 			} 		} 		catch (Throwable ex) { 			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 					"BeanPostProcessor before instantiation of bean failed", ex); 		} 

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

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. 		// 如果是合成的(mbd是AOP的时候,为true)并且实现 InstantiationAwareBeanPostProcessor 接口 		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 			Class<?> targetType = determineTargetType(beanName, mbd); 			if (targetType != null) { 				// 使用 InstantiationAwareBeanPostProcessor接口 生成的 bean 返回 				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); 				if (bean != null) { 					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); 				} 			} 		} 		mbd.beforeInstantiationResolved = (bean != null); 	} 	return bean; } 

DestructionAwareBeanPostProcessor

DestructionAwareBeanPostProcessor 它允许在Bean被销毁之前(例如,容器关闭或特定作用域的Bean销毁)执行一些操作。

org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {          //这里实现销毁对象的逻辑     void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;          //判断是否需要处理这个对象的销毁     default boolean requiresDestruction(Object bean) {         return true;     } } 

MergedBeanDefinitionPostProcessor

MergedBeanDefinitionPostProcessor 算是整个 BeanPostProcessor 家族中比较另类的一个接口了,它虽然是 BeanPostProcessor,但是却可以处理 BeanDefinition。
MergedBeanDefinitionPostProcessor 介入的时机就是 Bean 创建成功之后,Bean 中各个属性填充之前。

相关源码

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 			throws BeanCreationException {  		// Instantiate the bean. 		BeanWrapper instanceWrapper = null; 		if (mbd.isSingleton()) { 			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 		} 		if (instanceWrapper == null) { 			/** 			 *  1. 真正在jvm层面实例化对象; 			 *    1.1 如果该 BeanDefinition 有配置 instanceSupplier属性(java.util.function.Supplier), 			 * 		 将使用其Supplier#get方法的返回, 作为实例对象 			 *    1.2 如果该 BeanDefinition 有配置 factory-method 将使用该方法返回的, 作为实例对象 			 * 		 这里这里包括'静态工厂'和'实例工厂'的处理(通过bd的factoryBeanName 进行判断, 如果存在则是'实例工厂') 			 * 	  1.3 使用反射实例化, 根据策略实例化Bean对象 {@link org.springframework.beans.factory.support.SimpleInstantiationStrategy} 			 * 	   - 使用有参构造函数注入,创建 (new) 			 * 	   - 使用无参构造函数创建 (new) 			 * 	   - 工厂方法实例化 ('静态工厂' '实例工厂' ) 			 * 	     `<bean  factory-bean="bookFactoryBean"  factory-method="getBook()"/>` 			 * 	        静态工厂: factory-bean 若是 全限定类名 则使用 BookFactoryBean::getBook 的静态方法返回的对象 			 * 	        实例工厂:  factory-bean 若是 bean 名 则使用该实例方法返回的对象 			 * 	{@link AbstractAutowireCapableBeanFactory#createBeanInstance(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])} 			 *  2. 用BeanWrapper 包装原始bean (装饰模式) 			 * {@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition)} 			 * 			 */ 			instanceWrapper = createBeanInstance(beanName, mbd, args); 		} 		/** 		 * 获取 BeanWrapper中的原始 Bean 实例 		 */ 		Object bean = instanceWrapper.getWrappedInstance(); 		/** 		 * 获取Bean Class类型 		 */ 		Class<?> beanType = instanceWrapper.getWrappedClass(); 		if (beanType != NullBean.class) { 			mbd.resolvedTargetType = beanType; 		}  		// Allow post-processors to modify the merged bean definition. 		synchronized (mbd.postProcessingLock) { 			if (!mbd.postProcessed) { 				try { 					/** 					 * 实例化完了, 处理 MergedBeanDefinitionPostProcessor 的接口回调 					 */ 					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 				} 				catch (Throwable ex) { 					throw new BeanCreationException(mbd.getResourceDescription(), beanName, 							"Post-processing of merged bean definition failed", ex); 				} 				mbd.markAsPostProcessed(); 			} 		}  		// 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.isTraceEnabled()) { 				logger.trace("Eagerly caching bean '" + beanName + 						"' to allow for resolving potential circular references"); 			} 			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 		}  		// Initialize the bean instance. 		Object exposedObject = bean; 		try { 			/** 			 * 填充属性 			 */ 			populateBean(beanName, mbd, instanceWrapper); 			exposedObject = initializeBean(beanName, exposedObject, mbd); 		}  ..... 

处理 init-method, @PostConstruct, @PreDestroy

对应子类 org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor

注意: 这里只是查询到封装为元信息保存到 BeanDefinition, 还不会调用
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#findLifecycleMetadata(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Class<?>)

private LifecycleMetadata findLifecycleMetadata(RootBeanDefinition beanDefinition, Class<?> beanClass) {   /** 查找相应的注解方法信息, 封装为 LifecycleMetadata 元数据(使用集合存起来包含: initMethods 列表,destroyMethods列表...)   */    LifecycleMetadata metadata = findLifecycleMetadata(beanClass);   /** 再将这些 LifecycleMetadata 元数据, 注册(修改)到 BeanDefinition 中 beanDefinition.registerExternallyManagedInitMethod(methodIdentifier); beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);  **/    metadata.checkInitDestroyMethods(beanDefinition);      return metadata;   }  

处理 @Autowired

对应子类 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

注意: 这里只是查询到封装为元信息保存到 BeanDefinition, 还不会调用

雷同的逻辑
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findInjectionMetadata

	private InjectionMetadata findInjectionMetadata(String beanName, Class<?> beanType, RootBeanDefinition beanDefinition) { 		// 查找  注解方法信息, 封装为元数据对象 		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); 		// 注册(修改)到 BeanDefinition 中 		metadata.checkConfigMembers(beanDefinition); 		return metadata; 	}  

发表评论

评论已关闭。

相关文章