Spring技术原理之Bean生命周期

简介: Spring技术原理之Bean生命周期

生命周期图解



image.png


生命周期举例



public class BeanLifeTest implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
    private String name;
    public BeanLifeTest() {
      System.out.println("第一步:实例化类");
    }
    public void setName(String name) {
      System.out.println("第二步:设置属性");
      this.name = name;
    }
    @Override
    public void setBeanName(String s) {
      System.out.println("第三步:设置bean的名称也就是spring容器中的名称,也就是id值" + s);
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      System.out.println("第四步:获取工厂信息ApplicationContext");
    }
    //第五步执行初始化之前执行的方法
    @Override
    public void afterPropertiesSet() throws Exception {
      System.out.println("第六步:属性设置后执行的方法");
    }
    public void init() {
      System.out.println("第七步:执行自己配置的初始化方法");
  }
    //第八步执行初始化之后执行的方法
    public void start() {
      System.out.println("第九步:执行自身的业务方法");
    }
    @Override
    public void destroy() throws Exception {
      System.out.println("第十步:执行spring的销毁方法");
    }
    public void myDestory() {
      System.out.println("第十一步:执行自己配置的销毁方法");
    }
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("testBeans.xml");
        String[] names = applicationContext.getBeanDefinitionNames();
        Arrays.stream(names).forEach(e -> System.out.println(e));
        BeanLifeTest beanLifeTest = (BeanLifeTest) applicationContext.getBean("testBean");
        beanLifeTest.start();
        ((ClassPathXmlApplicationContext) applicationContext).close();
    }
}
/**
 * @Description bean处理器
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    //后处理bean,最重要的两步
    @Override
    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
        if(bean instanceof BeanLifeTest)
        System.out.println("第五步:初始化之前执行的方法");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
        if(bean instanceof BeanLifeTest)
        System.out.println("第八步:执行初始化之后的方法");
        return bean;
    }
}


ClassPathXmlApplicationContext原理



public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
    private Resource[] configResources;
    public ClassPathXmlApplicationContext() {
    }
  // 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
    public ClassPathXmlApplicationContext(ApplicationContext parent) {
        super(parent);
    }
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {
        super(parent);
         // 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();  //重点!!!
        }
    }
    @Override
    protected Resource[] getConfigResources() {
        return this.configResources;
    }
}
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
    // 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写 
    prepareRefresh();
    // 这步比较重要(解析),告诉子类去刷新bean工厂,这步完成后配置文件就解析成一个个bean定义,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    // 设置beanFactory类加载器,添加多个beanPostProcesser
    prepareBeanFactory(beanFactory);
    try {
        // 允许子类上下文中对beanFactory做后期处理
        postProcessBeanFactory(beanFactory);
        // 调用BeanFactoryPostProcessor各个实现类的方法
        invokeBeanFactoryPostProcessors(beanFactory);
        // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
        registerBeanPostProcessors(beanFactory);
        //初始化ApplicationContext的MessageSource
        initMessageSource();
        //初始化ApplicationContext事件广播器
        initApplicationEventMulticaster();
        // 初始化子类特殊bean(钩子方法)
        onRefresh();
        // 注册事件监听器
        registerListeners();
        // 初始化所有singleton bean  重点!!重点!!
        finishBeanFactoryInitialization(beanFactory);
        // 广播事件,ApplicationContext初始化完成
        finishRefresh();
} catch (BeansException ex) {
}


protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化名字为conversionService的bean
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
        beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
    // 初始化LoadTimeWeaverAware相关bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    // 停止使用临时类加载器进行类型匹配,置null
    beanFactory.setTempClassLoader(null);
    // 冻结(this.configurationFrozen = true;)所有beanDefinition,不让bean继续注册
    beanFactory.freezeConfiguration();
    // 实例化所有剩余的(非延迟-init)单例
    beanFactory.preInstantiateSingletons();
}
//---------------------------------
// 实例化所有剩余的(非延迟-init)单例
public void preInstantiateSingletons() throws BeansException {
    // 拿到所有beanName 去遍历
    //获取所有bean
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    // 触发所有非懒加载的singleton bean的初始化
    for (String beanName : beanNames) {
        //将非RootBeanDefinition转换为RootBeanDefinition以方便后续操作,
        //因为Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
        //合并bean定义
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        //如果当前“不是抽象类 && 是单例 && 不是延迟加载” 则执行
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) { //判断是否factoryBean
                //返回一个共享或独立的实例
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                boolean isEagerInit;
        // ......
                if (isEagerInit) {
                    //返回一个实例
                    getBean(beanName);
                }
            } else {
                getBean(beanName);
            }
        }
    }
   //...
}
//进行实例bean的方法,调用getBean方法最后调到doGetBean
//-返回一个指定bean的实例,无论是共享或独立
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    //去掉beanName前的'&',然后再拿当前beanName去别名aliasMap.get(canonicalName)取
    final String beanName = transformedBeanName(name);
    Object bean;
    // 检查是否已创建过 ,并根据注册给定的名字返回singleton
    Object sharedInstance = getSingleton(beanName);
    //args为空时是获取bean,不为空是创建bean
    if (sharedInstance != null && args == null) { 
        .........................
        //返回对象bean实例,如果是(beanInstance instanceof FactoryBean),则直接返回
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
    //检查当前bean是否已被创建,是则抛异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
        // 检查bean definition是否在该工厂已创建
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 没找到就去找parent容器
            String nameToLookup = originalBeanName(name);
            if (args != null) {
                // 返回父容器(带参数)
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else {
                // 不带参数
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }
        //typeCheckOnly为true时,将指定的bean标记为已创建,添加进Set<String> alreadyCreated中
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }
        try {
            //合并bean定义
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            //检查是否Abstract,是则抛异常
            checkMergedBeanDefinition(mbd, beanName, args);
            // 获取依赖的bean名称
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                //然后遍历传入进行初始化
                for (String dependsOnBean : dependsOn) {
                    //判断循环依赖
                    if (isDependent(beanName, dependsOnBean)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                    }
                    registerDependentBean(dependsOnBean, beanName);
                    //递归获取依赖的bean
                    getBean(dependsOnBean);
                }    
            }
            // 接下来就到了创建一个bean实例的过程,创建单例/多例
            //单例模式bean创建
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    @Override
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        } catch (BeansException ex) {
                            //。。。。。。。。。。。。。。。。
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }  else if (mbd.isPrototype()) {  //多例
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {  //非单例/多例处理
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            } finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    //...........
                }
            }
        } catch (BeansException ex) {
           // ...........
        }
    }
    // 检查所需的类型是否与实际bean实例的类型匹配。不是则抛出异常
    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        } catch (TypeMismatchException ex) {
            .............
        }
        return (T) bean;
    }
}
//AbstractAutowireCapableBeanFactory.createBean利会调用该方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
      throws BeanCreationException {
    //......
    if (instanceWrapper == null) {//实例化bean,调用构造函数
      instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    //......
    // 保存单例的实例,解决循环依赖,此时bean还未注入属性
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
      addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
              return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }//......
    try {
        //填充bean ,如:bean属性,autowired
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
        //初始化bean,调用初始化方法
            exposedObject = initializeBean(beanName, exposedObject, mbd);
    }//......
}
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}
//AbstractAutowireCapableBeanFactory.initializeBean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        //...
    } else {
        //调用一系列xxxAware接口,如:BeanNameAware
        invokeAwareMethods(beanName, bean);
    }
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {//调用BeanPostProcessor的before接口
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    try {
        //调用bean的初始化方法,InitializingBean.afterPropertiesSet
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {}
    if (mbd == null || !mbd.isSynthetic()) {//调用BeanPostProcessor的after接口,后面讲到的AOP的实现的关键,就是在这里对bean进行包装的
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}
目录
相关文章
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
11天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
1月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
66 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
2月前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
205 24
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
30天前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
2月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
210 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
2月前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
1月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
73 1
|
1月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
38 1
|
1月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
84 1