您好,歡迎來到賦能網(wǎng)!

pring ioc容器初始化過程是怎樣的詳解

賦能網(wǎng) 2023-05-09 50

下面要給大家?guī)淼木褪?strong>springioc理解和初始化過程方面的內(nèi)容,你對于這點有足夠的了解嗎?一起通過下文來進行學(xué)習(xí)吧。

下面對spring ioc容器的啟動過程進行一下詳細的介紹:

啟動容器

AnnotationConfigApplicationContext anno = new AnnotationConfigApplicationContext(MainConfig.class);

進入AnnotationConfigApplicationContext類當(dāng)中。

代碼,scan方法對包進行掃描,進行refresh方法,容器的刷新和IOC容器的創(chuàng)建。

 public AnnotationConfigApplicationContext(String...basePackages)
 {
     this();
     this.scan(basePackages);
     this.refresh();
 }

首先的話是refresh方法加入線程安全鎖,之后再調(diào)用prepareRefresh方法中,進行類加載前的刷新前的預(yù)處理。

public void refresh() throws BeansException, IllegalStateException
{
    synchronized(this.startupShutdownMonitor)
    { //加入線程安全鎖
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        this.prepareBeanFactory(beanFactory);
        try
        {
            this.postProcessBeanFactory(beanFactory);
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        }
        catch (BeansException var9)
        {
            if (this.logger.isWarnEnabled())
            {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }
            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        }
        finally
        {
            this.resetCommonCaches();
        }
    }
}

進入prepareRefresh方法中。

這個方法是由AbstractApplicationContext抽象類提供的公共方法。

protected void prepareRefresh()
{
    this.startupDate = System.currentTimeMillis(); //記錄開始時間
    this.closed.set(false); //記錄狀態(tài),當(dāng)前容器關(guān)不了嗎?
    this.active.set(true);
    if (this.logger.isInfoEnabled())
    {
        this.logger.info("Refreshing " + this);
    }
    this.initPropertySources(); //初始化一些屬性設(shè)計(此方法為空,留在子類做事情的,由子類來自定義屬性設(shè)置)
    this.getEnvironment()
        .validateRequiredProperties(); //檢驗屬性的合法性
    this.earlyApplicationEvents = new linkedHashSet(); //保存容器中早期的一些事件
}

通過obtainFreshBeanFactory方法獲取BeanFactory。

