深入理解Spring-IOC

作者:COLDE 文章內(nèi)容輸出來源:拉勾教育Java高薪訓(xùn)練營(yíng)課程

  1. IOC概述

1.1 什么是IOC

控制反轉(zhuǎn)(Inversion of Control,縮寫為IoC),是面向?qū)ο缶幊讨械囊环N設(shè)計(jì)原則,可以用來減低計(jì)算機(jī)代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡(jiǎn)稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉(zhuǎn),對(duì)象在被創(chuàng)建的時(shí)候,由一個(gè)調(diào)控系統(tǒng)內(nèi)所有對(duì)象的外界實(shí)體將其所依賴的對(duì)象的引用傳遞給它。也可以說,依賴被注入到對(duì)象中。

傳統(tǒng)開發(fā)模式
傳統(tǒng)開發(fā)模式.png
IoC模式
IOC容器.png

1.2 IOC解決了什么問題

演變.png
  • OOP開發(fā)模式

    UserService和UserDao深度耦合,當(dāng)UserDao發(fā)生變更時(shí),會(huì)聯(lián)動(dòng)引發(fā)UserService的變更,高層模塊依賴于底層模塊,違法依賴倒置原則。

  • IOP開發(fā)模式

    將UserDao抽象為IUserDao接口,UserService依賴于IUserDao抽象接口,不依賴其具體實(shí)現(xiàn),但在創(chuàng)建IUserDao實(shí)例對(duì)象時(shí)(new UserDaoImpl),UserService還是依賴其實(shí)例對(duì)象。

  • IoC開發(fā)模式

    對(duì)象之間只依賴于抽象規(guī)則,不依賴其具體實(shí)現(xiàn),具體實(shí)例的創(chuàng)建權(quán)限交由IOC容器進(jìn)行控制,極大的降低代碼的耦合

2. Spring IoC深入分析

IoC容器是Spring的核心模塊,是抽象了對(duì)象管理、依賴關(guān)系管理的框架解決方案。BeanFactory為頂層容器,不能被實(shí)例化,它定義了所有IoC容器必須遵從的一套原則,具體的容器實(shí)現(xiàn)可以增加額外的功能。以Spring Boot默認(rèn)加載容器AnnotationConfigApplicationContext為例,其繼承體系如下:

BeanFactory容器繼承體系.png

其中GenericApplicationContext持有一個(gè)BeanFactory的默認(rèn)實(shí)現(xiàn)類DefaultListableBeanFactory的實(shí)例對(duì)象,Spring Context使用代理模式使用該實(shí)例替它執(zhí)行BeanFactory接口定義的功能。DefaultListableBeanFactory繼承體系如下:


DefaultListableBeanFactory繼承體系.png
源碼分析
  • 源碼分析用例
public class AnnotationConfigApplicationContextTest {
        // 聲明配置Bean
    @Configuration
    public class BeanConfiguration {
        @Bean
        public TestBean getTestBean(){
            return new TestBean();
        }
    }
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfiguration.class);
        TestBean bean = applicationContext.getBean(TestBean.class);
        System.out.println(bean);
    }

}
  • Spring上下文容器初始化
public class GenericApplicationContext{
          public GenericApplicationContext() {
                     // 創(chuàng)建BeanFactory的默認(rèn)容器實(shí)現(xiàn)類,有關(guān)BeanFacory相關(guān)的大部分功能通過代理模式使用該實(shí)例進(jìn)行實(shí)現(xiàn)
              this.beanFactory = new DefaultListableBeanFactory();
         }
}
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

    private final AnnotatedBeanDefinitionReader reader;

    private final ClassPathBeanDefinitionScanner scanner;

    public AnnotationConfigApplicationContext() {
        // 配置Bean處理器
        this.reader = new AnnotatedBeanDefinitionReader(this);
        // 包掃描處理器
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

    // 注解方式上下文創(chuàng)建入口
    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        // 重載構(gòu)造方法,創(chuàng)建reader、scanner,調(diào)用父類構(gòu)造方法創(chuàng)建DefaultListableBeanFactory的實(shí)例對(duì)象
        this();
        // 注冊(cè)配置bean
        register(componentClasses);
        // 容器初始化核心方法
        refresh();
    }

    public void register(Class<?>... componentClasses) {
        this.reader.register(componentClasses);
    }

    public void scan(String... basePackages) {
        this.scanner.scan(basePackages);
    }

}
  • register:注冊(cè)配置Bean
public class AnnotatedBeanDefinitionReader {
  // 注冊(cè)bean入口
    public void register(Class<?>... componentClasses) {
        for (Class<?> componentClass : componentClasses) {
            registerBean(componentClass);
        }
    }
    public void registerBean(Class<?> beanClass) {
        doRegisterBean(beanClass, null, null, null, null);
    }
  private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
            @Nullable BeanDefinitionCustomizer[] customizers) {
        // 包裝為BeanDefinition對(duì)象
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }
    // 設(shè)置創(chuàng)建bean對(duì)象時(shí)的鉤子方法
        abd.setInstanceSupplier(supplier);
    // 獲取bean的Scope屬性
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
    // 獲取beanName
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
        // 處理bean上的注解
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        // 源碼略...
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    //調(diào)用BeanDefinitionReaderUtils.registerBeanDefinition
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
}
public abstract class BeanDefinitionReaderUtils {

}
    public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {

        //beanName注冊(cè)
        String beanName = definitionHolder.getBeanName();
    // 調(diào)用DefaultListableBeanFactory的registerBeanDefinition方法
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        //別名注冊(cè)
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }
public class DefaultListableBeanFactory{
  private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
  private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition){
        // 其他邏輯代碼略
      // 將bean信息包裝類放置到beanDefinitionMap中
        // 至此,bean注冊(cè)邏輯完成
      this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
  }
}
  • refresh:容器初始化核心邏輯分析
