zoukankan      html  css  js  c++  java
  • 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);
            }
        }
    }
    
  • 相关阅读:
    python 发包爬取中国移动充值页面---可判断手机号是否异常
    python利用selenium和safari浏览器驱动实现新浪微博自动点赞 Demo
    Django学习报错记录
    nginx和tomcat的区别
    Mac主机映射到域名
    mac下eclipse安装svn插件-subclipse
    移动端——等分,居中
    移动端——重置样式
    M端页面-绝对定位布局
    jquery-练习-折叠效果
  • 原文地址:https://www.cnblogs.com/lighter-blog/p/13205669.html
Copyright © 2011-2022 走看看