前言
之前我们分析了SpringApplication#run方法的前5步.接下来我们分析第6步.创建ApplicationContext.前5步如下:
- 初始化StopWatch,调用其start方法开始计时.
- 设置系统属性java.awt.headless,这里设置为true,表示运行在服务器端,在没有显示器和鼠标键盘的模式下工作,模拟输入输出设备功能
- 调用SpringApplicationRunListeners#starting
- 创建一个DefaultApplicationArguments对象,调用prepareEnvironment方法进行 Environment的设置
- 打印banner
分析
第6步是通过调用SpringApplication#createApplicationContext方法完成的.代码如下:
protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { contextClass = Class.forName(this.webEnvironment ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass); }
很简单.通过判断当前是否是web环境决定创建什么类,如果是web程序,那么创建org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext的实例,否则创建org.springframework.context.annotation.AnnotationConfigApplicationContext的实例,这些都是定义在SpringApplication类的静态属性中.
由于我们一般都是在web环境中,因此会初始化AnnotationConfigEmbeddedWebApplicationContext.
AnnotationConfigEmbeddedWebApplicationContext 类的继承关系如下:
通过类初始化顺序可知.首先会初始化DefaultResourceLoader.其构造器如下:
public DefaultResourceLoader() { this.classLoader = ClassUtils.getDefaultClassLoader(); }
只是获得了一个类加载器.
接下来初始化AbstractApplicationContext.其构造器如下:
public AbstractApplicationContext() { this.resourcePatternResolver = 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.beanFactory = new DefaultListableBeanFactory(); }
DefaultListableBeanFactory的初始化.DefaultListableBeanFactory的继承关系如下:
还是通过继承关系可知.会首先初始化SimpleAliasRegistry.其构造器为默认的无参构造器.没有做任何事.接下来初始化DefaultSingletonBeanRegistry,FactoryBeanRegistrySupport.同样是默认的无参构造器.没有做任何事.
接下来初始化AbstractBeanFactory.其构造器如下:
public AbstractBeanFactory() { }
接着初始化AbstractAutowireCapableBeanFactory.构造器如下:
public AbstractAutowireCapableBeanFactory() { super(); ignoreDependencyInterface(BeanNameAware.class); ignoreDependencyInterface(BeanFactoryAware.class); ignoreDependencyInterface(BeanClassLoaderAware.class); }
调用了ignoreDependencyInterface.将BeanNameAware,BeanFactoryAware,BeanClassLoaderAware 添加至ignoreDependencyInterface中.这是因为后续的context初始化时会对其进行处理.代码如下:
public void ignoreDependencyInterface(Class<?> ifc) { this.ignoredDependencyInterfaces.add(ifc); }
接着初始化DefaultListableBeanFactory.构造器如下:
public DefaultListableBeanFactory() { super(); }
至此DefaultListableBeanFactory 也就初始化完毕了. 也就意味着GenericApplicationContext初始化完毕.
接下来 初始化GenericWebApplicationContext,EmbeddedWebApplicationContext.其构造器都是使用的默认的.没有做任何事.
最后,初始化AnnotationConfigEmbeddedWebApplicationContext.其构造器如下:
public AnnotationConfigEmbeddedWebApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
初始化了AnnotatedBeanDefinitionReader,ClassPathBeanDefinitionScanner.
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"); if (registry instanceof EnvironmentCapable) { return ((EnvironmentCapable) registry).getEnvironment(); } return new StandardEnvironment(); }
注意这里的registry为AnnotationConfigEmbeddedWebApplicationContext.因此会通过调用AbstractApplicationContext#getEnvironment 获得Environment.代码如下:
public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = createEnvironment(); } return this.environment; }
由于此时environment 为null,因此调用GenericWebApplicationContext#createEnvironment进行创建.代码如下:
protected ConfigurableEnvironment createEnvironment() { return new StandardServletEnvironment(); }
StandardServletEnvironment 继承关系如下:
在AbstractEnvironment 初始化时,调用了customizePropertySources方法.
public AbstractEnvironment() { customizePropertySources(this.propertySources); if (logger.isDebugEnabled()) { logger.debug("Initialized " + getClass().getSimpleName() + " with PropertySources " + this.propertySources); } }
调用StandardServletEnvironment#customizePropertySources,代码如下:
protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME)); propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)); if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME)); } super.customizePropertySources(propertySources); }
- 添加名为servletConfigInitParams的StubPropertySource
- 添加名为servletContextInitParams的StubPropertySource
如果是在jndi的环境中,则添加名为jndiProperties的JndiPropertySource.默认为false.
JndiLocatorDelegate#isDefaultJndiEnvironmentAvailable代码如下:
public static boolean isDefaultJndiEnvironmentAvailable() { if (shouldIgnoreDefaultJndiEnvironment) { return false; } try { new InitialContext().getEnvironment(); return true; } catch (Throwable ex) { return false; } }
如果忽略jndi环境,则返回false.shouldIgnoreDefaultJndiEnvironment定义在JndiLocatorDelegate中,代码如下:
private static final boolean shouldIgnoreDefaultJndiEnvironment = SpringProperties.getFlag(IGNORE_JNDI_PROPERTY_NAME);
调用
public static boolean getFlag(String key) { return Boolean.parseBoolean(getProperty(key)); }
调用
public static String getProperty(String key) { String value = localProperties.getProperty(key); if (value == null) { try { value = System.getProperty(key); } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug("Could not retrieve system property '" + key + "': " + ex); } } } return value; }
- 在SpringProperties中尝试加载spring.properties中的配置,由于默认清情况下,不存在,则会返回null.
- 从系统配置中读取spring.jndi.ignore的配置,由于我们没有配置,因此,还是返回null.
因此,此处返回false.
尝试通过InitialContext#getEnvironment 判断是否存在jndi.如果抛出异常,则返回false,否则,返回true.
默认情况下,此处会抛出异常,因此返回的是false
调用父类(StandardEnvironment)的customizePropertySources方法,代码如下:
protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); }
因此 StandardEnvironment 也就持有了servletConfigInitParams,servletContextInitParams,systemProperties,systemEnvironment 4个PropertySource.
之后调用AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment)构造器进行初始化.
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; this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
做了2件事.
- 初始化了ConditionEvaluator,用于对@Conditional 注解的使用.
向AnnotationConfigEmbeddedWebApplicationContext进行注册.代码如下:
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) { registerAnnotationConfigProcessors(registry, 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<BeanDefinitionHolder>(4); 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)); } 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)); } if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. 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. 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)); } 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)); } 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; }
做了10件事.
获得DefaultListableBeanFactory 代码如下:
private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) { if (registry instanceof DefaultListableBeanFactory) { return (DefaultListableBeanFactory) registry; } else if (registry instanceof GenericApplicationContext) { return ((GenericApplicationContext) registry).getDefaultListableBeanFactory(); } else { return null; } }
由于AnnotationConfigEmbeddedWebApplicationContext本身就是DefaultListableBeanFactory子类,因此这里将AnnotationConfigEmbeddedWebApplicationContext向上转型为DefaultListableBeanFactory后返回.
如果DefaultListableBeanFactory中的DependencyComparator不是AnnotationAwareOrderComparator实例的话,就设置DependencyComparator为AnnotationAwareOrderComparator.这里一般都会进行设置的.
如果DefaultListableBeanFactory中的AutowireCandidateResolver不是ContextAnnotationAutowireCandidateResolver实例的话,就实例化为ContextAnnotationAutowireCandidateResolver.
- 如果不包含org.springframework.context.annotation.internalConfigurationAnnotationProcessor 的bean的定义.就注册一个bean class为 ConfigurationClassPostProcessor
- 如果不包含org.springframework.context.annotation.internalAutowiredAnnotationProcessor 的 bean, 就注册一个 bean class 为 AutowiredAnnotationBeanPostProcessor
- 如果不包含org.springframework.context.annotation.internalRequiredAnnotationProcessor的 bean, 就注册一个 bean class 为 RequiredAnnotationBeanPostProcessor
- 如果当前类路径存在javax.annotation.Resource.并且registry中不包含org.springframework.context.annotation.internalCommonAnnotationProcessor的定义,那么就注册一个 bean class 为 CommonAnnotationBeanPostProcessor 的bean. 一般都会进行注册的.
- 如果当前类路径存在javax.persistence.EntityManagerFactory和 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor 并且registry中不包含org.springframework.context.annotation.internalPersistenceAnnotationProcessor的 定义,那么就注册一个 class 为 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor 的bean. 一般都会进行注册的.
- 如果registry 不包含org.springframework.context.event.internalEventListenerProcessor的 定义.就注册一个bean class 为 EventListenerMethodProcessor 的定义
- 如果registry 不包含org.springframework.context.event.internalEventListenerFactory的 定义. 就注册一个 class 为 DefaultEventListenerFactory 的定义
接下来初始化ClassPathBeanDefinitionScanner.其继承关系如下:
还是同样的套路. ClassPathBeanDefinitionScanner的初始化会触发ClassPathScanningCandidateComponentProvider的初始化.其构造器如下:protected ClassPathScanningCandidateComponentProvider() { }
然后初始化 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"); if (registry instanceof EnvironmentCapable) { return ((EnvironmentCapable) registry).getEnvironment(); } return 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) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }
3步:
如果使用默认过滤器的话,就调用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( ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.debug("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 { // 3. 添加AnnotationTypeFilter --> javax.inject.Named this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }
依旧3步:
- 添加AnnotationTypeFilter–>Component
- 添加AnnotationTypeFilter –> ManagedBean
- 添加AnnotationTypeFilter –> javax.inject.Named
设置Environment,就是简单的赋值,代码如下:
public void setEnvironment(Environment environment) { Assert.notNull(environment, "Environment must not be null"); this.environment = environment; this.conditionEvaluator = null; }
设置ResourceLoader.执行如下代码:
public void setResourceLoader(ResourceLoader resourceLoader) { // 1. 设置ResourcePatternResolver this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); // 2. 实例化CachingMetadataReaderFactory this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader); }
2 步:
设置ResourcePatternResolver.执行如下代码:
public static ResourcePatternResolver getResourcePatternResolver(ResourceLoader resourceLoader) { if (resourceLoader instanceof ResourcePatternResolver) { return (ResourcePatternResolver) resourceLoader; } else if (resourceLoader != null) { return new PathMatchingResourcePatternResolver(resourceLoader); } else { return new PathMatchingResourcePatternResolver(); } }
由于当前环境下resourceLoader 是 ResourcePatternResolver的实例,因此直接返回.
实例化CachingMetadataReaderFactory.
至此.SpringApplication#run 中的第6步–> 创建AnnotationConfigEmbeddedWebApplicationContext也就分析完了.