Spring -- IOC 源码剖析

一、BeanFactory 及 容器继承体系

  • 基础概念回顾
    1. BeanFactory 是容器的顶级接口,它定义了容器的基础行为
    2. ApplicationContext 是容器的高级接口,字面意思就是 Spring 应用上下文,官方称之为 IOC 容器
    3. 错误的认识:容器就是 map 而已
    4. 正确的认识:map 是 IOC 容器的一个成员,叫做单例池(singletonObjects),容器是一组组件和过程的集合,包括 BeanFactory ,单例池,BeanPostProcessor 等以及之间的协作流程
  • BeanFactory 容器继承体系
    通过其接口设计,我们可以看到我们⼀贯使用的 ApplicationContext 除了继承 BeanFactory 的子接口,还继承了 ResourceLoader(加载资源)、MessageSource(国际化) 等接口,因此其提供的功能也就更丰富了


二、容器初始化流程

Bean 生命周期关键时机点:都在 AbstractApplicationContext 类中的 refresh 方法中

关键点 触发代码
构造器 finishBeanFactoryInitialization(beanFactory)
BeanFactoryPostProcessor 初始化 invokeBeanFactoryPostProcessors(beanFactory)
BeanFactoryPostProcessor 方法调用 invokeBeanFactoryPostProcessors(beanFactory)
BeanPostProcessor 初始化 registerBeanPostProcessors(beanFactory)
BeanPostProcessor 方法调用 finishBeanFactoryInitialization(beanFactory)
  • refresh 方法
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        /*
         * 对象加锁
         * 目的:在容器 启动、刷新、关闭 的时候不能同时执行 refresh 操作
         */
        synchronized (this.startupShutdownMonitor) {
            /*
             * 刷新前的预处理
             * 表示在真正做 refresh 操作之前需要准备做的事情:
             *     1. 设置 Spring 容器的启动时间
             *     2. 开启活跃状态,撤销关闭状态
             *     3. 验证环境信息里一些必须存在的属性等
             */
            prepareRefresh();
    
            /*
             * 获取 BeanFactory,默认实现是 DefaultListableBeanFactory
             * 加载 BeanDefinition 并注册到 BeanDefinitionRegistry
             */
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // BeanFactory 的预准备工作(BeanFactory 进行一些设置,比如 context 的类加载器等)
            prepareBeanFactory(beanFactory);
    
            try {
                // BeanFactory 准备工作完成后进行的后置处理工作
                postProcessBeanFactory(beanFactory);
    
                // 实例化实现了 BeanFactoryPostProcessor 接口的 Bean,并调用接口方法
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // 注册 BeanPostProcessor(Bean 的后置处理器),在创建 Bean 的前后等执行
                registerBeanPostProcessors(beanFactory);
    
                // 初始化 MessageSource 组件(做国际化功能,消息绑定,消息解析)
                initMessageSource();
    
                // 初始化事件派发器
                initApplicationEventMulticaster();
    
                /*
                 * 子类重写这个方法,在容器刷新的时候可以自定义逻辑
                 * 如:创建 tomcat,jetty 等 web 服务器
                 */
                onRefresh();
    
                // 注册应用的监听器,就是注册实现了 ApplicationListener 接口的监听器 bean
                registerListeners();
    
                /*
                 * 1.初始化所有剩下的非懒加载的单例 bean
                 * 2.初始化创建非懒加载方式的单例 bean 实例(未设置属性)
                 * 3.填充属性
                 * 4.初始化方法调用(比如调用 afterPropertiesSet 方法、init-method 方法)
                 * 5.调用 BeanPostProcessor(后置处理器)对实例 bean 进行后置处理
                 */
                finishBeanFactoryInitialization(beanFactory);
    
                /*
                 * 完成 context 的刷新
                 * 主要是调用 LifecycleProcessor 的 onRefresh() 方法
                 * 并且发布事件(ContextRefreshedEvent)
                 */
                finishRefresh();
            }
    
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }
    
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
    
                // Reset 'active' flag.
                cancelRefresh(ex);
    
                // Propagate exception to caller.
                throw ex;
            }
    
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }
    
  • 获取 beanFactory 流程
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        return getBeanFactory();
    }
    
    @Override
    protected final void refreshBeanFactory() throws BeansException {
        // 判断是否已有 beanFactory
        if (hasBeanFactory()) {
            // 销毁 beans
            destroyBeans();
            // 关闭 beanFactory
            closeBeanFactory();
        }
        try {
            // 实例化 DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 设置序列化id
            beanFactory.setSerializationId(getId());
            // 自定义bean工厂的一些属性(是否覆盖、是否允许循环依赖)
            customizeBeanFactory(beanFactory);
            // 加载应用中的BeanDefinitions
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                // 赋值当前beanFactory
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
    
  • BeanDefinition加载注册流程
    所谓的注册就是把封装的 XML 中定义的 Bean信息封装为 BeanDefinition 对象之后放入⼀个Map中,BeanFactory 是以 Map 的结构组织这些 BeanDefinition的
    loadBeanDefinitions(beanFactory);
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 给指定的beanFactory创建一个XmlBeanDefinitionReader读取器对象,用于读取解析xml对象
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    
        // 给XmlBeanDefinitionReader对象设置一些context上下文中的环境属性
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    
        // 提供给子类实现提供一些自定义的初始化策略
        initBeanDefinitionReader(beanDefinitionReader);
        // 真正的去加载BeanDefinitions
        loadBeanDefinitions(beanDefinitionReader);
    }
    
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        // 从Resource资源对象加载BeanDefinitions
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        // 从xml配置文件加载BeanDefinition对象
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }
    
    public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
        Assert.notNull(locations, "Location array must not be null");
        int count = 0;
        // 如果有多个配置文件,循环读取加载,并统计总共加载了多少个BeanDefinition
        for (String location : locations) {
            count += loadBeanDefinitions(location);
        }
        return count;
    }
    
    public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
        // 获取上下文的资源加载器
        ResourceLoader resourceLoader = getResourceLoader();
        if (resourceLoader == null) {
            throw new BeanDefinitionStoreException(
                    "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
        }
        // 判断资源加载器是否ResourcePatternResolver类型(xml、url等不同类型统一接口为匹配类型)
        if (resourceLoader instanceof ResourcePatternResolver) {
            try {
                // 统一加载转换为Resource资源对象
                Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                // 加载资源中配置的BeanDefinition对象,并返回数量
                int count = loadBeanDefinitions(resources);
                // ......
            }
            // ......
        }
        // ......
    }
    
    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
        Assert.notNull(resources, "Resource array must not be null");
        int count = 0;
        for (Resource resource : resources) {
            count += loadBeanDefinitions(resource);
        }
        return count;
    }
    
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        // ......
        try {
            // 从资源对象中获取流信息
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try {
                // 把xml文件流封装为InputSource对象
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                // do!执行加载逻辑
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
            // ......
        }
        //......
    }
    
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {
    
        try {
            // 读取xml信息,将xml中信息保存到Document对象
            Document doc = doLoadDocument(inputSource, resource);
            // 解析Document对象,封装BeanDefinition对象并进行注册
            int count = registerBeanDefinitions(doc, resource);
                //......
        }
        //......
    }
    
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        //获取已有BeanDefinition的数量
        int countBefore = getRegistry().getBeanDefinitionCount();
        //注册BeanDefinition
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        //返回新注册的BeanDefinition数量
        return getRegistry().getBeanDefinitionCount() - countBefore;
    }
    
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        doRegisterBeanDefinitions(doc.getDocumentElement());
    }
    
    protected void doRegisterBeanDefinitions(Element root) {
        //......
        preProcessXml(root);//供子类实现的方法
        parseBeanDefinitions(root, this.delegate);
        postProcessXml(root);//供子类实现的方法
        this.delegate = parent;
    }
    
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    if (delegate.isDefaultNamespace(ele)) {
                        //解析默认标签元素
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        //解析自定义标签元素
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }
    
    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        //import元素处理
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
        //alias元素处理
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
        //bean元素处理
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            processBeanDefinition(ele, delegate);
        }
        //嵌套beans处理
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
    }
    
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        //解析bean元素为BeanDefinition,但是此时使用BeanDefinitionHolder又包装成了BeanDefinitionHolder对象
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            //如果有自定义标签,则处理自定义标签
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                //完成BeanDefinition的注册
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            //......
    }
    
    public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {
    
        // Register bean definition under primary name.
        String beanName = definitionHolder.getBeanName();
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        //......
    }
    
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
    
        //......
    
        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            //......
        }
        else {
            if (hasBeanCreationStarted()) {
                //......
            }
            else {
                // 注册beanDefinition到beanDefinitionMap中
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                removeManualSingletonName(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }
        //......
    }
    
  • Bean对象创建流程
    finishBeanFactoryInitialization(beanFactory);
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        //......
        // 实例化所有 非懒加载 的单例Bean
        beanFactory.preInstantiateSingletons();
    }
    
    @Override
    public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }
    
        // 所有Bean的名字
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
        // 触发所有非延迟加载的单例Bean的初始化,主要步骤为getBean
        for (String beanName : beanNames) {
            //合并父BeanDefinition对象
            //map.get(beanName)
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //只实例化非抽象方法并且是单例并且是非懒加载的Bean
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    //如果是一个FactoryBean,那么实例化的时候会在beanName前面加一个"&"的前缀
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    //......
                }
                else {
                    //实例化当前bean
                    getBean(beanName);
                }
            }
        }
    
        //......
    }
    
    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }
    
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    
        /*
         * 解析beanName
         * 1.如果以"&"开头,去掉"&"
         * 2.如果是别名,获取到真正的名字
         */
        final String beanName = transformedBeanName(name);
        Object bean;
    
        //单纯理解尝试从缓存中获取bean
        Object sharedInstance = getSingleton(beanName);
        //如果已经存在则返回
        if (sharedInstance != null && args == null) {
            //......
            //针对FactoryBean的处理
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
    
        else {
            //如果是prototype类型且开启允许循环依赖,则抛出异常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
    
            // 检查父工厂中是否存在该对象
            BeanFactory parentBeanFactory = getParentBeanFactory();
            //......
    
            try {
                //合并父子Bean属性
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
    
                // 处理dependsOn配置
                String[] dependsOn = mbd.getDependsOn();
                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 + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
    
                // 创建单例bean
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            //创建bean
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                //......
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }
        //......
    }
    
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                //是否正在销毁,异常
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                //验证完要真正开始创建对象,先标识该bean正在被创建,因为SpringBean创建过程复杂,步骤很多,需要标识
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //传进来的调用,lambda表达式使用
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                //......
            }
            return singletonObject;
        }
    }
    
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean '" + beanName + "'");
        }
        //将beanDefinition转换成了RootBeanDefinition
        RootBeanDefinition mbdToUse = mbd;
    
        //获得类信息
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
    
        //......
    
        try {
            //进入真真正正创建bean
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }
    
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {
    
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //创建bean实例,仅仅调用构造方法,但是尚未设置属性
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        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) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }
    
        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isTraceEnabled()) {
                logger.trace("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }
    
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //Bean属性填充
            populateBean(beanName, mbd, instanceWrapper);
            //调用初始化方法,应用BeanPostProcessor后置处理器
            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.");
                    }
                }
            }
        }
    
        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
    
        return exposedObject;
    }
    
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
    
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    
        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
    
        return wrappedBean;
    }
    

三、lazy-init 延迟加载机制原理

  • lazy-init 延迟加载机制分析
    1. 普通 Bean 的初始化是在容器启动初始化阶段执行的
    2. lazy-init=true修饰的 bean 是在从容器里第⼀次进行context.getBean() 时进行触发
    3. Spring 启动的时候会把所有bean信息(包括XML和注解)解
      析转化成Spring能够识别的BeanDefinition并存到Hashmap里供下面的初始化时用,然后对每个BeanDefinition 进行处理,如果是懒加载的则在容器初始化阶段不处理,其他的则在容器初始化阶段进行初始化并依赖注入

四、循环依赖

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容