• Spring源码分析-bean的初始化过程


    初始化过程

    1. 构造 bean
    2. 依赖注入(接下来才是初始化过程)
    3. 获取容器中所有的 BeanPostProcessor,执行其 postProcessBeforeInitialization 方法(@PostConstruct注解指定的初始化方法,就是在这一步由 CommonAnnotationBeanPostProcessor 实现)
    4. 如果 bean 实现了 InitializingBean 接口,执行 afterPropertiesSet 方法
    5. 如果 @Bean 注解中指定了 initMethod 属性,执行指定的方法
    6. 获取容器中所有的 BeanPostProcessor,执行其 postProcessAfterInitialization 方法

    源码分析

    • BeanFactory 的 initializeBean 方法中
    /**
     * 获取 BeanPostProcessor,执行 postProcessBeforeInitialization 方法
     */
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    /**
     * 执行 bean 指定的初始化方法:InitializingBean 接口的 afterPropertiesSet 方法,@Bean 注解指定的初始化方法
     */
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    /**
     * 获取 BeanPostProcessor,执行 postProcessAfterInitialization 方法
     */
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    
    • invokeInitMethods 方法
    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {
    
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                /**
                 * 执行 InitializingBean 接口的 afterPropertiesSet 方法
                 */
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }
    
        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                /**
                 * 执行 @Bean 注解的 initMethod 属性指定的方法
                 */
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }
    
  • 相关阅读:
    Ubuntu16.04安装Docker、nvidia-docker
    Java 对象和类
    Java基础知识总结
    Java 学习路线
    编写radware的负载配置
    MySQL的主从复制+双主模式
    模拟MBR Grub故障修复
    搭建Nginx(haproxy)+keepalived+Tomcat双主高可用负载均衡
    golang数据库操作初体验
    我操蛋的2019
  • 原文地址:https://www.cnblogs.com/lighter-blog/p/13205669.html
Copyright © 2020-2023  润新知