public class AbstractApplicationContext {

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 1、預(yù)處理設(shè)置啟動(dòng)時(shí)間活動(dòng)標(biāo)記
            prepareRefresh();
            // 2、獲取BeanFactory;默認(rèn)實(shí)現(xiàn)是DefaultListableBeanFactory,由GenericApplicationContext構(gòu)造方法中創(chuàng)建
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 3、BeanFactory的預(yù)準(zhǔn)備?作
            prepareBeanFactory(beanFactory);
            try {
                // 4、BeanFactory準(zhǔn)備?作完成后進(jìn)?的后置處理?作
                postProcessBeanFactory(beanFactory);

                // 5.1、實(shí)例化并調(diào)?實(shí)現(xiàn)了BeanFactoryPostProcessor接?的Bean
                // 5.2、解析配置類中Bean信息并注冊(cè)
                invokeBeanFactoryPostProcessors(beanFactory);

                // 6、注冊(cè)BeanPostProcessor(Bean的后置處理器)
                registerBeanPostProcessors(beanFactory);

                // 7、初始化MessageSource組件(做國(guó)際化功能;消息綁定,消息解析)
                initMessageSource();

                // 8、初始化事件派發(fā)器
                initApplicationEventMulticaster();

                // 9、鉤子方法,?類重寫這個(gè)?法,在容器刷新的時(shí)候可以?定義邏輯
                onRefresh();

                // 10、注冊(cè)應(yīng)?的監(jiān)聽器。就是注冊(cè)實(shí)現(xiàn)了ApplicationListener接?的監(jiān)聽器bean
                registerListeners();

                // 11、初始化所有剩下的?懶加載的單例bean
                finishBeanFactoryInitialization(beanFactory);

                // 12、完成context的刷新。主要是調(diào)?LifecycleProcessor的onRefresh()?法,并且發(fā)布事件
                finishRefresh();
            }
            catch (BeansException ex) { }
        }
    }
}
  • 解析配置類中的Bean信息并注冊(cè)
// 核心代碼
class ConfigurationClassBeanDefinitionReader {
    private void loadBeanDefinitionsForConfigurationClass(
            ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
                for (BeanMethod beanMethod : configClass.getBeanMethods()) {
                        // 解析配置類中的bean配置方法
            loadBeanDefinitionsForBeanMethod(beanMethod);
                        // 最終調(diào)用DefaultListableBeanFactory的registerBeanDefinition進(jìn)行bean的注冊(cè)
                        this.registry.registerBeanDefinition(beanName, beanDefToRegister);
        }
    }
      
}
  • 循環(huán)依賴對(duì)象創(chuàng)建分析
//開始初始化Bean
DefaultListableBeanFactory#preInstantiateSingletons 
 AbstractBeanFactory#getBean
  AbstractBeanFactory#doGetBean 
    // #從三級(jí)緩存中獲取Bean,解決循環(huán)依賴關(guān)鍵位置,第一次返回null
    DefaultSingletonBeanRegistry#getSingleton 
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
                // 從一級(jí)緩存獲取,獲取成功則對(duì)象已經(jīng)創(chuàng)建成功
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                                // 從二級(jí)緩存取
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                                                // 從三級(jí)緩存取,獲取成功則從三件緩存**剪切**對(duì)象到二級(jí)緩存
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }
      // 創(chuàng)建實(shí)例bean,還未對(duì)實(shí)例bean對(duì)象屬性進(jìn)行賦值
      AbstractAutowireCapableBeanFactory#doCreateBean
        AbstractAutowireCapableBeanFactory#createBeanInstance
//  將實(shí)例bean包裝未ObjectFactory對(duì)象,放入三級(jí)緩存提前暴露對(duì)象        DefaultSingletonBeanRegistry#addSingletonFactory(ObjectFactory)
           // 屬性填充
           AbstractAutowireCapableBeanFactory#populateBean 
            AbstractAutowireCapableBeanFactory#autowire*
             AbstractBeanFactory#getBean 
              AbstractBeanFactory#doGetBean 
               // 繼續(xù)嘗試從三級(jí)緩存中獲取對(duì)象,如獲取失敗,執(zhí)行bean創(chuàng)建邏輯,并放入緩存供依賴對(duì)象獲取填充
               DefaultSingletonBeanRegistry#getSingleton 
  • 循環(huán)依賴流程說明
    Spring-IOC-循環(huán)依賴.png

總結(jié)

Spring IoC將對(duì)象的創(chuàng)建權(quán)限和對(duì)象之間的依賴關(guān)系交由容器進(jìn)行管理,使得代碼之間的耦合度進(jìn)一步降低,業(yè)務(wù)開發(fā)時(shí),一旦對(duì)象之間的抽象關(guān)系確立,底層業(yè)務(wù)邏輯發(fā)生業(yè)務(wù)變更,無(wú)需修改上層邏輯即可實(shí)現(xiàn)業(yè)務(wù)的變更,達(dá)到對(duì)象之間只依賴與抽象而不依賴于具體實(shí)現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容