SpringIOC 容器启动过程 源码分析以及 循环依赖问题

🍀java全知识点学习笔记 思维导图 面试跳槽必备 码云仓库地址 https://gitee.com/vx202158/vx202158.git 🍀

Spring容器启动过程 源码分析 以及如何解决循环依赖问题

1.Spring是什么

Spring是一款轻量级的开发框架 . 简而言之 Spring提高了开发效率 两个核心 IOC 和 AOP

1.1 IOC ( Inversion of Control ) 是什么

*Inversion of Control 控制反转 *

1.1.1 控制了什么

想象一下如果没有使用spring ,我们要创建一个A对象 它 有属性 id name age 等等 我们是不是需要

new A(id,name,age)

而使用了spring框架后 你所需要的组件没有使用过new 吧 那这个对象 又是谁帮我们创建的呢 又是从哪里来的呢

显而易见的是 对象由spring 帮我们创建的 从容器中获取的 这就是"控制" 控制了 对象的创建以及生命周期的管理

1.1.2 反转了什么

又假如 我们要创建对象A 而又依赖于对象B 没有使用Spring我们通常的做法是 在对象A创建之前创建对象B 而使用了Spring之后 Spring容器能帮我们注入对象A所需要的依赖 这就是反转 反转了 对象与对象之间依赖的获取

1.1.3 类比生活

某一天我们想吃辣椒炒肉,我们需要自己去买菜,自己去炒,最后做出来辣椒炒肉 ( new 对象 ) 你需要吃什么,自己动手去做

而现在,我们可以打开美团 ( spring容器 ) 点一份辣椒炒肉 ,美团(忽略商家) 会做好辣椒炒肉 ( 辣椒炒肉不用你炒了 ) ,送到你家 你需要吃什么 美团给你做好,送到指定位置

1.2 AOP 是什么

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方
式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个
热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑
的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高
了开发的效率。
                                                                         ---  百度的解释

关于AOP ,就不多说了 该贴重点也不在这

2.Spring容器的启动过程

2.1 三种启动Spring容器的方式

(1) 从类的根路径下加载配置⽂件,创建spring容器

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

(2) 从磁盘路径上加载配置⽂件,创建spring容器

ApplicationContext applicationContext =new FileSystemXmlApplicationContext();

(3) 加载注解配置类,创建spring容器

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();

2.2 启动过程分析 先看图 ( 使用第一种方式 根路径加载配置文件 )

image-20220225200455231

2.2.1 准备工作

2.2.1.1 创建测试类

/**
 * @author sz
 * @DATE 2022/2/25  18:20
 */
public class TestBean {

    public TestBean() {
        System.out.println("testBean构造方法执行了");
    }
}

2.2.1.2 创建 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
">

    <!--  创建测试bean对象    -->
    <bean id="testBean" class="com.qiuri.sz.TestBean"/>


</beans>

2.2.1.3 主启动类

    /**
     *  Ioc 容器启动过程分析
     */
    @Test
    public void testAOP() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext-----.xml");
        TestBean bean = applicationContext.getBean(TestBean.class);
    }

2.2.2 断点分析

image-20220225182847257

跟进去 来到 ClassPathXmlApplicationContext 类

image-20220225182947437

调用了另外一个构造方法

