目录
1. 容器的初始化
(1)构造方法做的一些事
(2) register()注册配置类
2. refresh()
前面,我们把Bean的生命周期做了一个概述和梳理,为的是更深刻的理解Spring容器的启动及Bean的实例化过程,没有看过的,可以进去看一下(文章链接:Spring源码之Bean的生命周期_奔跑的蜗牛_Kieasr-CSDN博客),也有助于理解本文内容,本节会更详细、更全面的进入Spring容器的启动过程,直击Bean实例化的底层逻辑,为了方便大家阅读,由于内容较多,分成若干个篇幅,下面,进入第一篇——容器的启动:
1. 容器的初始化我们将Spring当成生产Bean的容器,里面放了N多个Bean对象。
ApplicationContext为Spring上下文的重要接口,它两个比较重要的实现类:
- AnnotationConfigApplicationContext
- ClassPathXmlApplicationContext
我们以AnnotationConfigApplicationContext为例,先看一下它的父类GenericApplicationContext:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry { private final DefaultListableBeanFactory beanFactory; public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
看它的构造方法:
public AnnotationConfigApplicationContext(Class>... componentClasses) { // this()会先调用父类GenericApplicationContext的无参构造方法,会构造一个BeanFactory——DefaultListableBeanFactory this(); register(componentClasses); refresh(); }(1)构造方法做的一些事
调用AnnotationConfigApplicationContext的构造方法之前, this()方法中会调用父类GenericApplicationContext的无参构造方法,会构造一个BeanFactory——DefaultListableBeanFactory,DefaultListableBeanFactory是容器的始祖,先看一下它的继承关系:
可以看出,DefaultListableBeanFactory 是一个集大成者。在 Spring 中,针对 Bean 的不同 *** 作都有不同的接口进行规范,每个接口都有自己对应的实现,最终在 DefaultListableBeanFactory 中将所有的实现汇聚到一起。
我先大概介绍一下每个类的作用:
-
BeanFactory:这个接口看名字就知道是一个 Bean 的工厂,这是Spring容器的顶层接口,BeanFactory 接口定义了各种获取 Bean 的方法、判断 Bean 是否存在、判断 Bean 是否单例等针对 Bean 的基础方法;
-
ListableBeanFactory:这个接口继承自 BeanFactory,在 BeanFactory 的基础上,扩展了 Bean 的查询方法,例如根据类型获取 BeanNames、根据注解获取 BeanNames、根据 Bean 获取注解等;
-
AutowireCapableBeanFactory:该接口继承自 BeanFactory,在 BeanFactory 的基础上,提供了 Bean 的创建、配置、注入、销毁等 *** 作。有时候我们需要自己手动注入 Bean 的时候,可以考虑通过实现该接口来完成。AutowireCapableBeanFactory 在 Spring Security 中有一个重要的应用就是 ObjectPostProcessor。
-
HierarchicalBeanFactory:该接口继承自 BeanFactory,并在 BeanFactory 基础上添加了获取 parent beanfactory 的方法;
-
SingletonBeanRegistry:这个接口定义了对单例 Bean 的定义以及获取方法;
-
ConfigurableBeanFactory:这个接口主要定了针对 BeanFactory 的各种配置以及销毁的方法;
-
ConfigurableListableBeanFactory:这是 BeanFactory 的配置清单,这里定义了忽略的类型、接口,通过 Bean 的名称获取 BeanDefinition 、冻结 BeanDefinition 等;
-
AliasRegistry:这个接口定义了对 alias 的注册、移除、判断以及查询 *** 作;
-
SimpleAliasRegistry:这个类实现了 AliasRegistry 接口并实现了它里边的方法,SimpleAliasRegistry 使用 ConcurrentHashMap 做载体,实现了对 alias 的注册、移除判断以及查询 *** 作;
-
DefaultSingletonBeanRegistry:这个类基于 Java 中的集合,对 SingletonBeanRegistry 接口进行了实现;
-
FactoryBeanRegistrySupport:该类继承自 DefaultSingletonBeanRegistry,并在 DefaultSingletonBeanRegistry 的基础上,增加了获取 FactoryBean 类型、移除 FactoryBean 缓存的方法等等 *** 作;
-
AbstractBeanFactory:实现了 ConfigurableBeanFactory 接口并继承自 FactoryBeanRegistrySupport,在 AbstractBeanFactory 中对 ConfigurableBeanFactory 中定义的方法进行了实现;
-
AbstractAutowireCapableBeanFactory:该类继承自 AbstractBeanFactory 并对 AutowireCapableBeanFactory 接口中定义的方法进行了落地实现;
-
BeanDefinitionRegistry:这个接口继承自 AliasRegistry 接口,并增加了一系列针对 BeanDefinition 的注册、移除、查询、判断等方法;
-
最后的 DefaultListableBeanFactory 自然就具备了上面所有的功能。
好了,我们回到在AnnotationConfigApplicationContext容器的构造方法,在这里会先初始化两个核心组件:
public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
a. AnnotatedBeanDefinitionReader为BeanDefinition读取器
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; // 创建一个@Conditional注解的解析器 this.conditionevaluator = new Conditionevaluator(registry, environment, null); // 注册BeanDefiniiton***** AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
进入registerAnnotationConfigProcessors()方法,Spring在构造AnnotatedBeanDefinitionReader的时候会在容器中注册许多组件,这里传进来的参数registry就是DefaultListableBeanFactory:
所属类:org.springframework.context.annotation.AnnotationConfigUtils
public static SetregisterAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { // 设置beanFactory的OrderComparator为AnnotationAwareOrderComparator // 它是一个Comparator(比较器),用来排序,比如new ArrayList<>().sort(Comparator) if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } // ContextAnnotationAutowireCandidateResolver类是注解候选解析器(主要处理@Lazy),用来推断某个Bean是否需要依赖注入 if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set beanDefs = new linkedHashSet<>(8); // 注册ConfigurationClassPostProcessor类型的BeanDefinition if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. // 注册CommonAnnotationBeanPostProcessor类型的BeanDefinition if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. // 注册PersistenceAnnotationBeanPostProcessor类型的BeanDefinition if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 注册EventListenerMethodProcessor类型的BeanDefinition,用来处理@EventListener注解 if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } // 注册DefaultEventListenerFactory类型的BeanDefinition,用来处理@EventListener注解 if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
AnnotationAwareOrderComparator类是一个比较器,后面排序会用到。
ContextAnnotationAutowireCandidateResolver类是注解候选解析器(主要处理@Lazy注解),它的最顶层父类SimpleAutowireCandidateResolver是用来解析BeanDefinition的isAutowireCandidate属性的,后面依赖注入的时候会用到。
所以,这两个类会在容器初始化的时候设置进去。
b.ClassPathBeanDefinitionScanner为扫描器,主要作用可以用来扫描得到并注册BeanDefinition,扫描某个包路径,对扫描到的类进行解析,例如:
@Test public void testClassPathBeanDefinitionScanner() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.refresh(); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext); scanner.scan("cn.kieasar"); System.out.println(applicationContext.getBean("goodsService")); }
同时进行设置:
i. 设置this.includeFilters = AnnotationTypeFilter(Component.class)
ii. 设置environment
iii. 设置resourceLoader
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { // 注册默认的注解过滤器,默认扫描@Component注解 registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }
进入registerDefaultFilters()方法:
所属类:org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
protected void registerDefaultFilters() { // 注册@Component对应的AnnotationTypeFilter,默认扫描@Component注解 this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter( ((Class extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip. } try { this.includeFilters.add(new AnnotationTypeFilter( ((Class extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }(2) register()注册配置类
接下来,AnnotationConfigApplicationContext的构造方法中的register()方法会把传进来的配置类封装成BeanDefinition,然后注册到Spring容器。
public void register(Class>... componentClasses) { Assert.notEmpty(componentClasses, "At least one component class must be specified"); this.reader.register(componentClasses); }
public void register(Class>... componentClasses) { for (Class> componentClass : componentClasses) { registerBean(componentClass); } }
最终会调用到doRegisterBean()方法:
所属类:org.springframework.context.annotation.AnnotatedBeanDefinitionReader
privatevoid doRegisterBean(Class beanClass, @Nullable String name, @Nullable Class extends Annotation>[] qualifiers, @Nullable Supplier supplier, @Nullable BeanDefinitionCustomizer[] customizers) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); if (this.conditionevaluator.shouldSkip(abd.getmetadata())) { return; } abd.setInstanceSupplier(supplier); // 解析@Scope注解的结果为Scopemetadata Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(abd); abd.setScope(scopemetadata.getScopeName()); String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null) { for (Class extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } if (customizers != null) { for (BeanDefinitionCustomizer customizer : customizers) { customizer.customize(abd); } } // 把BeanDefinition包装成BeanDefinitionHolder BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry); // 把BeanDefinition注册到Spring中 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
进入registerBeanDefinition()方法:
所属类:org.springframework.beans.factory.support.BeanDefinitionReaderUtils
public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); // 把BeanDefinition注册到beanDefinitionMap中 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }2. refresh()
容器的初始化工作之后,接下来就是执行refresh()方法了,refresh()是Spring 容器启动过程中的核心方法,也是最重要的,没有之一,Spring 容器启动、Bean的实例化等都必须执行该方法,该方法中包括:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 子类设置一下BeanFactory postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 把实现了BeanPostProcessor接口的类实例化并排序,并且加入到BeanFactory的beanPostProcessor属性中 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 国际化 initMessageSource(); // Initialize event multicaster for this context. // 初始化事件发布器,在单例池中创建了一个SimpleApplicationEventMulticaster类 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 这个方法着重理解模板设计模式,在springboot中,这个方法是用来做内嵌tomcat启动的 onRefresh(); // Check for listener beans and register them. // 往事件发布器中注册事件监听器,事件发布的核心逻辑在这里 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // Spring容器关闭时的 *** 作,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知 finishRefresh(); }
- prepareRefresh():
i. 记录启动时间;
ii. 可以允许子容器设置一些内容到Environment中
iii. 验证Environment中是否包括了必须要有的属性 - obtainFreshBeanFactory():主要的作用就是创建了一个BeanFactory——DefaultListableBeanFactory,进行BeanFactory的refresh,在这里会去调用子类的refreshBeanFactory方法,具体子类是怎么刷新的得看子类,然后再调用子类的getBeanFactory方法,重新得到一个BeanFactory;
- prepareBeanFactory(beanFactory):
- i. 设置beanFactory的类加载器;
ii. 设置表达式解析器:StandardBeanexpressionResolver,用来解析Spring中的表达式
iii. 添加PropertyEditorRegistrar:ResourceEditorRegistrar,PropertyEditor类型转化器注册器,用来注册一些默认的PropertyEditor;
iv. 添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个BeanPostProcessor,用来执行EnvironmentAware、ApplicationEventPublisherAware等回调方法;
v. 添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了这个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那么就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接
口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性的);
a. EnvironmentAware
b. EmbeddedValueResolverAware
c. ResourceLoaderAware
d. ApplicationEventPublisherAware
e. MessageSourceAware
f. ApplicationContextAware
g. 另外其实在构造BeanFactory的时候就已经提前添加了另外三个:
h. BeanNameAware
i. BeanClassLoaderAware
j. BeanFactoryAware。
vi. 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找Bean:
a. BeanFactory.class:当前BeanFactory对象
b. ResourceLoader.class:当前ApplicationContext对象
c. ApplicationEventPublisher.class:当前ApplicationContext对象
d. ApplicationContext.class:当前ApplicationContext对象
vii. 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个Bean添加到ApplicationContext中去,注意一个ApplicationListener只能是单例的;
viii. 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,是一个BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean。
ix. 添加一些单例bean到单例池:
a. "environment":Environment对象;
b. "systemProperties":System.getProperties()返回的Map对象;
c. "systemEnvironment":System.getenv()返回的Map对象; - postProcessBeanFactory(beanFactory) : 提供给AbstractApplicationContext的子类进行扩展,具体的子类,可以继续向BeanFactory中再添加一些东西
- invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor
i. 此时在BeanFactory中会存在一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor,它也是一个
BeanDefinitionRegistryPostProcessor
iii. 从BeanFactory中找到类型为BeanDefinitionRegistryPostProcessor的beanName,也就是ConfigurationClassPostProcessor, 然后调用BeanFactory的getBean方法得到实例对象
iv. 执行**ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()**方法:
a. 解析AppConfig类
b. 扫描得到BeanDefinition并注册
c. 解析@import,@Bean等注解得到BeanDefinition并注册
d. 详细的看另外的笔记,专门分析了ConfigurationClassPostProcessor是如何工作的
e. 在这里,我们只需要知道在这一步会去得到BeanDefinition,而这些BeanDefinition中可能存在BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,所以执行完ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法后,还需要继续执行其他BeanDefinitionRegistryPostProcessor的
postProcessBeanDefinitionRegistry()方法
v. 执行其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
vi. 执行所有BeanDefinitionRegistryPostProcessor的**postProcessBeanFactory()方法
vii. 第二阶段
viii. 从BeanFactory中找到类型为BeanFactoryPostProcessor的beanName,而这些BeanFactoryPostProcessor包括了上面的BeanDefinitionRegistryPostProcessor
ix. 执行还没有执行过的BeanFactoryPostProcessor的postProcessBeanFactory()方法 - 到此,所有的BeanFactoryPostProcessor的逻辑都执行完了,主要做的事情就是得到BeanDefinition并注册到BeanFactory中
- registerBeanPostProcessors(beanFactory):因为上面的步骤完成了扫描,这个过程中程序员可能自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象,并添加到BeanFactory中去(属性beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后)
- initMessageSource():如果BeanFactory中存在一个叫做"messageSource"的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的messageSource属性,让ApplicationContext拥有国际化的功能
- initApplicationEventMulticaster():如果BeanFactory中存在一个叫做"applicationEventMulticaster"的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性,让ApplicationContext拥有事件发布的功能
- onRefresh():提供给AbstractApplicationContext的子类进行扩展,Springboot
- registerListeners():从BeanFactory中获取ApplicationListener类型的beanName,然后添加到ApplicationContext中的事件广播器applicationEventMulticaster中去,到这一步因为FactoryBean还没有调用getObject()方法生成Bean对象,所以这里要在根据类型找一下ApplicationListener,记录一下对应的beanName
- finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化非懒加载的单例Bean,单独的笔记去讲。
- finishRefresh():BeanFactory的初始化完后,就到了Spring启动的最后一步了
- 设置ApplicationContext的lifecycleProcessor,默认情况下设置的是DefaultLifecycleProcessor
- 调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命周期扩展机制
- 发布ContextRefreshedEvent事件
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)