Spring 的 初始化 ------- refresh()

5 篇文章 0 订阅
1 篇文章 0 订阅

Spring 的初始化

想必,Spring 不陌生吧,Java 中核心框架了吧,面试官常问的一个点,源码写的也是最漂亮的一个框架。 核心是 IOC 和 AOP , IOC 说白了 就是一个容器,将所有的都放在一起进行管理 ,AOP 就是动态的在你执行这些 Bean 中的方法的时候,加入一些增强的功能。Spring 也强大在于它的兼容性,其中容器在初始化的时候就是一个加载 Bean 的过程,十分重要。

Spring IOC 有几种初始化的方式

  • ClassPathXmlApplicationContext 类路径加载
ApplicationContext act = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
  • FileSystemXmlApplicationContext 文件系统加载
ApplicationContext act = new FileSystemXmlApplicationContext("src/main/resources/applicationContext.xml");
  • AnnotationConfigApplicationContext 注解扫描获取
ApplicationContext ioc =
		new AnnotationConfigApplicationContext("com.itcast.pojo");
  • GenericGroovyApplicationContext 通过Groovy 获取元数据
		GenericGroovyApplicationContext context = new GenericGroovyApplicationContext("SpringConfig.groovy");

基于XML 配置获取 , 基于注解扫描获取, 基于Groovy 获取

初始化容器的方法

获取容器的每个类点进去都是都是走到了同一个方法 this.refresh(); 这个方法就是初始化的核心

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

我们跟进去

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh(); // 1.
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 2. 
            this.prepareBeanFactory(beanFactory); // 3. 

            try {
                this.postProcessBeanFactory(beanFactory);  // 4. 
                this.invokeBeanFactoryPostProcessors(beanFactory); // 5. 
                this.registerBeanPostProcessors(beanFactory);  // 6.
                this.initMessageSource();  // 7.
                this.initApplicationEventMulticaster(); // 8.
                this.onRefresh();   // 9 .
                this.registerListeners();  // 10.
                this.finishBeanFactoryInitialization(beanFactory); // 11. 
                this.finishRefresh();  //11.
            } 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();
            }

        }
    }

接下来就对于每一个方法,都干了什么进行解剖

1. prepareRefresh()

protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        if (this.logger.isDebugEnabled()) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Refreshing " + this);
            } else {
                this.logger.debug("Refreshing " + this.getDisplayName());
            }
        }

        this.initPropertySources();
        this.getEnvironment().validateRequiredProperties();
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
        } else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        this.earlyApplicationEvents = new LinkedHashSet();
    }

除过一些打印日志的方法,其中重要的就三个方法

  • initPropertySources(); 初始化一些属性设置,其中是空实现留给子类扩展
  • getEnvironment().validateRequiredProperties(); 创建environment 对象,保存属性值 ,检验属性的合法等
  • earlyApplicationEvents = new LinkedHashSet(); 保存容器中一些早期事件。
    总结来看 :
    1. 创建和准备了Environment 对象
    2. Environment 是为属性注入是提供键值对信息

2. obtainFreshBeanFactory()

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

这个方法比较简单就是将 BeanFactory 进行创建和刷新,然后进行返回
refreshBeanFactory(); : 的实现是由 GenericApplicationContext 进行实现, 在这个类加载的时候
在构造方法中将 bean 工厂进行创建。而实际方法中只是进行了初始值的刷新,为bean 工厂设置一个id

this.beanFactory = new DefaultListableBeanFactory();

getBeanFactory(); 就是将这个bean 工厂进行返回


特别的是 BeanFactory 是负责 bean 的创建,依赖注入和初始化等功能
而且 BeanFactory 成员变量也有很多,起着很重要的作用,

Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);

这个是其中一个成员变量, BeanDefinition 就是十分重要的那一个,规定了Bean 的特征,初始化,依赖关系,销毁方法等。
总结一下:
1. 这一步用来创建和刷新 BeanFactory
2. Bean Factory 是 是负责 bean 的创建,依赖注入和初始化等功能
3. BeanDefinition 规定了Bean 的特征,初始化,依赖关系,销毁方法等。
4. BeanDefinition 的获取来源有很多,XML ,配置类, 组件扫描,编程添加。

