『深入学习 Spring Boot』——Bean 实例化流程

Posted 守夜人爱吃兔子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『深入学习 Spring Boot』——Bean 实例化流程相关的知识,希望对你有一定的参考价值。

Bean 实例化

finishBeanFactoryInitialization(beanFactory)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        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));
        }
 
        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }
 
        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }
 
        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);
 
        // Allow for caching all bean definition metadata, not expecting further changes.
        beanFactory.freezeConfiguration();
 
        // Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();
    }

这里,看起来有这么多方法,其实初始化的主体逻辑都在beanFactory.preInstantiateSingletons()中。

preInstantiateSingletons()

这个方式是 Bean 实例化的核心方法。

简单看一下注释,就知道这个方法做了两件事:

  • 初始化 Bean
  • Bean 的回调处理
public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }
 
        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
 
        // Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
 
        // Trigger post-initialization callback for all applicable beans...
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

Bean 实例化

我们截取上面方法的实例化部分来分析:

for (String beanName : beanNames) {
          // 获取 Bean 的定义。BeanDefinition 是 Spring 中对于 Bean 的描述。
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
          // 不是抽象类、不是懒加载、是单例
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        // 判断是否工厂Bean
                if (isFactoryBean(beanName)) {
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
        // 不是工厂Bean
                else {
                    getBean(beanName);
                }
            }
        }

哦豁,这里面分了 工厂Bean 和 普通Bean 采取不同的处理策略。自然是先看 普通Bean 了。

getBean()

public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

下面就来到了真正的逻辑doGetBean(),但是这个方法太长了,约有150行。如果我觉得不是核心逻辑的语句,我就略去了。

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
        // 获取 beanName,有别名的用别名,工厂类的把工厂类名称前缀去掉。
        final String beanName = transformedBeanName(name);
        Object bean;
 
        // Eagerly check singleton cache for manually registered singletons.
        // 检查缓存中是否有手动注册的单例Bean
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
          …………
       // 获取给定bean实例的对象,如果是FactoryBean,则可以是bean实例本身或其创建的对象。
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
 
        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // 判断这个Bean的状态是不是正在创建,如果是,可能循环引用了。
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
 
      ........
 
            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
 
                // Guarantee initialization of beans that the current bean depends on.
               // 先加载当前Bean 定义了DpendsOn的类
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                // 遍历处理 DpendsOn 类
                    for (String dep : dependsOn) {
                        ....
                        // 为当前实例化中的bean注册一个从属bean
                        registerDependentBean(dep, beanName);
                        try {
                        // 递归调用,获取Dpends 实例化的Bean
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
 
                // Create bean instance.
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // 创建 Bean
                            return createBean(beanName, mbd, args);
                        }
                        ...........
                    });
                   .........
                }
     ............
        return (T) bean;
    }

我们继续进入到createBean(beanName,mbd,args)中:

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
     ........
        RootBeanDefinition mbdToUse = mbd;
        ........
 
        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        ........
 
        try {
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            ......
            return beanInstance;
        }
        ........
    }

主要到这里有两个比较重要的方法:resolveBeforeInstantiation(beanName, mbdToUse) doCreateBean(beanName, mbdToUse, args)

resolveBeforeInstantiation

 
// 执行 Bean 实例化的,前后处理器。
// 从文档注释来看,这里可以指定Bean实例化的快捷方式
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
          // 实例化 Bean 前置处理
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
            // 实例化 Bean 后置处理
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }
 
// 实现了 InstantiationAwareBeanPostProcessor 的Bean,执行 postProcessBeforeInstantiation
// 这个应该是上面所指的实例化快捷方式,我们可以实现 InstantiationAwareBeanPostProcessor 后,在postProcessBeforeInstantiation方法中,自定义实例化Bean 的逻辑。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

很显然,我们一般不会这么搞的。我们日常时候都是直接注解一下就ok,并不会自定义Bean的实例化逻辑。

doCreateBean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {
 
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        ......
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        ......
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        ......
 
     ......
 
        .....
        return exposedObject;
    }

这里面呢,有三个主要方法需要我们注意:createBeanInstance(beanName, mbd, args)populateBean(beanName, mbd, instanceWrapper)initializeBean(beanName, exposedObject, mbd)

  • createBeanInstance

    使用适当的实例化策略为指定的bean创建一个新实例。

  • populateBean

    使用Bean定义中的属性值填充给定BeanWrapper中的Bean实例。

  • initializeBean

    初始化给定的bean实例,应用工厂回调以及init方法和bean post处理器。 对于传统定义的bean,从createBean调用,对于现有的bean实例,从initializeBean调用。

createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {        // Make sure bean class is actually resolved at this point.        Class<?> beanClass = resolveBeanClass(mbd, beanName);         ...     // 使用命名工厂方法实例化bean。        if (mbd.getFactoryMethodName() != null) {            return instantiateUsingFactoryMethod(beanName, mbd, args);        }         // Shortcut when re-creating the same bean...        boolean resolved = false;        boolean autowireNecessary = false;        ......        if (resolved) {            if (autowireNecessary) {        // 构造函数注入                return autowireConstructor(beanName, mbd, null, null);            }            else {        // 使用其默认构造函数实例化给定的bean。                return instantiateBean(beanName, mbd);            }        }    ......        // 使用无参构造,实例化Bean        return instantiateBean(beanName, mbd);    }

populateBean

不是重点。

initializeBean

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {        .....        else {      // 判断实现了哪一种 Aware 接口,调用对应的方法            invokeAwareMethods(beanName, bean);        }         Object wrappedBean = bean;        if (mbd == null || !mbd.isSynthetic()) {      // 巨熟悉的方法:实例化的前置处理            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);        }         try {      // 调用Bean的 afterPropertiesSet() 方法            invokeInitMethods(beanName, wrappedBean, mbd);        }        ......        if (mbd == null || !mbd.isSynthetic()) {      // 实例化的后置处理            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);        }     // 返回 Bean        return wrappedBean;    }

总结

Bean 的实例化总体流程,我们就此走完了。

Bean 的实例化过程,还是非常复杂的。所以我们这节,还是重在总体流程的理解,细枝末节的以后再探究。

在探究 Bean 的实例过程中,我们看到了,很多判断是否实现了某接口,然后调用接口方法的逻辑,例如 BeanPostProcessors。这是 Spring 里非常常用的手法。

最后

最近我整理了整套《JAVA核心知识点总结》,说实话 ,作为一名Java程序员,不论你需不需要面试都应该好好看下这份资料。拿到手总是不亏的~我的不少粉丝也因此拿到腾讯字节快手等公司的Offer

Java进阶之路群,找管理员获取哦-!

以上是关于『深入学习 Spring Boot』——Bean 实例化流程的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot是如何扫描和加载bean的

Java框架spring Boot学习笔记:Bean的作用域

Spring Boot 学习系列(09)—自定义Bean的顺序加载

Spring Boot 学习系列(09)—自定义Bean的顺序加载

深入Spring Boot:那些注入不了的Spring占位符(${}表达式)

spring boot配置类注册深入解析