游戏类网站怎么做济南今日头条新闻
作为Spring Boot应用启动的核心入口,SpringApplication.run()方法承载着从环境准备到上下文初始化的全流程控制,而SpringApplication的构造函数则是这一流程的基石。通过解析其构造逻辑,可深入理解Spring Boot如何根据主配置类推断应用类型、加载初始化组件,并为后续的自动装配和上下文构建奠定基础。接下来将以该项目中ExcelApplication类开启Spring源码解析之旅。源码跳转
SpringApplication构造函数
// SpringApplication.run()方法默认调用构造函数,传入配置类public SpringApplication(Class<?>... primarySources) {this(null, primarySources);}// 资源加载器,默认传入null 配置类public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 推断应用的web服务类型 NONE(应用服务不作为web服务器使用)SERVLET(作为SERVLET服务器) REACTIVE(作为响应式web服务器)this.webApplicationType = WebApplicationType.deduceFromClasspath();// 从spring.factories获取Bootstrap上下文初始化(BootstrapContext初始化使用)this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));// 从spring.factories获取Application上下文初始化(ApplicationContext初始化使用)setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 从spring.factories获取ApplicationListener监听器(发布Spring事件的时候使用)setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 推断main方法启动类this.mainApplicationClass = deduceMainApplicationClass();}// 获取指定类型spring.factories配置的类实例private <T> List<T> getSpringFactoriesInstances(Class<T> type) {return getSpringFactoriesInstances(type, null);}private <T> List<T> getSpringFactoriesInstances(Class<T> type, ArgumentResolver argumentResolver) {// 获取默认加载文件(spring.factories)的SpringFactoriesLoader来加载类实例 argumentResolver是构造实例时用到的参数return SpringFactoriesLoader.forDefaultResourceLocation(getClassLoader()).load(type, argumentResolver);}// 推断main方法类private Class<?> deduceMainApplicationClass() {// StackWalker.Option.RETAIN_CLASS_REFERENCE保留类引用return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)// 查找main方法class.walk(this::findMainClass).orElse(null);}private Optional<Class<?>> findMainClass(Stream<StackFrame> stack) {// 获取方法名字是main的类return stack.filter((frame) -> Objects.equals(frame.getMethodName(), "main")).findFirst().map(StackWalker.StackFrame::getDeclaringClass);}
推断服务类型
static WebApplicationType deduceFromClasspath() {if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {// 存在DispatcherHandler类且没有DispatcherServlet类和ServletContainer的时候是响应式服务器return WebApplicationType.REACTIVE;}for (String className : SERVLET_INDICATOR_CLASSES) {if (!ClassUtils.isPresent(className, null)) {// 不存在任何Servlet类的时候return WebApplicationType.NONE;}}return WebApplicationType.SERVLET;}
SpringFactoriesLoader加载解析
// resourceLocation:加载的文件(默认META-INF/spring.factoriespublic static SpringFactoriesLoader forResourceLocation(String resourceLocation, @Nullable ClassLoader classLoader) {Assert.hasText(resourceLocation, "'resourceLocation' must not be empty");ClassLoader resourceClassLoader = (classLoader != null ? classLoader :SpringFactoriesLoader.class.getClassLoader());// 用类加载器从缓存中获取 不存在新增Map<String, SpringFactoriesLoader> loaders = cache.computeIfAbsent(resourceClassLoader, key -> new ConcurrentReferenceHashMap<>());// 使用加载文件名字从缓存中获取 不存在构建SpringFactoriesLoaderreturn loaders.computeIfAbsent(resourceLocation, key ->new SpringFactoriesLoader(classLoader, loadFactoriesResource(resourceClassLoader, resourceLocation)));}// 加载resourceLocation文件中的配置protected static Map<String, List<String>> loadFactoriesResource(ClassLoader classLoader, String resourceLocation) {Map<String, List<String>> result = new LinkedHashMap<>();try {// 读取指定目录文件Enumeration<URL> urls = classLoader.getResources(resourceLocation);while (urls.hasMoreElements()) {UrlResource resource = new UrlResource(urls.nextElement());// 加载Properties Properties properties = PropertiesLoaderUtils.loadProperties(resource);properties.forEach((name, value) -> {// 使用 , 拆分成数组String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String) value);// 使用配置key从map中获取 不存在的时候新增List<String> implementations = result.computeIfAbsent(((String) name).trim(),key -> new ArrayList<>(factoryImplementationNames.length));// trim后添加Arrays.stream(factoryImplementationNames).map(String::trim).forEach(implementations::add);});}// 全部去重替换成不可变listresult.replaceAll(SpringFactoriesLoader::toDistinctUnmodifiableList);}catch (IOException ex) {throw new IllegalArgumentException("Unable to load factories from location [" + resourceLocation + "]", ex);}return Collections.unmodifiableMap(result);}
SpringFactoriesLoader加载类实例
public <T> List<T> load(Class<T> factoryType, @Nullable ArgumentResolver argumentResolver,@Nullable FailureHandler failureHandler) {Assert.notNull(factoryType, "'factoryType' must not be null");// 根据factoryType获取到配置的对应实例类名List<String> implementationNames = loadFactoryNames(factoryType);logger.trace(LogMessage.format("Loaded [%s] names: %s", factoryType.getName(), implementationNames));List<T> result = new ArrayList<>(implementationNames.size());// 异常处理 默认抛出异常FailureHandler failureHandlerToUse = (failureHandler != null) ? failureHandler : THROWING_FAILURE_HANDLER;for (String implementationName : implementationNames) {// 实例化类T factory = instantiateFactory(implementationName, factoryType, argumentResolver, failureHandlerToUse);if (factory != null) {result.add(factory);}}// 排序AnnotationAwareOrderComparator.sort(result);return result;}protected <T> T instantiateFactory(String implementationName, Class<T> type,@Nullable ArgumentResolver argumentResolver, FailureHandler failureHandler) {try {// 加载类Class<?> factoryImplementationClass = ClassUtils.forName(implementationName, this.classLoader);Assert.isTrue(type.isAssignableFrom(factoryImplementationClass), () ->"Class [%s] is not assignable to factory type [%s]".formatted(implementationName, type.getName()));// 用于实例化类的工厂FactoryInstantiator<T> factoryInstantiator = FactoryInstantiator.forClass(factoryImplementationClass);// 实例化return factoryInstantiator.instantiate(argumentResolver);}catch (Throwable ex) {failureHandler.handleFailure(type, implementationName, ex);return null;}}
构建FactoryInstantiator,实例化对应类
static <T> FactoryInstantiator<T> forClass(Class<?> factoryImplementationClass) {// 查找构造方法Constructor<?> constructor = findConstructor(factoryImplementationClass);Assert.state(constructor != null, () ->"Class [%s] has no suitable constructor".formatted(factoryImplementationClass.getName()));return new FactoryInstantiator<>((Constructor<T>) constructor);}private static Constructor<?> findConstructor(Class<?> factoryImplementationClass) {// Same algorithm as BeanUtils.getResolvableConstructor// Kotlin忽略Constructor<?> constructor = findPrimaryKotlinConstructor(factoryImplementationClass);// 查找public的构造函数 仅有一个的时候获取constructor = (constructor != null ? constructor :findSingleConstructor(factoryImplementationClass.getConstructors()));// 不存在的时候 获取当前类定义的构造方法 仅有一个的时候获取constructor = (constructor != null ? constructor :findSingleConstructor(factoryImplementationClass.getDeclaredConstructors()));// 不存在的时候 获取默认构造函数constructor = (constructor != null ? constructor :findDeclaredConstructor(factoryImplementationClass));return constructor;}// 实例化类T instantiate(@Nullable ArgumentResolver argumentResolver) throws Exception {// 解析参数 Object[] args = resolveArgs(argumentResolver);if (isKotlinType(this.constructor.getDeclaringClass())) {return KotlinDelegate.instantiate(this.constructor, args);}// 实例化return this.constructor.newInstance(args);}private Object[] resolveArgs(@Nullable ArgumentResolver argumentResolver) {// 参数类型Class<?>[] types = this.constructor.getParameterTypes();return (argumentResolver != null ?// 解析每一个类型对应参数Arrays.stream(types).map(argumentResolver::resolve).toArray() :// 返回空数组new Object[types.length]);}