SpringBoot启动流程源码分析( 七 )

复制
SpringApplication#postProcessApplicationContext方法protected void postProcessApplicationContext(ConfigurableApplicationContext context) {if (this.beanNameGenerator != null) {context.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", this.beanNameGenerator); // 应用上下文中的beanFactory注册单例BeanNameGenerator bean}if (this.resourceLoader != null) {if (context instanceof GenericApplicationContext) {((GenericApplicationContext)context).setResourceLoader(this.resourceLoader);// 设置资源加载器}if (context instanceof DefaultResourceLoader) {((DefaultResourceLoader)context).setClassLoader(this.resourceLoader.getClassLoader());// 设置类加载器}}if (this.addConversionService) {context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());// 设置conversionService属性}}复制
SpringApplication#applyInitializers方法protected void applyInitializers(ConfigurableApplicationContext context) {// 获取初始化器迭代器Iterator var2 = this.getInitializers().iterator();// 循环遍历初始化器迭代器while(var2.hasNext()) {ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();// 根据解析器calss类型和应用上下文初始化器calss类型解析参数类型Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");initializer.initialize(context);}}复制
GenericTypeResolver#resolveTypeArgument方法@Nullablepublic static Class<?> resolveTypeArgument(Class<?> clazz, Class<?> genericIfc) {ResolvableType resolvableType = ResolvableType.forClass(clazz).as(genericIfc);return !resolvableType.hasGenerics() ? null : getSingleGeneric(resolvableType);}// 加载解析类public static ResolvableType forClass(@Nullable Class<?> clazz) {return new ResolvableType(clazz);}// 判断是否有解析类型数组public boolean hasGenerics() {return this.getGenerics().length > 0;}// 获取单个解析类型@Nullableprivate static Class<?> getSingleGeneric(ResolvableType resolvableType) {Assert.isTrue(resolvableType.getGenerics().length == 1, () -> {return "Expected 1 type argument on generic interface [" + resolvableType + "] but found " + resolvableType.getGenerics().length;});return resolvableType.getGeneric(new int[0]).resolve();}复制
加载Spring应用上下文中的beanSpringApplication#load方法protected void load(ApplicationContext context, Object[] sources) {if (logger.isDebugEnabled()) {// 如果开启了debug级别日志 , 则记录debug日志logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));}// 创建BeanDefinitionLoader类实例BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);if (this.beanNameGenerator != null) {loader.setBeanNameGenerator(this.beanNameGenerator);}if (this.resourceLoader != null) {loader.setResourceLoader(this.resourceLoader);}if (this.environment != null) {loader.setEnvironment(this.environment);}loader.load();}// 通过BeanDefinitionRegistry类实例参数和应用源数组构造BeanDefinitionLoader类实例protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {return new BeanDefinitionLoader(registry, sources); }复制
BeanDefinitionLoader类带两个参数的构造方法源码:
BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {// 断言registry和sources两个参数不能为空Assert.notNull(registry, "Registry must not be null");Assert.notEmpty(sources, "Sources must not be empty");this.sources = sources;// 初始化基于注解的BeanDefinitionReaderthis.annotatedReader = new AnnotatedBeanDefinitionReader(registry);// 初始化基于xml的BeanDefinitionReaderthis.xmlReader = new XmlBeanDefinitionReader(registry);if (this.isGroovyPresent()) {// 如果存在groovy脚本则初始化基于Groovy的BeanDefinitionReaderthis.groovyReader = new GroovyBeanDefinitionReader(registry);}// 初始化类路径bean定义扫描器this.scanner = new ClassPathBeanDefinitionScanner(registry);// 扫描器添加排除过滤器 , 排除扫描启动类this.scanner.addExcludeFilter(new BeanDefinitionLoader.ClassExcludeFilter(sources));}

经验总结扩展阅读