SpringApplication#run⽅法的第6步,创建ApplicationContext(五)

    技术2022-07-13  123

    前⾔

    之前我们分析了SpringApplication#run⽅法的前5步.接下来我们分析第6步.创建ApplicationContext.前5步如下:

    1. 初始化StopWatch,调⽤其start⽅法开始计时. 2. 设置系统属性java.awt.headless,这⾥设置为true,表示运⾏在服务器端,在没有显示器和⿏标键盘的模式下⼯作,模拟输⼊输出设备功能 3. 调⽤SpringApplicationRunListeners#starting 4. 创建⼀个DefaultApplicationArguments对象,调⽤prepareEnvironment⽅法进⾏ Environment的设置 5. 打印banner

    分析

    1. 第6步是通过调⽤SpringApplication#createApplicationContext⽅法完成的.代码如下:

    protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { contextClass = Class.forName(this.webEnvironment ? "org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext" : "org.springframework.context.annotation.AnnotationConfigApplicationContext"); } catch (ClassNotFoundException var3) { throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3); } } return (ConfigurableApplicationContext)BeanUtils.instantiate(contextClass); }

    很简单.通过判断当前是否是web环境决定创建什么类,如果是web程序,那么创建org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext的实例,否则创建org.springframework.context.annotation.AnnotationConfigApplicationContext的实例,这些都是定义在SpringApplication类的静态属性中。

    由于我们⼀般都是在web环境中,因此会初始化AnnotationConfigEmbeddedWebApplicationContext。

    2. AnnotationConfigEmbeddedWebApplicationContext 类的继承关系如下:

     通过类初始化顺序可知.⾸先会初始化DefaultResourceLoader.其构造器如下:

    public DefaultResourceLoader() { this.classLoader = ClassUtils.getDefaultClassLoader(); }

    只是获得了⼀个类加载器.

    接下来初始化AbstractApplicationContext.其构造器如下:

    public AbstractApplicationContext() { this.logger = LogFactory.getLog(this.getClass()); this.id = ObjectUtils.identityToString(this); this.displayName = ObjectUtils.identityToString(this); this.beanFactoryPostProcessors = new ArrayList(); this.active = new AtomicBoolean(); this.closed = new AtomicBoolean(); this.startupShutdownMonitor = new Object(); this.applicationListeners = new LinkedHashSet(); this.resourcePatternResolver = this.getResourcePatternResolver(); }

    调⽤了getResourcePatternResolver⽅法获得ResourcePatternResolver.代码如下:

    protected ResourcePatternResolver getResourcePatternResolver() { return new PathMatchingResourcePatternResolver(this); }

    将⾃⼰对于当前场景来说是AnnotationConfigEmbeddedWebApplicationContext传⼊了进去.构造器如下:

    public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) { Assert.notNull(resourceLoader, "ResourceLoader must not be null"); this.resourceLoader = resourceLoader; }

    接下来初始化GenericApplicationContext.其构造如下:

    public GenericApplicationContext() { this.customClassLoader = false; this.refreshed = new AtomicBoolean(); this.beanFactory = new DefaultListableBeanFactory(); }

    3. DefaultListableBeanFactory的初始化.DefaultListableBeanFactory的继承关系如下:

    还是通过继承关系可知.会⾸先初始化SimpleAliasRegistry.其构造器为默认的⽆参构造器.没有做任何事。 接下来初始化DefaultSingletonBeanRegistry,FactoryBeanRegistrySupport.同样是默认的⽆参构造器.没有做任何事。 接下来初始化AbstractBeanFactory.其构造器如下:

    public AbstractBeanFactory() { }

    接着初始化AbstractAutowireCapableBeanFactory.构造器如下:

    public AbstractAutowireCapableBeanFactory() { this.instantiationStrategy = new CglibSubclassingInstantiationStrategy(); this.parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); this.allowCircularReferences = true; this.allowRawInjectionDespiteWrapping = false; this.ignoredDependencyTypes = new HashSet(); this.ignoredDependencyInterfaces = new HashSet(); this.factoryBeanInstanceCache = new ConcurrentHashMap(16); this.filteredPropertyDescriptorsCache = new ConcurrentHashMap(256); this.ignoreDependencyInterface(BeanNameAware.class); this.ignoreDependencyInterface(BeanFactoryAware.class); this.ignoreDependencyInterface(BeanClassLoaderAware.class); }

    调⽤了ignoreDependencyInterface.将BeanNameAware,BeanFactoryAware,BeanClassLoaderAware 添加⾄ignoreDependencyInterface中.这是因为后续的context初始化时会对其进⾏处理.代码如下:

    public void ignoreDependencyInterface(Class<?> ifc) { this.ignoredDependencyInterfaces.add(ifc); }

    接着初始化DefaultListableBeanFactory.构造器如下:

    public DefaultListableBeanFactory() { }

    ⾄此DefaultListableBeanFactory 也就初始化完毕了. 也就意味着GenericApplicationContext初始化完毕。

    4. 接下来 初始化GenericWebApplicationContext,EmbeddedWebApplicationContext.其构造器都是使⽤的默认的.没有做任何事。  5. 最后,初始化AnnotationConfigEmbeddedWebApplicationContext.其构造器如下:

    public AnnotationConfigEmbeddedWebApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }

    AnnotatedBeanDefinitionReader构造器如下:

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); }

    ⾸先调⽤getOrCreateEnvironment⽅法获得Environment:

    private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); return (Environment)(registry instanceof EnvironmentCapable ? ((EnvironmentCapable)registry).getEnvironment() : new StandardEnvironment()); }

    注意这⾥的registry为AnnotationConfigEmbeddedWebApplicationContext.因此会通过调⽤AbstractApplicationContext#getEnvironment 获得Environment.代码如下:

    public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = this.createEnvironment(); } return this.environment; }

    由于此时environment 为null,因此调⽤createEnvironment进⾏创建.代码如下:

    protected ConfigurableEnvironment createEnvironment() { return new StandardEnvironment(); }

    StandardEnvironment 继承关系如下:

    在AbstractEnvironment 初始化时,调⽤了customizePropertySources⽅法:

    public AbstractEnvironment() { this.propertySources = new MutablePropertySources(this.logger); this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources); this.customizePropertySources(this.propertySources); if (this.logger.isDebugEnabled()) { this.logger.debug("Initialized " + this.getClass().getSimpleName() + " with PropertySources " + this.propertySources); } }

    StandardEnvironment 实现如下:

    protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new MapPropertySource("systemProperties", this.getSystemProperties())); propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment())); }

    因此 StandardEnvironment 也就持有了systemProperties, systemEnvironment 2个PropertySource。

    之后调⽤AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment)构造器进⾏初始化.

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { this.beanNameGenerator = new AnnotationBeanNameGenerator(); this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(); Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }

    做了2件事。

    1. 初始化了ConditionEvaluator,⽤于对@Conditional 注解的使⽤. 2. 向AnnotationConfigEmbeddedWebApplicationContext进⾏注册.代码如下:

    public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) { registerAnnotationConfigProcessors(registry, (Object)null); }

    调⽤

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(4); RootBeanDefinition def; if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) { def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) { def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor")) { def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor")); } if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) { def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor")); } if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) { def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException var6) { throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) { def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) { def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory")); } return beanDefs; }

    做了10件事. 1. 获得DefaultListableBeanFactory 代码如下:

    private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) { if (registry instanceof DefaultListableBeanFactory) { return (DefaultListableBeanFactory)registry; } else { return registry instanceof GenericApplicationContext ? ((GenericApplicationContext)registry).getDefaultListableBeanFactory() : null; } }

    由于AnnotationConfigEmbeddedWebApplicationContext本身就是DefaultListableBeanFactory⼦类,因此这⾥将AnnotationConfigEmbeddedWebApplicationContext向上转型为DefaultListableBeanFactory后返回。

    2. 如果DefaultListableBeanFactory中的DependencyComparator不是AnnotationAwareOrderComparator实例的话,就设置DependencyComparator为AnnotationAwareOrderComparator.这⾥⼀般都会进⾏设置的。

    3. 如果DefaultListableBeanFactory中的AutowireCandidateResolver不是ContextAnnotationAutowireCandidateResolver实例的话,就实例化为ContextAnnotationAutowireCandidateResolver.

    4. 如果不包含org.springframework.context.annotation.internalConfigurationAnnotationProcessor 的bean的定义.就注册⼀个bean class为ConfigurationClassPostProcessor

    5. 如果不包含org.springframework.context.annotation.internalAutowiredAnnotationProcessor 的 bean, 就注册⼀个 bean class 为AutowiredAnnotationBeanPostProcessor

    6. 如果不包含org.springframework.context.annotation.internalRequiredAnnotationProcessor的 bean, 就注册⼀个 bean class 为RequiredAnnotationBeanPostProcessor

    7. 如果当前类路径存在javax.annotation.Resource.并且registry中不包含org.springframework.context.annotation.internalCommonAnnotationProcessor的定义,那么就注册⼀个 bean class 为CommonAnnotationBeanPostProcessor 的bean. ⼀般都会进⾏注册的.

    8. 如果当前类路径存在javax.persistence.EntityManagerFactory和org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor 并且registry中不包含org.springframework.context.annotation.internalPersistenceAnnotationProcessor的 定义,那么就注册⼀个 class 为 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor 的bean. ⼀般都会进⾏注册的.

    9. 如果registry 不包含org.springframework.context.event.internalEventListenerProcessor的 定义.就注册⼀个bean class 为 EventListenerMethodProcessor 的定义

    10. 如果registry 不包含org.springframework.context.event.internalEventListenerFactory的 定义. 就注册⼀个 class 为 DefaultEventListenerFactory 的定义  

    6. 接下来初始化ClassPathBeanDefinitionScanner.其继承关系如下:

     还是同样的套路. ClassPathBeanDefinitionScanner的初始化会触发ClassPathScanningCandidateComponentProvider的初始化。其构造器如下:

    protected ClassPathScanningCandidateComponentProvider() { this.logger = LogFactory.getLog(this.getClass()); this.resourcePattern = "**/*.class"; this.includeFilters = new LinkedList(); this.excludeFilters = new LinkedList(); }

    然后初始化 ClassPathBeanDefinitionScanner.构造器如下:

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) { this(registry, true); }

    注意这⾥传⼊的registry为AnnotationConfigEmbeddedWebApplicationContext。

    接着调⽤如下构造器:

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { this(registry, useDefaultFilters, getOrCreateEnvironment(registry)); }

    这⾥调⽤getOrCreateEnvironment⽅法获得Environment.代码如下:

    private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); return (Environment)(registry instanceof EnvironmentCapable ? ((EnvironmentCapable)registry).getEnvironment() : new StandardEnvironment()); }

    由于在构造AnnotatedBeanDefinitionReader 已经初始化了Environment.因此这⾥就直接返回了StandardEnvironment.

    接下来调⽤如下构造器:

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) { this(registry, useDefaultFilters, environment, registry instanceof ResourceLoader ? (ResourceLoader)registry : null); }

    由于AnnotationConfigEmbeddedWebApplicationContext实现了ResourceLoader接⼝,因此这⾥将AnnotationConfigEmbeddedWebApplicationContext向上转型为ResourceLoader.

    进⽽调⽤如下构造器:

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, ResourceLoader resourceLoader) { this.beanDefinitionDefaults = new BeanDefinitionDefaults(); this.beanNameGenerator = new AnnotationBeanNameGenerator(); this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(); this.includeAnnotationConfig = true; Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { this.registerDefaultFilters(); } this.setEnvironment(environment); this.setResourceLoader(resourceLoader); }

    3步: 1. 如果使⽤默认过滤器的话,就调⽤registerDefaultFilters进⾏注册,⼀般都是为true的.因此为执⾏如下代码:

    protected void registerDefaultFilters() { // 1. 添加AnnotationTypeFilter-->Component this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { // 2. 添加AnnotationTypeFilter --> ManagedBean this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false)); this.logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException var4) { ; } try { // 3. 添加AnnotationTypeFilter --> javax.inject.Named this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false)); this.logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException var3) { ; } }

    依旧3步:

    1. 添加AnnotationTypeFilter-->Component2. 添加AnnotationTypeFilter --> ManagedBean3. 添加AnnotationTypeFilter --> javax.inject.Named

    2. 设置Environment,就是简单的赋值,代码如下:

    public void setEnvironment(Environment environment) { Assert.notNull(environment, "Environment must not be null"); this.environment = environment; this.conditionEvaluator = null; }

    3. 设置ResourceLoader.执⾏如下代码:

    public void setResourceLoader(ResourceLoader resourceLoader) { this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader); }

    2 步:

    1. 设置ResourcePatternResolver.执⾏如下代码: public static ResourcePatternResolver getResourcePatternResolver(ResourceLoader resourceLoader) { if (resourceLoader instanceof ResourcePatternResolver) { return (ResourcePatternResolver)resourceLoader; } else { return resourceLoader != null ? new PathMatchingResourcePatternResolver(resourceLoader) : new PathMatchingResourcePatternResolver(); } }

    由于当前环境下resourceLoader 是 ResourcePatternResolver的实例,因此直接返回.

    2. 实例化CachingMetadataReaderFactory

    ⾄此.SpringApplication#run 中的第6步--> 创建AnnotationConfigEmbeddedWebApplicationContext也就分析完了。  

    Processed: 0.012, SQL: 9