public ClassPathXmlApplicationContext(String[] configLocations,                                          boolean refresh,                                          @Nullable ApplicationContext parent) throws BeansException {        /**         *调用父类构造         */        super(parent);        // 2.解析配置文件的路径        setConfigLocations(configLocations);        // 3.判断是否需要刷新容器        if (refresh) {   //true              // 刷新容器            refresh();        }    }

最终执行了 refresh()方法

2.2.3 refresh() 方法分析

org.springframework.context.support.AbstractApplicationContext#refresh

​ 首先可以看到 方法第一行就是个同步代码块 解决线程安全问题

public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {                    prepareRefresh();                    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();                        prepareBeanFactory(beanFactory);            try {                                postProcessBeanFactory(beanFactory);                invokeBeanFactoryPostProcessors(beanFactory);                    registerBeanPostProcessors(beanFactory);                            initMessageSource();                            initApplicationEventMulticaster();                                onRefresh();                registerListeners();                            finishBeanFactoryInitialization(beanFactory);                finishRefresh();            }            catch (BeansException ex) {                if (logger.isWarnEnabled()) {                    logger.warn("Exception encountered during context initialization - " +                            "cancelling refresh attempt: " + ex);                }                        destroyBeans();                cancelRefresh(ex);                            throw ex;            }            finally {                // Reset common introspection caches in Spring's core, since we                // might not ever need metadata for singleton beans anymore...                resetCommonCaches();            }        }    }

2.2.3.1 prepareRefresh()方法 准备上下文刷新工作,记录容器的启动时间以及状态

protected void prepareRefresh() {        // 记录启动时间.        this.startupDate = System.currentTimeMillis();        // 设置容器为未关闭状态        this.closed.set(false);        // 设置容器为激活状态        this.active.set(true);        if (logger.isDebugEnabled()) {            if (logger.isTraceEnabled()) {                logger.trace("Refreshing " + this);            }            else {                logger.debug("Refreshing " + getDisplayName());            }        }                initPropertySources();        // Validate that all properties marked as required are resolvable:         * 作用:校验属性         */        getEnvironment().validateRequiredProperties();        // Store pre-refresh ApplicationListeners...        if (this.earlyApplicationListeners == null) {            /** 初始化监听器,用于初始化使用 */            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);        }        else {            // Reset local application listeners to pre-refresh state.            this.applicationListeners.clear();            this.applicationListeners.addAll(this.earlyApplicationListeners);        }        // Allow for the collection of early ApplicationEvents,        // to be published once the multicaster is available...        this.earlyApplicationEvents = new LinkedHashSet<>();    }

该方法主要是 准备上下文刷新工作,记录容器的启动时间以及状态

2.2.3.2 obtainFreshBeanFactory()方法 创建beanFactory工厂以及 解析创建BeanDefinition对象

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

跟进去

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {        refreshBeanFactory();        return getBeanFactory();    }

跟进 refreshBeanFactory()方法

protected final void refreshBeanFactory() throws BeansException {        // 看名字  是否有bean工厂存在        if (hasBeanFactory()) {            // 如果有bean工厂存在 销毁 bean            destroyBeans();            // 关闭bean工厂            closeBeanFactory();        }        try {            // 创建bean工厂,返回Bean工厂类型是:DefaultListableBeanFactory            //return new DefaultListableBeanFactory(getInternalParentBeanFactory());                        DefaultListableBeanFactory beanFactory = createBeanFactory();                        // 设置序列化ID            beanFactory.setSerializationId(getId());                        //设置bean是否可以被覆盖以及是否允许循环引用.            customizeBeanFactory(beanFactory);            // 解析bean的定义信息                                    loadBeanDefinitions(beanFactory);            synchronized (this.beanFactoryMonitor) {                this.beanFactory = beanFactory;            }        }        catch (IOException ex) {            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);        }    }

image-20220225184950230

loadBeanDefinitions(beanFactory) 方法执行前 beanDefinitionMap 为空

image-20220225185101048

loadBeanDefinitions(beanFactory) 方法执行后 beanDefinitionMap 有元素了

其中map的key为 我们xml配置文件中 bean标签的ID 也就是容器中bean的name value 的 beanClass记录了 testBean的全限定类名 com.qiuri.sz.TestBean

在obtainFreshBeanFactory 获取Bean工厂,解析bean定义信息.生成BeanDefinition对象,存入BeanDefinitionMap中

2.2.3.3 prepareBeanFactory(beanFactory)方法 设置bean工厂的属性

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {        beanFactory.setBeanClassLoader(getClassLoader());        // 设置SPEL解析器        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));        // 添加属性编辑注册器        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));        // 添加bean的后置处理器。此处添加的是Spring自己的后置处理器,用来回调bean所实现的aware接口中的方法.        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));        // 下面的ignoreDependencyInterface是用来设置bean工厂中需要忽略的接口        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);        // 可以通过实现EmbeddedValueResolverAware接口来获取String类型值的解析器        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);        // 资源加载器,例如使用:@Autowired ResourceLoaderAware aware; 将不会被注入        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);        // 事件发布器        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);        // 消息资源        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);        // 应用的上下文信息        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);        // 注册一些可以自动装配的接口。 当类型为dependencyType时, 注入autowiredValue。为了解决一个类型有多个子类实现时,优先注入那个子类实现的问题。        // 例如下面第一个,当注入类型为BeanFactory时,注入的值为beanFactory,默认为DefaultListableBeanFactory        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);        // 当注入类型为ResourceLoader时,注入的值为ApplicationContext        beanFactory.registerResolvableDependency(ResourceLoader.class, this);        // 当注入类型为ApplicationEventPublisher时,注入的值为ApplicationContext        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);        // 当注入的类型为ApplicationContext时,注入的值为ApplicationContext.        beanFactory.registerResolvableDependency(ApplicationContext.class, this);        // 增加一个bean的后置处理器,ApplicationListenerDetector        // Register early post-processor for detecting inner beans as ApplicationListeners.        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));        // Detect a LoadTimeWeaver and prepare for weaving, if found.        // 如果bean工厂中存在着名称为loadTimeWeaver的bean定义,则给bean工厂中加入LoaderTimeWeaverAwareProcessor后置处理器        // 补充:1、增加对AspectJ的支持,在Java中织入分为3种:(1) 编译期织入; (2) 类加载期织入; (3) 运行期织入。编译期织入指的是在java编译期,        //         采用特殊的编译器,将切面织入到java类中;类加载期织入则指的是通过特殊的类加载器,在字节码加载到JVM时,织入切面;运行期织入则是        //         通过采用cglib或者jdk进行切面的织入。        //      2、aspectJ中提供了两种方式:        //         (1) 通过特殊编译器,在编译期,将aspectJ语言编写的切面类织入到java类中;        //         (2) 类加载期织入,就是通过下面的LoadTimeWeaving        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));            // Set a temporary ClassLoader for type matching.            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));        }        // 给容器中注册一些与运行环境相关的单实例Bean        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {            // beanName: environment,直接将new出来的Spring内部对象放入到Spring的单实例缓存池中.            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());        }        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {            // beanName: systemProperties   方法:System.getProperties();            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());        }        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {            // beanName: systemEnvironment,   方法:System.getEnv();            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());        }    }

2.2.3.4 postProcessBeanFactory(beanFactory) 空方法,bean定义信息加载完成后执行,可以用来修改beanFactory中定义的bean定义信息

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {    }

2.2.3.5 invokeBeanFactoryPostProcessors(beanFactory) 执行 BeanFactory的后置处理器方法

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {        // 执行Bean工厂的所有后置处理器        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));        }    }

我们没有BeanFactory的后置处理器,所以方法跟进去后if判断直接跳过

2.2.3.6 registerBeanPostProcessors(beanFactory) 注册(不是执行)Bean的后置处理器

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}

2.2.3.7 initMessageSource() 消息国际化

protected void initMessageSource() {        // 获取bean工厂        ConfigurableListableBeanFactory beanFactory = getBeanFactory();        // 判断是否在bean工厂中定义了id为messageSource的bean对象        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {            // 如果有id为messageSource,而且类型是MessageSource的组件,直接赋值给messageSource属性            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);            // Make MessageSource aware of parent MessageSource.            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;                if (hms.getParentMessageSource() == null) {                    // Only set parent context as parent MessageSource if no parent MessageSource                    // registered already.                    hms.setParentMessageSource(getInternalParentMessageSource());                }            }            if (logger.isTraceEnabled()) {                logger.trace("Using MessageSource [" + this.messageSource + "]");            }        }        else {            // Use empty MessageSource to be able to accept getMessage calls.            // 如果没有,则创建一个DelegatingMessageSource类型的messageSource对象            DelegatingMessageSource dms = new DelegatingMessageSource();            dms.setParentMessageSource(getInternalParentMessageSource());            this.messageSource = dms;            // 将messageSource注册到容器中,在获取国际化配置文件中的某个值时,可以直接通过注入MessageSource,            // 调用其getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale)方法来获取.            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);            if (logger.isTraceEnabled()) {                logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");            }        }    }

2.2.3.8 initApplicationEventMulticaster() 初始化上下文事件派发器

protected void initApplicationEventMulticaster() {        // 获取Bean工厂        ConfigurableListableBeanFactory beanFactory = getBeanFactory();                // APPLICATION_EVENT_MULTICASTER_BEAN_NAME =  applicationEventMulticaster        // 判断当前的bean工厂中有没有id为applicationEventMulticaster的事件派发器                if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {                    // 如果有,则直接获取到ApplicationEventMulticaster类型的事件多播器,并赋值给applicationEventMulticaster.            this.applicationEventMulticaster =                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);            if (logger.isTraceEnabled()) {                logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");            }        }        else {            // 如果没有则创建一个类型为SimpleApplicationEventMulticaster事件监听器,            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);            // 将创建的事件多播器注册到容器中,在其他组件需要派发事件时,直接获取这个applicationEventMulticaster            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);            if (logger.isTraceEnabled()) {                logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +                        "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");            }        }    }

2.2.3.9 ionRefresh() 初始化特殊的Bean,通过继承AbstractApplicationContext类,重写该方法完成自定义特殊bean的初始化.

    protected void onRefresh() throws BeansException {        //空,什么也没有,留给我们去实现  SpringBoot也是在改步骤中启动内嵌Tomcat容器的    }

2.2.3.10 registerListeners() 注册监听器

protected void registerListeners() {        // 将注册的监听器绑定到广播器        for (ApplicationListener<?> listener : getApplicationListeners()) {            getApplicationEventMulticaster().addApplicationListener(listener);        }        // 根据类型获取listener监听器的名称        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);        for (String listenerBeanName : listenerBeanNames) {            // 将事件监听器注册到派发器中,以后使用的时候,就可以直接通过事件派发器执行.            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);        }                    /**         * 派发之前产生的事件。         * earlyApplicationEvent是在prepareRefresh中声明的.         */        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;        this.earlyApplicationEvents = null;        if (earlyEventsToProcess != null) {            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {                getApplicationEventMulticaster().multicastEvent(earlyEvent);            }        }    }

2.2.3.11 finishBeanFactoryInitialization(beanFactory) 初始化所有的单例bean (核心)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {        // 1. 初始化此上下文的转换服务,用来自定义将Spring中的某个Bean的属性从一个类型转换到另外一个类型.        //    判断Bean工厂中是否存在名称为conversionService的转换服务bean,如果存在而且类型为ConversionService,则获取该Bean实例,并将其设置到BeanFactory中        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));        }                        if (!beanFactory.hasEmbeddedValueResolver()) {            // 调用resolvePlaceholders方法解析strVal对应的值            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));        }                         String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);        for (String weaverAwareName : weaverAwareNames) {            getBean(weaverAwareName);        }        // 停止使用临时的类加载器.        beanFactory.setTempClassLoader(null);        // 缓存(冻结)所有的BeanName(注册的bean定义不会被修改或进一步做处理了,因为下面马上要创建Bean的实例对象了)        beanFactory.freezeConfiguration();        // 初始化所有的单实例Bean,包括创建单实例bean的全部过程        beanFactory.preInstantiateSingletons();    }
直接看 beanFactory.preInstantiateSingletons()方法 跟进去
public void preInstantiateSingletons() throws BeansException {        if (logger.isTraceEnabled()) {            logger.trace("Pre-instantiating singletons in " + this);        }        // 创建beanName集合        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);        // 遍历所有的beanNames,创建所有的单实例Bean        for (String beanName : beanNames) {                    // 获取beanName对应的MergedBeanDefinition.    BeanDefinitionMap的value  key为beanName   不记得了可以看  2.2.3.2                        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);            // 如果bd对应的Bean实例满足:(不是抽象类 && 是单例 && 不是懒加载)            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {                // 判断BeanName对应的Bean实例是否是FactoryBean.                if (isFactoryBean(beanName)) {                    // 通过beanName获取FactoryBean的实例,factoryBean的名称是:"&" + beanName                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);                    if (bean instanceof FactoryBean) {                        final FactoryBean<?> factory = (FactoryBean<?>) bean;                        boolean isEagerInit;                        // 判断这个FactoryBean是否需要紧急初始化.                                                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) {                            // 如果需要紧急初始化,则通过beanName获取Bean的实例.                            getBean(beanName);                        }                    }                }                else {                    // 如果BeanName对应的Bean实例不是FactoryBean,则通过BeanName去获取Bean实例.                    getBean(beanName);                }            }        }        /**         * 上一步for循环中已经创建完了所有的单实例Bean,这个for循环中,会拿出所有的单实例Bean,         *   然后遍历,判断单实例bean是否实现了SmartInitializingSingleton接口,如果实现了该接口,         *   则调用单实例Bean的afterSingletonsInstantiated方法         */        for (String beanName : beanNames) {            // 获取beanName对应的bean实例            Object singletonInstance = getSingleton(beanName);            // 判断当前的bean是否实现了SmartInitializingSingleton接口.            if (singletonInstance instanceof SmartInitializingSingleton) {                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;                // 触发SmartInitializingSingleton实现类的afterSingletonInstantiated方法.                if (System.getSecurityManager() != null) {                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {                        smartSingleton.afterSingletonsInstantiated();                        return null;                    }, getAccessControlContext());                }                else {                    /**                     * 如果实现了SmartInitializingSingleton接口,则会调用afterSingletonInstantiated方法                     *   例如@EventListener注解的实现原理,就是利用EventListenerMethodProcessor后置处理器完成的,                     *   而在EventListenerMethodProcessor中就是实现了SmartInitializingSingleton接口                     */                    smartSingleton.afterSingletonsInstantiated();                }            }        }    }
跟进getBean(beanName)方法 org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
@Override    public Object getBean(String name) throws BeansException {        // 空方法        return doGetBean(name, null, null, false);    }
继续跟进 doGetBean方法 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean ( Spring循环依赖问题在此解决)
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {        // 获取真正的BeanName。主要包括: 去掉FactoryBean名称前面的&前缀;(2) bean别名解析;        final String beanName = transformedBeanName(name);        Object bean;        // 先尝试从缓存中获取单实例Bean,如果能获取到,说明已经被创建过        //   注意:如果是通过FactoryBean方式创建对象。在根据名称获取目标bean对象(非FactoryBean实例)时,此处返回的sharedInstance是FactoryBean对象        Object sharedInstance = getSingleton(beanName);        /**         * 当组件实现了FactoryBean接口,并重写了getObject方法时。在从容器中获取bean的时候,sharedInstance就是容器中返回的bean对象         * 此时sharedInstance不为空,就会调用getObjectForBeanInstance方法,这个方法内部会调用子类重写的getObject方法.          */        if (sharedInstance != null && args == null) {            if (logger.isTraceEnabled()) {                if (isSingletonCurrentlyInCreation(beanName)) {                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +                            "' that is not fully initialized yet - a consequence of a circular reference");                }                else {                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");                }            }            // 获取bean对象,包括使用FactoryBean来创建bean的逻辑.            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);        }        else {            // 如果当前创建的是单实例类型的bean,则尝试解决循环依赖,此处仅仅只是一个校验;如果当前的多实例bean正在创建中,而且存在循环依赖,直接抛出异常            if (isPrototypeCurrentlyInCreation(beanName)) {                throw new BeanCurrentlyInCreationException(beanName);            }            // 获取Bean的父工厂            BeanFactory parentBeanFactory = getParentBeanFactory();            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {                // Not found -> check parent.                String nameToLookup = originalBeanName(name);                if (parentBeanFactory instanceof AbstractBeanFactory) {                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(                            nameToLookup, requiredType, args, typeCheckOnly);                }                else if (args != null) {                    // Delegation to parent with explicit args.                    return (T) parentBeanFactory.getBean(nameToLookup, args);                }                else if (requiredType != null) {                    // No args -> delegate to standard getBean method.                    return parentBeanFactory.getBean(nameToLookup, requiredType);                }                else {                    return (T) parentBeanFactory.getBean(nameToLookup);                }            }            // 标记Bean已经被创建,防止多线程时,Bean可能会被创建多个,就不是单实例了            if (!typeCheckOnly) {                // 将beanName对应的bean定义从mergedBeanDefinitions中移除,并将beanName添加到alreadyCreated集合中.                markBeanAsCreated(beanName);            }            try {                // 获取合并之后的Bean定义                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);                // 校验bean对应的类是否为抽象的,如果bean对应的类标注了抽象,直接会抛出异常                checkMergedBeanDefinition(mbd, beanName, args);                /**                 * 获取当前Bean所依赖的其他Bean                 解决循环依赖问题                  */                String[] dependsOn = mbd.getDependsOn();                // 如果有依赖的Bean                if (dependsOn != null) {                    for (String dep : dependsOn) {                                                                        if (isDependent(beanName, dep)) {                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");                        }                        // 维护依赖和被依赖的bean之间的关联关系                        registerDependentBean(dep, beanName);                        try {                            // 先去创建当前bean所依赖的其他bean对象                            getBean(dep);                        }                        catch (NoSuchBeanDefinitionException ex) {                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);                        }                    }                }                // bean定义如果是单例的,则调用createBean方法进行单实例bean的创建.                if (mbd.isSingleton()) {                    // 此处的lambda表达式为:ObjectFactory的getObject方法                    sharedInstance = getSingleton(beanName, () -> {                        try {                            /**                             * 创建对象并初始化,Spring用来创建Bean实例的核心方法                             *  此处调用的子类AbstractAutowireCapableBeanFactory的createBean方法.                             */                            return createBean(beanName, mbd, args);                        }                        catch (BeansException ex) {                            // 如果创建单实例bean失败,则会删除关于该bean的一切信息,包括三级缓存和已经注册的bean集合中有关该bean的信息                            destroySingleton(beanName);                            throw ex;                        }                    });                    /**                     * 如果一个类实现了FactoryBean接口,回调FactoryBean的getObject自定义方法进行应用bean的创建工作                     */                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);                }                // 当前需要创建的bean如果是多例                else if (mbd.isPrototype()) {                    // 创建多实例bean                    Object prototypeInstance;                    try {                        // 进行多实例bean创建之前的准备工作,将当前正在创建的多实例bean的名称添加到prototypesCurrentlyInCreation中.                        beforePrototypeCreation(beanName);                        // 创建多实例对象,和创建单实例bean使用的是同一个方法                        prototypeInstance = createBean(beanName, mbd, args);                    }                    finally {                        // 从prototypesCurrentlyInCreation【ThreadLocal】中移除                        afterPrototypeCreation(beanName);                    }                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);                }                // 未明确指定将要创建的bean是单例的还是多例的                else {                    String scopeName = mbd.getScope();                    // 从bean定义中获取bean的scope信息,如果bean的scope信息为null,也就是随意设置的scope,直接抛出异常                    final Scope scope = this.scopes.get(scopeName);                    if (scope == null) {                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");                    }                    try {                        // 根据指定的scope获取bean实例                        Object scopedInstance = scope.get(beanName, () -> {                            // 初始化之前准备工作,将bean的名称添加到prototypesCurrentlyInCreation                            beforePrototypeCreation(beanName);                            try {                                // 创建bean实例                                return createBean(beanName, mbd, args);                            }                            finally {                                // 从prototypesCurrentlyInCreation中移除                                afterPrototypeCreation(beanName);                            }                        });                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);                    }                    catch (IllegalStateException ex) {                        throw new BeanCreationException(beanName,                                "Scope '" + scopeName + "' is not active for the current thread; consider " +                                "defining a scoped proxy for this bean if you intend to refer to it from a singleton",                                ex);                    }                }            }            catch (BeansException ex) {                cleanupAfterBeanCreationFailure(beanName);                throw ex;            }        }        /**         * 判断是否需要将bean转换为我们指定类型的Class,如果需要转换,则使用自定义的TypeConverter进行bean类型的转换         *  如果未指定TypeConverter,则默认使用SimpleTypeConverter,converter需要设置一个用来转化的Service实现类,即:ConversionService,         *  ConversionService是在finishBeanFactoryInitialization方法的最前面进行注册的,可以在xml中配置对应的ConversionService实现类         */        if (requiredType != null && !requiredType.isInstance(bean)) {            try {                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);                if (convertedBean == null) {                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());                }                return convertedBean;            }            catch (TypeMismatchException ex) {                if (logger.isTraceEnabled()) {                    logger.trace("Failed to convert bean '" + name + "' to required type '" +                            ClassUtils.getQualifiedName(requiredType) + "'", ex);                }                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());            }        }        return (T) bean;    }
跟进 createBean(beanName, mbd, args)方法 创建实例对象
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)            throws BeanCreationException {        // Instantiate the bean.        BeanWrapper instanceWrapper = null;        if (mbd.isSingleton()) {            // 删除之前工厂bean缓存中的工厂bean对象,重新进行实例化.            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);        }        // 创建Bean的实例,并且包装为一个包装对象返回.        if (instanceWrapper == null) {            // 使用策略方法创建实例,包括:工厂方法,构造函数注入,简单初始化.            // TODO 里面调用的方法超级长            instanceWrapper = createBeanInstance(beanName, mbd, args);        }        // 获取新创建的bean对象和对应的class        final Object bean = instanceWrapper.getWrappedInstance();        Class<?> beanType = instanceWrapper.getWrappedClass();        if (beanType != NullBean.class) {            mbd.resolvedTargetType = beanType;        }        // Allow post-processors to modify the merged bean definition.        synchronized (mbd.postProcessingLock) {            // 如果还未执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法            if (!mbd.postProcessed) {                try {                    // 依次调用所有MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法,用来处理类中使用注解标注的属性,并放入到缓存中.                    /**                     * 其中包括了                     *     【AutowiredAnnotationBeanPostProcessor】,  用来处理@Autowired,@Value,@Inject注解                     *     【CommonAnnotationBeanPostProcessor】,    用来处理@Resource注解                     *     【RequiredAnnotationBeanPostProcessor】, 用来处理@Required注解                     *     【InitDestroyAnnotationBeanPostProcessor】,用来处理@Predestroy和@PostConstruct注解                     *     【ScheduledAnnotationBeanPostProcessor】,用来处理@Scheduled注解                     *         等后置处理器                     */                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);                }                catch (Throwable ex) {                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,                            "Post-processing of merged bean definition failed", ex);                }                mbd.postProcessed = true;            }        }        /**         * 当前的bean是单例的 && 允许bean之间的循环依赖 && bean正在创建中         */        boolean earlySingletonExposure = (mbd.isSingleton()                && this.allowCircularReferences                && isSingletonCurrentlyInCreation(beanName));        // 判断是否需要提前暴露自己。如果需要提前暴露,会将创建完但未填充属性和初始化的bean放入到singletonFactories中,用来解决循环依赖.        //         Spring中的单实例Bean,而且是使用属性注入的方式,默认支持循环依赖的;如果是prototype类型的,默认不支持循环依赖        //     如果是单例bean,而且使用构造器注入的方式,默认不支持循环依赖,可在构造器上添加@Lazy注解,让依赖的属性延迟初始化来解决        //     如果是单例bean和prototype类型的bean混用,则如果先创建单例,可以成功,如果先创建prototype类型的bean,则会失败        if (earlySingletonExposure) {            if (logger.isTraceEnabled()) {                logger.trace("Eagerly caching bean '" + beanName +                        "' to allow for resolving potential circular references");            }            /**             * getEarlyBeanReference: 是用来获取到被SmartInstantiationAwareBeanPostProcessor后处理器处理过的刚刚实例化结束的bean对象             *             * addSingletonFactory: 是用来将刚刚初始化的bean对象放入到singletonFactories中,singletonFactories是个map集合,             *  key: bean的名称,value: 是一个ObjectFactory,当存在着循环依赖时,可以通过ObjectFactory.getObject方法获取到刚刚实例化的bean对象             */            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));        }        /** 初始化单实例bean。 包括:填充属性及执行初始化方法 */        Object exposedObject = bean;        try {            /**             * 【依赖注入】             * 填充的属性包括:普通属性和使用@Autowired和@Resource注解标注的引用类型属性的赋值。使用了反射操作set方法完成赋值.             *             * eg: 重点操作举例:             *         【创建完成Bean之后,填充Bean的属性,填充过程中会调用InstantiationAwareBeanPostProcessorAdaptor类的postProcessProperties方法】             */            populateBean(beanName, mbd, instanceWrapper);            /**             * 完成Bean的初始化(执行afterPropertiesSet和init-method)             *         注意:会调用@PostConstruct标注的方法,这个方法是在Bean创建完成,而且属性填充完成之后,才会被调用             */            exposedObject = initializeBean(beanName, exposedObject, mbd);        }        catch (Throwable ex) {            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {                throw (BeanCreationException) ex;            }            else {                throw new BeanCreationException(                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);            }        }        if (earlySingletonExposure) {            Object earlySingletonReference = getSingleton(beanName, false);            if (earlySingletonReference != null) {                if (exposedObject == bean) {                    exposedObject = earlySingletonReference;                }                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {                    String[] dependentBeans = getDependentBeans(beanName);                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);                    for (String dependentBean : dependentBeans) {                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                            actualDependentBeans.add(dependentBean);                        }                    }                    if (!actualDependentBeans.isEmpty()) {                        throw new BeanCurrentlyInCreationException(beanName,                                "Bean with name '" + beanName + "' has been injected into other beans [" +                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +                                "] in its raw version as part of a circular reference, but has eventually been " +                                "wrapped. This means that said other beans do not use the final version of the " +                                "bean. This is often the result of over-eager type matching - consider using " +                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");                    }                }            }        }        try {            /**             * 注册bean的销毁方法,如果bean不是prototype类型,而且requiresDestruction方法返回true             *  则会将当前的bean放入到一个需要被销毁的map集合中.             */            registerDisposableBeanIfNecessary(beanName, bean, mbd);        }        catch (BeanDefinitionValidationException ex) {            throw new BeanCreationException(                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);        }        return exposedObject;    }

*addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); * 把实例对象放入三级缓存中

getSingleton(String beanName) 缓存中获取Bean (解决循环依赖)

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)

public Object getSingleton(String beanName) {        // 从缓存中获取单实例Bean        return getSingleton(beanName, true);    }

继续根据 getSingleton(beanName, true);

protected Object getSingleton(String beanName, boolean allowEarlyReference) {        //首先从一级缓存  singletonObjects中  尝试获取bean        Object singletonObject = this.singletonObjects.get(beanName);        // 一级缓存中都是以及初始化完成的单例bean  如果一级没有,可能在二级缓存 earlySingletonObjects  也就是半成品bean 正在初始化的        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {            // 加锁操作.            synchronized (this.singletonObjects) {                            //尝试从二级缓存中获取半成品bean                singletonObject = this.earlySingletonObjects.get(beanName);                // 如果早二级缓存中没有,而且允许创建早期单实例对象引用                if (singletonObject == null && allowEarlyReference) {                    // 则从三级缓存中获取BeanName对应的单例工厂.                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);                    if (singletonFactory != null) {                        // 如果存在着单例对象工厂,则通过工厂创建一个单例对象,                        // 调用的是:addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))中的lombda表达式                        singletonObject = singletonFactory.getObject();                        // 将单例工厂对象创建的bean放到二级缓存  earlySingletonObjects中                        this.earlySingletonObjects.put(beanName, singletonObject);                        // 删除三级缓存中的bean对应的工厂对象                        this.singletonFactories.remove(beanName);                    }                }            }        }        //返回bean单例对象        return singletonObject;    }

3.循环依赖问题

3.1什么是循环依赖

依赖注入的时候 ,发现A 依赖于B 而B依赖注入的时候发现依赖于A 两者都需要依赖于对方完成属性注入

image-20220225204314476

3.2 Spring中的三级缓存

一级缓存 singletonObjects 存放已经完成实例化的单例bena 本质是一个 ConcurrentHashMap

二级缓存 earlysingletonObjects 存放半成品单例Bean ( 已经实例化,未完成初始化 ) 本质是一个 HashMap

三级缓存 singletonFactorie 存放bean工厂对象 本质是一个HashMap

源码 可以看 getSingleton(String beanName) 缓存中获取Bean

3.3 spring是如何解决循环依赖的

sping在初始化一个bean对象时,会看这个bean是有有依赖的其他bean ,如果有 先初始化依赖的bean ,依赖的bean对象完成初始化后,再来初始化当前bean

具体详细过程:

1,A创建过程中需要B,于是A将自己放到三级缓里面,去实例化B

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

2,B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A

3,B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)

然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A自己放到一级缓存里面。

#Java求职##学习路径##Spring##Java##笔试题目##面经##春招##实习#
全部评论
感谢楼主分享
点赞 回复 分享
发布于 2022-02-28 20:42

相关推荐

评论
6
33
分享
牛客网
牛客企业服务