Spring BeanFactory lifecycle

Posted by jkatcherny on Fri, 29 Nov 2019 15:58:52 +0100

Put a picture first:

 

Explain:

1. For the BeanFactory life cycle of spring, we can customize and implement the functions we need according to the creation of beans

Customized usage of container post processor:

@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {


    /**
     * Predict the type of bean s that will eventually be returned from this
     * The {@ link ා postprocessbeforeinstance} callback of the processor.
     * <p>The default implementation returns {@ code null}. </p>
     *
     * @param beanClass bean Primitive class
     * @param beanName  bean Name
     * @return bean If it is not predictable, {@ code null} will be returned
     * @throws org.springframework.beans.BeansException,Send as error throw
     */
    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
        if ("userService".equals(beanName))
            System.out.println("Start calling:predictBeanType" + beanClass.getName() + "--->" + beanName);
        return super.predictBeanType(beanClass, beanName);
    }

    /**
     * Determines the candidate constructor to use for the given bean.
     * <p>The default implementation returns {@ code null}. </p>
     *
     * @param beanClass bean The original class of (never {@ code null})
     * @param beanName  bean Name
     * @return Candidate constructor, {@ code null} if not specified
     * @throws org.springframework.beans.BeansException,If there is an error
     */
    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("Start calling:determineCandidateConstructors" + beanName);
        return super.determineCandidateConstructors(beanClass, beanName);
    }

    /**
     * Gets a reference to an earlier access to a specified bean,
     * Typically used to resolve circular references.
     * <p>This callback gives the postprocessor the opportunity to expose the wrapper early - that is, what the exposed object should be equivalent to before the target bean instance is fully initialized</p>
     * {@link #postProcessBeforeInitialization}Or {@ link ා postprocessafterinitialization}
     * Otherwise, it will be exposed. Note that the object returned by this method will be
     * Use as a bean reference unless the postprocessor returns different content
     * A wrapper from the post-processing callback. In other words: those post-processing
     * The callback may eventually expose the same reference or override
     * Returns the original bean instance (in the case of a wrapper) from a subsequent callback
     * The affected bean has been built to call this method,
     * By default, it will be exposed as the final bean reference).
     * <p>The default implementation returns the given {@ code bean} as is. </p>
     *
     * @param bean     Original bean instance
     * @param beanName bean Name
     * @return Expose the object as a bean reference (usually using the incoming bean instance as the default)
     * @throws org.springframework.beans.BeansException,If there is an error
     */
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("Start calling:getEarlyBeanReference" + beanName);
        return super.getEarlyBeanReference(bean, beanName);
    }


    /**
     * Apply this BeanPostProcessor before the target bean is instantiated.
     * The returned bean object can be a proxy instead of the target bean, which effectively suppresses the default instantiation of the target bean.
     * <p>If this method returns a non null object, the creation process for the bean will be short circuited. The only further processing of the application is</p>
     * {@link #postProcessAfterInitialization}Callback from configuration
     * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors}. 
     * <p>This callback only applies to bean definitions with bean classes.
     * In particular, it does not apply to bean s with factory methods.
     * </p>Postprocessor can realize expansion
     * {@link org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor}Interfaces in order
     * Predict the type of bean objects they will return here.
     * <p>The default implementation returns {@ code null}. </p>
     *
     * @param beanClass The class of the bean to instantiate
     * @param beanName  bean Name
     * @return bean Object exposes instead of the default instance of the target bean or {@ code null} continues with the default instantiation
     * @throws org.springframework.beans.BeansException,If there is an error
     * @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("Start calling:postProcessBeforeInstantiation" + beanName);
        return super.postProcessBeforeInstantiation(beanClass, beanName);
    }


    /**
     * The operation is performed after the bean is instantiated through a constructor or factory method,
     * But before the Spring attribute population (from explicit attributes or auto assembly).
     * <p>This is the ideal callback to perform custom field injection on a given bean
     * Instance, just before Spring's automatic assembly starts.
     * </p>The default implementation returns {@ code true}.
     *
     * @param bean     Created bean instance whose properties have not been set
     * @param beanName bean Name
     * @return {@code true}If you want to set properties on a bean; {@ code false}
     * If property population should be skipped. Normal implementation should return {@ code true}.
     * Returning {@ code false} will also block any subsequent instantiation awarebeanpostprocessor
     * Call the instance on this bean instance.
     * @throws org.springframework.beans.BeansException,If there is an error
     * @see #postProcessBeforeInstantiation
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("Start calling:postProcessAfterInstantiation" + beanName);
        return super.postProcessAfterInstantiation(bean, beanName);
    }


    /**
     * Post process the given property value before factory application
     * To the given bean, no property descriptor is required.
     * <p>If the implementation provides customization, the implementation should return {@ code null} (the default)</p>
     * {@link #postProcessPropertyValues}Otherwise {@ code pvs}.
     * In the future version of this interface ({@ link ා (postprocesspropertyvalues}) has been deleted),
     * The default implementation will directly return the given {@ code pvs}.
     *
     * @param pvs      Property value to be applied by factory (never {@ code null})
     * @param bean     bean instance created, but its properties have not been set
     * @param beanName bean Name
     * @return The actual property value to be applied to the given bean, which can be the passed in PropertyValues instance, or {@ code null} to continue using the existing property
     * But in particular, continue to call {@ link {postprocesspropertyvalues} (it is required to initialize {@ code PropertyDescriptor} for the current bean class)
     * @throws org.springframework.beans.BeansException,If there is an error
     * @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("Start calling:postProcessPropertyValues" + beanName);
        return super.postProcessPropertyValues(pvs, pds, bean, beanName);
    }


    /**
     * Apply this BeanPostProcessor to a given new bean instance before any bean
     * Initialize callbacks (such as {@ code afterpropertieset} or custom init methods of InitializingBean). The bean is already populated with property values.
     * The returned bean instance may be the wrapper of the original instance.
     * <p>The default implementation returns the given {@ code bean} as is. </p>
     *
     * @param bean     New bean instance
     * @param beanName bean Name
     * @return The bean instance to be used, whether original or wrapped; if {@ code null}, subsequent BeanPostProcessors will not be called
     * @throws org.springframework.beans.BeansException,If there is an error
     * @see org.springframework.beans.factory.InitializingBean #afterPropertiesSet
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName))
            System.out.println("Start calling:postProcessBeforeInitialization" + beanName);
        return super.postProcessBeforeInitialization(bean, beanName);
    }


    /**
     * After any bean, apply this BeanPostProcessor to the given new bean instance
     * Initialize callbacks (such as {@ code afterpropertieset} or custom init methods of InitializingBean). The bean is already populated with property values.
     * The returned bean instance may be the wrapper of the original instance.
     * <p>In the case of FactoryBean, this callback instance and the objects created by FactoryBean are called for FactoryBean (starting with Spring 2.0).
     * The postprocessor can decide whether to apply or create a FactoryBean
     * Object or both are checked by the corresponding {@ code bean instanceof FactoryBean}. </p>
     * <p>This callback will also be called after a triggers the short circuit</p>
     * {@link org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}Method, as opposed to all other BeanPostProcessor callbacks.
     * <p>The default implementation returns the given {@ code bean} as is. </p>
     *
     * @param bean     New bean instance
     * @param beanName bean Name
     * @return The bean instance to be used, whether it is the original instance or the wrapper instance;
     * If {@ code null}, subsequent BeanPostProcessors will not be called
     * @throws org.springframework.beans.BeansException,If there is an error
     * @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("Start calling:postProcessAfterInitialization" + beanName);
        return super.postProcessAfterInitialization(bean, beanName);
    }
}

 

Sort it out:

The bean lifecycle interfaces are:

BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean

The bean container postprocessor generally inherits:

InstantiationAwareBeanPostProcessorAdapter

 

The brief description is as follows: start the container: predict the type returned by the bean -- > pre instantiation -- > determine the bean constructor -- > construct the bean -- > post instantiation -- > set the bean property value -- > call the life cycle interface of the bean initialization -- > the spring cache pool is ready. -- call the destroy method of the bean life cycle - > destroy

Topics: Programming Spring Attribute