美文网首页
Spring bean生命周期

Spring bean生命周期

作者: 雪飘千里 | 来源:发表于2019-12-19 12:10 被阅读0次

1、Bean实例生命周期

image.png image.png image.png

Bean实例生命周期的执行过程如下:

1、Spring对bean进行实例化(调用构造函数),默认bean是单例;

2、通过set方法设置对象属性;

3、检查Aware相关接口,并设置相关依赖

  • 3.1 如果bean实现了BeanNameAware接口,spring将bean的id传给setBeanName()方法;

  • 3.2 如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory方法,将BeanFactory实例传进来;

  • 3.3 如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;
    ——我们在项目中通常需要一个Bean上下文工具类SpringUtil.class,用来通过名称获取bean,这时我们就可以通过SpringUtil implements ApplicationContextAware来获取ApplicationContext上下文,然后通过ApplicationContext来获取bean,例子见后面代码

4、BeanPostProcessor前置处理
如果bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization方法将被调用;

5、如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet接口方法;

6、如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;

7、BeanPostProcessor后置处理
如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法将被调用;

BeanPostProcessor 称之为bean的加工器,主要是在bean完成初始化之后,准备执行默认方法的前后对bean进行包装,即允许我们对bean实例进行自定义的修改,比如注入属性和完善配置,例子见后面代码

8、如果该Bean是单例singleton的,则将Bean放到Spring 缓冲池中;如果该Bean是多例prototype,则将准备好的Bean提交给调用者,后续不再管理该Bean的生命周期。

执行到这里时,bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中(spring 缓存池),直到该应用上下文被销毁;

9、销毁
当bean的应用上下文springApplicationContent(spring 缓存池)销毁时,bean销毁,
这时如果有bean实现了DisposableBean接口,spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用;

2、spring bean 注册到 IOC容器的过程

image.png
  • 1、读取bean配置信息(通过xml中<bean> ,或者通过注解@Autowrite @Configuration),根据配置信息,在容器内部建立Bean定义注册表
  • 2、根据bean注册表实例化bean
  • 3、将bean实例放到spring容器中(spring容器中有一个Bean缓存池)
  • 4、使用bean

3、SpringUtil工具类

package com.xxx.web.util;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public final class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;; // Spring应用上下文环境

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContext = applicationContext;
    }

    /**
     * 获取对象
     *
     * @param name
     * @return Object 一个以所给名字注册的bean的实例
     * @throws BeansException
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) throws BeansException {
        return (T) applicationContext.getBean(name);
    }

    /**
     * 获取类型为requiredType的对象
     *
     * @param clz
     * @return
     * @throws BeansException
     *
     */
    public static <T> T getBean(Class<T> clz) throws BeansException {
        @SuppressWarnings("unchecked")
        T result = (T) applicationContext.getBean(clz);
        return result;
    }

    /**
     * 如果applicationContext包含一个与所给名称匹配的bean定义,则返回true
     *
     * @param name
     * @return boolean
     */
    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }

    /**
     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
     *
     * @param name
     * @return boolean
     * @throws NoSuchBeanDefinitionException
     *
     */
    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
        return applicationContext.isSingleton(name);
    }

    /**
     * @param name
     * @return Class 注册对象的类型
     * @throws NoSuchBeanDefinitionException
     *
     */
    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
        return applicationContext.getType(name);
    }

    /**
     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
     *
     * @param name
     * @return
     * @throws NoSuchBeanDefinitionException
     *
     */
    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
        return applicationContext.getAliases(name);
    }

}

4、BeanPostProcessor使用

注入属性,如果bean属于ServiceBean,则把其属性dynamic设置为true

package com.xxx.processor;

import org.apache.dubbo.config.spring.ServiceBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * Description:修复dubbo2.7.1 zk 注册服务为 持久化节点问题
 * Date:2019/5/7
 */
@Component
public class ServiceBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(ServiceBean.class.isInstance(bean)){
            ((ServiceBean)bean).setDynamic(Boolean.TRUE);
        }
        return bean;
    }
}

相关文章

网友评论

      本文标题:Spring bean生命周期

      本文链接:https://www.haomeiwen.com/subject/bwwunctx.html