3. prepareBeanFactory(beanFactory)

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        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.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
        if (beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        if (!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if (!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if (!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

    }

这步就是将 Bean Factory 创建好的对象传入,进行初始化,

  • 设置BeanFactory 的类加载器,支持表达式解析器
  • 添加部分 BeanPostProcessor 【ApplicationContextAwareProcessor】
  • 设置忽略自动装配的接口 EnviromentAware
  • 解析自动装配,我们能再任何组件中自动注入
  • 添加BeanPostProcessor
  • 添加编译时的AspectJ
  • 给Bean Factory 添加一些可用的组件

总结

  1. 完善BeanFactory
  2. StandardBeanExpressionResolver 来解析 SpEL
  3. ResourceEditorRegistrar 注册类型转换器的,并应用 ApplicationContext 的 Enviroment 完成对 ${}解析
  4. 特殊bean 是指 BeanFactory 以及ApplicationContext 通过 registerResolvableDependency 来注册他们
  5. ApplicationContextAwareProcessor 来解析 Aware 接口

4. postProcessBeanFactory(beanFactory)

 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

提供空实现,留给子类扩展,利用它注册新的 Scope ,完善 Web 下的BeanFactory
体现的是模板方法模式。

5. invokeBeanFactoryPostProcessors(beanFactory)

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()));
        }

    }

BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标注初始化之后执行​ 有两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

执行invokeBeanFactoryPostProcessors方法

  • 获取所有BeanDefinitionRegistryPostProcessor
    • 先执行实现了PriorityOrdered优先级接口的、再执行实现了Ordered的接口的、最后执行其它的
  • 获取所有BeanFactoryPostProcessor
    • 先执行实现了PriorityOrdered优先级接口的、再执行实现了Ordered的接口的、最后执行其它的

总结:
1. beanFactory 的后处理器,充当beanFactory 的扩展点,可用来补充和修改 BeanDefinition
2. ConfigurationClassPostProcessor 用来解析 @ Configuration , @Import ,@ Bean , @PropertyResource
3. PropertyResourcePlaceHolderConfiguration 中的${}

6. registerBeanPostProcessors(beanFactory)

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
  • 这一步是继续从 beanFactory 中找出 bean 后处理器,添加至 beanPostProcessors 集合中
  • Bean 的后置处理器,充当Bean 的扩展点,可以再Bean 的依赖注入实例化,初始化阶段。
    • AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解
    • CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy
    • AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标 bean 自动创建代理

7. initMessageSource()

protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("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.isTraceEnabled()) {
                this.logger.trace("Using MessageSource [" + this.messageSource + "]");
            }
        } else {
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(this.getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton("messageSource", this.messageSource);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("No 'messageSource' bean, using [" + this.messageSource + "]");
            }
        }

    }
  • 这一步是为 ApplicationContext 添加 messageSource 成员,实现国际化功能
  • 去 beanFactory 内找名为 messageSource 的 bean,如果没有,则提供空的 MessageSource 实现

8. initApplicationEventMulticaster()

protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
            }
        }

    }
  • 这一步为 ApplicationContext 添加事件广播器成员,即 applicationContextEventMulticaster
  • 它的作用是发布事件给监听器
  • 去 beanFactory 找名为 applicationEventMulticaster 的 bean 作为事件广播器,若没有,会创建默认的事件广播器
  • 之后就可以调用 ApplicationContext.publishEvent(事件对象) 来发布事件

9. onRefresh()

protected void onRefresh() throws BeansException {
    }
  • 这一步是空实现,留给子类扩展
    • SpringBoot 中的子类在这里准备了 WebServer,即内嵌 web 容器
  • 体现的是模板方法设计模式

10 . registerListeners()

  • 这一步会从多种途径找到事件监听器,并添加至 applicationEventMulticaster
  • 事件监听器顾名思义,用来接收事件广播器发布的事件,有如下来源
    • 事先编程添加的
    • 来自容器中的 bean
    • 来自于 @EventListener 的解析
  • 要实现事件监听器,只需要实现 ApplicationListener 接口,重写其中 onApplicationEvent(E e) 方法即可

11 .finishBeanFactoryInitialization(beanFactory)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }
  • 这一步会将 beanFactory 的成员补充完毕,并初始化所有非延迟单例 bean
  • conversionService 也是一套转换机制,作为对 PropertyEditor 的补充
  • embeddedValueResolvers 即内嵌值解析器,用来解析 @Value 中的 ${ },借用的是 Environment 的功能
  • singletonObjects 即单例池,缓存所有单例对象
    • 对象的创建都分三个阶段,每一阶段都有不同的 bean 后处理器参与进来,扩展功能

12. finishRefresh()

protected void finishRefresh() {
        this.clearResourceCaches();
        this.initLifecycleProcessor();
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
        LiveBeansView.registerApplicationContext(this);
    }
  • 这一步会为 ApplicationContext 添加 lifecycleProcessor 成员,用来控制容器内需要生命周期管理的 bean
  • 如果容器中有名称为 lifecycleProcessor 的 bean 就用它,否则创建默认的生命周期管理器
  • 准备好生命周期管理器,就可以实现
    • 调用 context 的 start,即可触发所有实现 LifeCycle 接口 bean 的 start
    • 调用 context 的 stop,即可触发所有实现 LifeCycle 接口 bean 的 stop
  • 发布 ContextRefreshed 事件,整个 refresh 执行完成

总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值