深入理解Spring-IOC

2020-04-03  本文已影响0人  colde_包包白

作者:COLDE 文章内容输出来源:拉勾教育Java高薪训练营课程

  1. IOC概述

1.1 什么是IOC

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

传统开发模式
传统开发模式.png
IoC模式
IOC容器.png

1.2 IOC解决了什么问题

演变.png

2. Spring IoC深入分析

IoC容器是Spring的核心模块,是抽象了对象管理、依赖关系管理的框架解决方案。BeanFactory为顶层容器,不能被实例化,它定义了所有IoC容器必须遵从的一套原则,具体的容器实现可以增加额外的功能。以Spring Boot默认加载容器AnnotationConfigApplicationContext为例,其继承体系如下:

BeanFactory容器继承体系.png

其中GenericApplicationContext持有一个BeanFactory的默认实现类DefaultListableBeanFactory的实例对象,Spring Context使用代理模式使用该实例替它执行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);
    }

}
public class GenericApplicationContext{
          public GenericApplicationContext() {
                     // 创建BeanFactory的默认容器实现类,有关BeanFacory相关的大部分功能通过代理模式使用该实例进行实现
              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);
    }

    // 注解方式上下文创建入口
    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        // 重载构造方法,创建reader、scanner,调用父类构造方法创建DefaultListableBeanFactory的实例对象
        this();
        // 注册配置bean
        register(componentClasses);
        // 容器初始化核心方法
        refresh();
    }

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

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

}
public class AnnotatedBeanDefinitionReader {
  // 注册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对象
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }
    // 设置创建bean对象时的钩子方法
        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);
    //调用BeanDefinitionReaderUtils.registerBeanDefinition
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
}
public abstract class BeanDefinitionReaderUtils {

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

        //beanName注册
        String beanName = definitionHolder.getBeanName();
    // 调用DefaultListableBeanFactory的registerBeanDefinition方法
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        //别名注册
        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注册逻辑完成
      this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
  }
}
public class AbstractApplicationContext {

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 1、预处理设置启动时间活动标记
            prepareRefresh();
            // 2、获取BeanFactory;默认实现是DefaultListableBeanFactory,由GenericApplicationContext构造方法中创建
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 3、BeanFactory的预准备⼯作
            prepareBeanFactory(beanFactory);
            try {
                // 4、BeanFactory准备⼯作完成后进⾏的后置处理⼯作
                postProcessBeanFactory(beanFactory);

                // 5.1、实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
                // 5.2、解析配置类中Bean信息并注册
                invokeBeanFactoryPostProcessors(beanFactory);

                // 6、注册BeanPostProcessor(Bean的后置处理器)
                registerBeanPostProcessors(beanFactory);

                // 7、初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
                initMessageSource();

                // 8、初始化事件派发器
                initApplicationEventMulticaster();

                // 9、钩子方法,⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
                onRefresh();

                // 10、注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean
                registerListeners();

                // 11、初始化所有剩下的⾮懒加载的单例bean
                finishBeanFactoryInitialization(beanFactory);

                // 12、完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事件
                finishRefresh();
            }
            catch (BeansException ex) { }
        }
    }
}
// 核心代码
class ConfigurationClassBeanDefinitionReader {
    private void loadBeanDefinitionsForConfigurationClass(
            ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
                for (BeanMethod beanMethod : configClass.getBeanMethods()) {
                        // 解析配置类中的bean配置方法
            loadBeanDefinitionsForBeanMethod(beanMethod);
                        // 最终调用DefaultListableBeanFactory的registerBeanDefinition进行bean的注册
                        this.registry.registerBeanDefinition(beanName, beanDefToRegister);
        }
    }
      
}
//开始初始化Bean
DefaultListableBeanFactory#preInstantiateSingletons 
 AbstractBeanFactory#getBean
  AbstractBeanFactory#doGetBean 
    // #从三级缓存中获取Bean,解决循环依赖关键位置,第一次返回null
    DefaultSingletonBeanRegistry#getSingleton 
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
                // 从一级缓存获取,获取成功则对象已经创建成功
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                                // 从二级缓存取
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                                                // 从三级缓存取,获取成功则从三件缓存**剪切**对象到二级缓存
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }
      // 创建实例bean,还未对实例bean对象属性进行赋值
      AbstractAutowireCapableBeanFactory#doCreateBean
        AbstractAutowireCapableBeanFactory#createBeanInstance
//  将实例bean包装未ObjectFactory对象,放入三级缓存提前暴露对象        DefaultSingletonBeanRegistry#addSingletonFactory(ObjectFactory)
           // 属性填充
           AbstractAutowireCapableBeanFactory#populateBean 
            AbstractAutowireCapableBeanFactory#autowire*
             AbstractBeanFactory#getBean 
              AbstractBeanFactory#doGetBean 
               // 继续尝试从三级缓存中获取对象,如获取失败,执行bean创建逻辑,并放入缓存供依赖对象获取填充
               DefaultSingletonBeanRegistry#getSingleton 

总结

Spring IoC将对象的创建权限和对象之间的依赖关系交由容器进行管理,使得代码之间的耦合度进一步降低,业务开发时,一旦对象之间的抽象关系确立,底层业务逻辑发生业务变更,无需修改上层逻辑即可实现业务的变更,达到对象之间只依赖与抽象而不依赖于具体实现。

上一篇下一篇

猜你喜欢

热点阅读