這個方法一個是refreshBeanFactory方法另一個是getBeanFactory方法。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory()
{
    this.refreshBeanFactory(); //刷新BeanFactory
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); //獲取BeanFactory的對象
    if (this.logger.isDebugEnabled())
    {
        this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

進入refreshBeanFactory方式當(dāng)中。

這個方法是AbstractApplicationContext類提供一個抽象的方法,GenericApplicationContext類實現(xiàn)了這個方法,設(shè)置了id標(biāo)識并創(chuàng)建beanFactory對象。

protected final void refreshBeanFactory() throws IllegalStateException
{
    if (!this.refreshed.compareAndSet(false, true))
    {
        throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call refresh once");
    }
    else
    {
        this.beanFactory.setSerializationId(this.getId());
    }
}

現(xiàn)在執(zhí)行this.prepareBeanFactory(beanFactory)方法,這個方法BeanFactory的預(yù)準(zhǔn)備工作(對beanFactory進行設(shè)置)。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
{
    beanFactory.setBeanClassLoader(this.getClassLoader()); //設(shè)置BeanFactory的類加載器
    beanFactory.setBeanexpressionResolver(new StandardBeanexpressionResolver(beanFactory.getBeanClassLoader())); //支持表達式解析器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //設(shè)置PostProcessorf
    //設(shè)置忽略的自動裝配的接口
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    //注冊可以解析自動裝配;我們能直接在任何組件中自動注入
    //BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //添加編譯時的AspectJ
    if (beanFactory.containsBean("loadTimeWeaver"))
    {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    if (!beanFactory.containsLocalBean("environment"))
    { //環(huán)境
        beanFactory.registerSingleton("environment", this.getEnvironment());
    }
    if (!beanFactory.containsLocalBean("systemProperties"))
    { //系統(tǒng)屬性
        beanFactory.registerSingleton("systemProperties", this.getEnvironment()
            .getSystemProperties());
    }
    if (!beanFactory.containsLocalBean("systemEnvironment"))
    { //系統(tǒng)環(huán)境信息
        beanFactory.registerSingleton("systemEnvironment", this.getEnvironment()
            .getSystemEnvironment());
    }
}

this.postProcessBeanFactory(beanFactory)方法對BeanFactory準(zhǔn)備工作完成之后,進行的后置處理工作。

方法為空。

子類通過重寫這個方法在BeanFactory創(chuàng)建并且準(zhǔn)備完成以后做進一步的設(shè)置。

上面的內(nèi)容是BeanFactory的創(chuàng)建和預(yù)準(zhǔn)備工作。

this.invokeBeanFactoryPostProcessors(beanFactory)方法進行BeanFactory的后置處理器。在BeanFactory標(biāo)準(zhǔn)初始化之后執(zhí)行的。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)
{
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver"))
    {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

執(zhí)行BeanFactoryProcessorr的方法。

跟進這個方法。

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List < BeanFactoryPostProcessor > beanFactoryPostProcessors)
{
    Set < String > processedBeans = new HashSet();
    int var9;
    ArrayList currentRegistryProcessors;
    String[] postProcessorNames;
    if (beanFactory instanceof BeanDefinitionRegistry)
    { //先判斷BeanFactory是不是BeanDefinitionRegistry類型
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List < BeanFactoryPostProcessor > regularPostProcessors = new linkedList();
        List < BeanDefinitionRegistryPostProcessor > registryProcessors = new linkedList();
        Iterator var6 = beanFactoryPostProcessors.iterator();
        while (var6.hasNext())
        {
            BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor) var6.next();
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor)
            {
                BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else
            {
                regularPostProcessors.add(postProcessor);
            }
        }
        currentRegistryProcessors = new ArrayList();
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //獲取BeanDefinitionRegistryPostProcessor
        String[] var18 = postProcessorNames;
        var9 = postProcessorNames.length;
        int var10;
        String ppName;
        //遍歷所有的BeanDifinitionRgPostProcessor
        for (var10 = 0; var10 < var9; ++var10)
        {
            ppName = var18[var10];
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class))
            { //判斷是否實現(xiàn)了PriortyOrder接口
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName); //將處理過的bean存儲起來
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory); //優(yōu)先級進行排序
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //進行執(zhí)行
        currentRegistryProcessors.clear(); //清楚
        //在執(zhí)行實現(xiàn)了Ordered順序接口的BeanDefinitionRegistryPostProcessor
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        var18 = postProcessorNames;
        var9 = postProcessorNames.length;
        for (var10 = 0; var10 < var9; ++var10)
        {
            ppName = var18[var10];
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class))
            {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();
        boolean reiterate = true;
        while (reiterate)
        {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            String[] var21 = postProcessorNames;
            var10 = postProcessorNames.length;
            for (int var28 = 0; var28 < var10; ++var28)
            {
                String ppName = var21[var28];
                if (!processedBeans.contains(ppName))
                {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }
        invokeBeanFactoryPostProcessors((Collection) registryProcessors, (ConfigurableListableBeanFactory) beanFactory);
        invokeBeanFactoryPostProcessors((Collection) regularPostProcessors, (ConfigurableListableBeanFactory) beanFactory);
    }
    else
    {
        invokeBeanFactoryPostProcessors((Collection) beanFactoryPostProcessors, (ConfigurableListableBeanFactory) beanFactory);
    }
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    List < BeanFactoryPostProcessor > priorityOrderedPostProcessors = new ArrayList();
    List < String > orderedPostProcessorNames = new ArrayList();
    currentRegistryProcessors = new ArrayList();
    postProcessorNames = postProcessorNames;
    int var22 = postProcessorNames.length;
    String ppName;
    for (var9 = 0; var9 < var22; ++var9)
    {
        ppName = postProcessorNames[var9];
        if (!processedBeans.contains(ppName))
        {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class))
            {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class))
            {
                orderedPostProcessorNames.add(ppName);
            }
            else
            {
                currentRegistryProcessors.add(ppName);
            }
        }
    }
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors((Collection) priorityOrderedPostProcessors, (ConfigurableListableBeanFactory) beanFactory);
    List < BeanFactoryPostProcessor > orderedPostProcessors = new ArrayList();
    Iterator var23 = orderedPostProcessorNames.iterator();
    while (var23.hasNext())
    {
        String postProcessorName = (String) var23.next();
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors((Collection) orderedPostProcessors, (ConfigurableListableBeanFactory) beanFactory);
    List < BeanFactoryPostProcessor > nonOrderedPostProcessors = new ArrayList();
    Iterator var26 = currentRegistryProcessors.iterator();
    while (var26.hasNext())
    {
        ppName = (String) var26.next();
        nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors((Collection) nonOrderedPostProcessors, (ConfigurableListableBeanFactory) beanFactory);
    beanFactory.clearmetadataCache();
}

invokeBeanDefinitionRegistryPostProcessors方法中,在執(zhí)行實現(xiàn)了Ordered順序接口的BeanDefinitionRegistryPostProcessor;

private static void invokeBeanDefinitionRegistryPostProcessors(Collection < ? extends BeanDefinitionRegistryPostProcessor > postProcessors, BeanDefinitionRegistry registry)
{
    Iterator var2 = postProcessors.iterator();
    while (var2.hasNext())
    {
        BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor) var2.next();
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}

this.registerBeanPostProcessors(beanFactory)這個方法為注冊BeanPostProcessor(Bean的后置處理器)。

{
    //獲取所有的后置處理器
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    List < BeanPostProcessor > priorityOrderedPostProcessors = new ArrayList();
    List < BeanPostProcessor > internalPostProcessors = new ArrayList();
    List < String > orderedPostProcessorNames = new ArrayList();
    List < String > nonOrderedPostProcessorNames = new ArrayList();
    String[] var8 = postProcessorNames;
    int var9 = postProcessorNames.length;
    String ppName;
    BeanPostProcessor pp;
    //循環(huán)所有的后置處理器,進行優(yōu)先級的處理
    for (int var10 = 0; var10 < var9; ++var10)
    {
        ppName = var8[var10];
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class))
        { //判斷是否是PriorityOrdered類型的類添加到priorityOrderedPostProcessors集合中
            pp = (BeanPostProcessor) beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor)
            {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class))
        { //判斷是否是Ordered類型添加到orderedPostProcessorNames集合中
            orderedPostProcessorNames.add(ppName);
        }
        else
        {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
    //對priorityOrderedPostProcessors進行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);、
    registerBeanPostProcessors(beanFactory, (List) priorityOrderedPostProcessors);
    List < BeanPostProcessor > orderedPostProcessors = new ArrayList();
    Iterator var14 = orderedPostProcessorNames.iterator();
    while (var14.hasNext())
    {
        String ppName = (String) var14.next();
        BeanPostProcessor pp = (BeanPostProcessor) beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp); //添加到orderedPostProcessors中
        //MergedBeanDefinitionPostProcessor則是在合并處理Bean定義的時候的回調(diào)。也基本是框架內(nèi)部使用的,
        if (pp instanceof MergedBeanDefinitionPostProcessor)
        {
            internalPostProcessors.add(pp);
        }
    }
    //對orderedPostProcessors進行排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List) orderedPostProcessors);
    List < BeanPostProcessor > nonOrderedPostProcessors = new ArrayList();
    Iterator var17 = nonOrderedPostProcessorNames.iterator();
    while (var17.hasNext())
    {
        ppName = (String) var17.next();
        pp = (BeanPostProcessor) beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        //MergedBeanDefinitionPostProcessor則是在合并處理Bean定義的時候的回調(diào)。也基本是框架內(nèi)部使用的,
        if (pp instanceof MergedBeanDefinitionPostProcessor)
        {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, (List) nonOrderedPostProcessors);
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List) internalPostProcessors);
    //注冊一個ApplicationListenerDetector;來在Bean創(chuàng)建完成后檢查是否是ApplicationListener
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

