Spring BeanFactory 生命周期

首先放一张图:

aac6e4df26a9e72accfa7ce28aedc7d8278.jpg

 

说明:

1.对于spring的BeanFactory生命周期.我们可以根据bean的创建来定制化实现我们需要的功能.

容器后处理器定制化使用方法:

@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {


    /**
     * 预测最终从此返回的bean的类型
     * 处理器的{@link #postProcessBeforeInstantiation}回调。
     * <p>默认实现返回{@code null}。</p>
     *
     * @param beanClass bean的原始类
     * @param beanName  bean的名称
     * @return bean的类型,如果不可预测,则返回{@code null}
     * @throws org.springframework.beans.BeansException,发成错误抛出
     */
    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
        if ("userService".equals(beanName))
            System.out.println("开始调用:predictBeanType" + beanClass.getName() + "--->" + beanName);
        return super.predictBeanType(beanClass, beanName);
    }

    /**
     * 确定用于给定bean的候选构造函数。
     * <p>默认实现返回{@code null}。</p>
     *
     * @param beanClass bean的原始类(从不{@code null})
     * @param beanName  bean的名称
     * @return 候选构造函数,如果没有指定,则为{@code null}
     * @throws org.springframework.beans.BeansException,如果有错误
     */
    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("开始调用:determineCandidateConstructors" + beanName);
        return super.determineCandidateConstructors(beanClass, beanName);
    }

    /**
     * 获取早期访问指定bean的引用,
     * 通常用于解析循环引用。
     * <p>此回调使后处理器有机会公开包装器早期 - 也就是说,在目标bean实例完全初始化之前,暴露的物体应该等同于什么</p>
     * {@link #postProcessBeforeInitialization}或{@link #postProcessAfterInitialization}
     * 否则会暴露。请注意,此方法返回的对象将是
     * 用作bean引用,除非后处理器返回不同的内容
     * 来自所述后处理回调的包装器。换句话说:那些后期处理
     * 回调可能最终暴露相同的引用或者替代
     * 从后续回调中返回原始bean实例(如果是包装器
     * 已经构建了受影响的bean,用于调用此方法,
     * 默认情况下它将作为最终bean引用公开)。
     * <p>默认实现按原样返回给定的{@code bean}。</p>
     *
     * @param bean     原始bean实例
     * @param beanName bean的名称
     * @return 将对象公开为bean引用 (通常使用传入的bean实例作为默认值)
     * @throws org.springframework.beans.BeansException,如果有错误
     */
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("开始调用:getEarlyBeanReference" + beanName);
        return super.getEarlyBeanReference(bean, beanName);
    }


    /**
     * 在目标bean实例化之前应用此BeanPostProcessor 。
     * 返回的bean对象可以是代替目标bean使用的代理,有效地抑制目标bean的默认实例化。
     * <p>如果此方法返回非null对象,则为bean创建过程将被短路。应用的唯一进一步处理是</p>
     * {@link #postProcessAfterInitialization}来自配置的回调
     * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors}。
     * <p>此回调仅适用于具有bean类的bean定义。
     * 特别是,它不会应用于具有工厂方法的bean。
     * </p>后处理器可以实现扩展
     * {@link org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor}接口按顺序排列
     * 预测它们将在这里返回的bean对象的类型。
     * <p>默认实现返回{@code null}。</p>
     *
     * @param beanClass 要实例化的bean的类
     * @param beanName  bean的名称
     * @return bean对象公开而不是目标bean的默认实例或{@code null}继续进行默认实例化
     * @throws org.springframework.beans.BeansException,如果有错误
     * @see #postProcessAfterInstantiation
     * @see org.springframework.beans.factory.support.AbstractBeanDefinition #hasBeanClass
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("开始调用:postProcessBeforeInstantiation" + beanName);
        return super.postProcessBeforeInstantiation(beanClass, beanName);
    }


    /**
     * 通过构造函数或工厂方法实例化bean之后执行操作,
     * 但是在Spring属性人口(来自显式属性或自动装配)之前发生。
     * <p>这是在给定bean上执行自定义字段注入的理想回调
     * 实例,就在Spring的自动装配开始之前。
     * </p>默认实现返回{@code true}。
     *
     * @param bean     创建的bean实例,其属性尚未设置
     * @param beanName bean的名称
     * @return {@code true}如果要在bean上设置属性; {@code false}
     * 如果应该跳过财产人口。 正常实现应返回{@code true}。
     * 返回{@code false}也会阻止任何后续的 InstantiationAwareBeanPostProcessor
     * 在此bean实例上调用实例。
     * @throws org.springframework.beans.BeansException,如果有错误
     * @see #postProcessBeforeInstantiation
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("开始调用:postProcessAfterInstantiation" + beanName);
        return super.postProcessAfterInstantiation(bean, beanName);
    }


    /**
     * 在工厂应用之前对给定的属性值进行后处理
     * 到给定的bean,不需要属性描述符。
     * <p>如果实现提供自定义,则实现应返回{@code null}(默认值)</p>
     * {@link #postProcessPropertyValues}实现,否则{@code pvs}。
     * 在此界面的未来版本中(删除了{@link #postProcessPropertyValues}),
     * 默认实现将直接返回给定的{@code pvs}。
     *
     * @param pvs      工厂即将应用的属性值(从不{@code null})
     * @param bean     创建了bean实例,但其属性尚未设置
     * @param beanName bean的名称
     * @return 要应用于给定bean的实际属性值(可以是传入的 PropertyValues实例),或{@code null}继续使用现有属性
     * 但特别是继续调用{@link #postProcessPropertyValues}(要求为当前bean类初始化{@code PropertyDescriptor})
     * @throws org.springframework.beans.BeansException,如果有错误
     * @see #postProcessPropertyValues
     * @since 5.1
     */
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("开始调用:postProcessPropertyValues" + beanName);
        return super.postProcessPropertyValues(pvs, pds, bean, beanName);
    }


    /**
     * 在任何bean之前,将此BeanPostProcessor应用于给定的新bean实例
     * 初始化回调(如InitializingBean的{@code afterPropertiesSet}或自定义init方法)。 bean已经填充了属性值。
     * 返回的bean实例可能是原始实例的包装器。
     * <p>默认实现按原样返回给定的{@code bean}。</p>
     *
     * @param bean     新的bean实例
     * @param beanName bean的名称
     * @return 要使用的bean实例,无论是原始实例还是包装实例; 如果{@code null},则不会调用后续的BeanPostProcessors
     * @throws org.springframework.beans.BeansException,如果有错误
     * @see org.springframework.beans.factory.InitializingBean #afterPropertiesSet
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("开始调用:postProcessBeforeInitialization" + beanName);
        return super.postProcessBeforeInitialization(bean, beanName);
    }


    /**
     * 在任何bean之后,将此BeanPostProcessor应用于给定的新bean实例
     * 初始化回调(如InitializingBean的{@code afterPropertiesSet}或自定义init方法)。 bean已经填充了属性值。
     * 返回的bean实例可能是原始实例的包装器。
     * <p>如果是FactoryBean,将为FactoryBean调用此回调实例和FactoryBean创建的对象(从Spring 2.0开始)。
     * 该后处理器可以决定是应用于FactoryBean还是创建
     * 对象或两者通过相应的{@code bean instanceof FactoryBean}检查。</p>
     * <p>在a触发短路后也会调用此回调</p>
     * {@link org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}方法,与所有其他BeanPostProcessor回调相反。
     * <p>默认实现按原样返回给定的{@code bean}。</p>
     *
     * @param bean     新的bean实例
     * @param beanName bean的名称
     * @return 要使用的bean实例,无论是原始实例还是包装实例;
     * 如果{@code null},则不会调用后续的BeanPostProcessors
     * @throws org.springframework.beans.BeansException,如果有错误
     * @see org.springframework.beans.factory.InitializingBean #afterPropertiesSet
     * @see org.springframework.beans.factory.FactoryBean
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("开始调用:postProcessAfterInitialization" + beanName);
        return super.postProcessAfterInitialization(bean, beanName);
    }
}

 

整理一下:

bean生命周期接口有:

BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean

bean容器后处理器一般继承:

InstantiationAwareBeanPostProcessorAdapter

 

简要描述就是,启动容器: 预测bean返回的类型 --> 实例化前处理 --> 确定bean构造函数  --> 构造bean --> 实例化后处理 --> 设置bean属性值 --> 调用bean初始化的生命周期接口 --> spring缓存池准备就绪. --> 调用bean生命周期的销毁方法 -> 销毁.

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/lmxy1990/blog/3035899

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值