尸酒岐 发表于 2025-11-13 21:35:02

Spring BeanPostProcessor接口

[]
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 还细分一些子接口:

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}
                       * 关于它们的作用见笔记 []
                       */
                        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)
                       *            - 工厂方法实例化 ('静态工厂' '实例工厂' )
                       *              `<beanfactory-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;
        }
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

湄圳啸 发表于 2025-11-19 23:46:31

喜欢鼓捣这些软件,现在用得少,谢谢分享!

任俊慧 发表于 2025-12-2 00:00:19

感谢发布原创作品,程序园因你更精彩

卜笑 发表于 前天 10:34

感谢分享
页: [1]
查看完整版本: Spring BeanPostProcessor接口