this.initMessageSource()方法為初始化MessageSource組件(做國際化,消息綁定,消息解析)。

protected void initMessageSource()
{
    //獲取Beanfactory
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
    //判斷beanFactory中是否存在messageSource類
    if (beanFactory.containsLocalBean("messageSource"))
    {
        //獲取messageSource類
        this.messageSource = (MessageSource) beanFactory.getBean("messageSource", MessageSource.class);
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource)
        {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null)
            {
                hms.setParentMessageSource(this.getInternalParentMessageSource());
            }
        }
        if (this.logger.isDebugEnabled())
        {
            this.logger.debug("Using MessageSource [" + this.messageSource + "]");
        }
    }
    else
    {
        //如果不存在,new一個DelegatingMessageSource 
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(this.getInternalParentMessageSource());
        this.messageSource = dms;
        beanFactory.registerSingleton("messageSource", this.messageSource);
        if (this.logger.isDebugEnabled())
        {
            this.logger.debug("Unable to locate MessageSource with name messageSource: using default [" + this.messageSource + "]");
        }
    }
}

this.initApplicationEventMulticaster方法為初始化事件派發(fā)器。

protected void initApplicationEventMulticaster()
{
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
    //判斷工廠是否存在applicationEventMulticaster的applicationEventMulticaster
    if (beanFactory.containsLocalBean("applicationEventMulticaster"))
    {
        this.applicationEventMulticaster = (ApplicationEventMulticaster) beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
        if (this.logger.isDebugEnabled())
        {
            this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else
    {
        //如果不存在,自己創(chuàng)建一個DelegatingMessageSource
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
        if (this.logger.isDebugEnabled())
        {
            this.logger.debug("Unable to locate ApplicationEventMulticaster with name applicationEventMulticaster: using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

onrefresh();//空方法,留給子容器(子類),子類重寫這個方法,在容器刷新的時候可以自定義邏輯。

 protected void onRefresh() throws BeansException
 {}

this.registerListeners()方法將容器中所有項目里面的ApplicationListener注冊進來。

protected void registerListeners()
{
    Iterator var1 = this.getApplicationListeners()
        .iterator(); //獲取時間派發(fā)器中的監(jiān)聽
    while (var1.hasNext())
    {
        ApplicationListener < ? > listener = (ApplicationListener) var1.next();
        //將監(jiān)聽添加到事件派發(fā)器中 
        this.getApplicationEventMulticaster()
            .addApplicationListener(listener); //添加監(jiān)聽
    }
    //從容器中獲取監(jiān)聽
    String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
    String[] var7 = listenerBeanNames;
    int var3 = listenerBeanNames.length;
    for (int var4 = 0; var4 < var3; ++var4)
    {
        String listenerBeanName = var7[var4];
        //將監(jiān)聽添加到事件派發(fā)器中            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    Set < ApplicationEvent > earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null)
    {
        Iterator var9 = earlyEventsToProcess.iterator();
        while (var9.hasNext())
        {
            ApplicationEvent earlyEvent = (ApplicationEvent) var9.next();
            //派發(fā)之前步驟產(chǎn)生的事件
            this.getApplicationEventMulticaster()
                .multicastEvent(earlyEvent);
        }
    }
}

this.finishBeanFactoryInitialization(beanFactory)方法將所有單實例bean創(chuàng)建。

finishRefresh()完成BeanFactory的初始化創(chuàng)建工作,ioc容器創(chuàng)建完成。

protected void finishRefresh()
{
    //清除環(huán)境級別的緩存
    this.clearResourceCaches();
    //初始化與生命周期有關(guān)的后置處理
    this.initLifecycleProcessor();
    //拿到上面定義的生命周期處理器,回調(diào)onRefresh
    this.getLifecycleProcessor()
        .onRefresh();
    //發(fā)布容器刷新完成容器時間
    this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
    //暴露一些 Mbean類
    LiveBeansView.registerApplicationContext(this);
}

此文源于網(wǎng)絡(luò),僅供參考,假如你還想了解更多的java編程常見問題,可以繼續(xù)的通過關(guān)注賦能網(wǎng)來進行相關(guān)內(nèi)容的獲取哦。


本文鏈接:

本文章“pring ioc容器初始化過程是怎樣的詳解”已幫助 50 人

免責(zé)聲明:本信息由用戶發(fā)布,本站不承擔(dān)本信息引起的任何交易及知識產(chǎn)權(quán)侵權(quán)的法律責(zé)任!

本文由賦能網(wǎng) 整理發(fā)布。了解更多培訓(xùn)機構(gòu)》培訓(xùn)課程》學(xué)習(xí)資訊》課程優(yōu)惠》課程開班》學(xué)校地址等機構(gòu)信息,可以留下您的聯(lián)系方式,讓課程老師跟你詳細解答:
咨詢熱線:4008-569-579

如果本頁不是您要找的課程,您也可以百度查找一下: