概述
Spring Boot是一个用于构建独立、生产级别的基于Spring框架的Java应用程序的开发工具。它旨在简化Spring应用程序的创建和部署,并提供了许多开箱即用的功能。下面将详细介绍Spring Boot的优点和缺点。
优点
- 简化开发过程:Spring Boot通过自动配置和约定大于配置的原则,简化了Spring应用的初始化和开发过程。它提供了大量开箱即用的功能,如安全性、数据库访问、消息传递等,减少了开发者的工作量。
- 快速应用程序启动:由于Spring Boot集成了嵌入式的Tomcat或Jetty服务器,可以快速部署和启动应用程序,减少了部署时间。
- 易于测试:Spring Boot集成了大量用于单元测试和集成测试的工具,使得测试变得更加简单和快速。
- 易于部署:由于其独立的运行方式,Spring Boot应用程序可以轻松部署到云端或服务器上。
- 强大的社区支持:Spring Boot拥有庞大的开发者社区,为开发者提供了丰富的资源和支持。
- 集成度:Spring Boot与许多流行的技术和框架集成,如Thymeleaf、Bootstrap、Spring Data等,方便开发者快速构建应用程序。
- 安全性:Spring Boot提供了内置的安全特性,如CSRF保护、安全性过滤器等,并可轻松集成第三方安全解决方案。
- 监控和度量:Spring Boot集成了用于监控和度量的工具,如健康检查、性能指标等,方便开发者对应用程序进行实时监控和管理。
缺点
- 学习曲线陡峭:对于初学者来说,Spring Boot的强大功能和广泛集成可能会带来学习上的挑战。需要花费一定的时间来熟悉其概念和工具。
- 配置复杂性:虽然Spring Boot简化了开发过程,但有时过于简化的配置可能会导致某些情况下的配置复杂性增加。
- 性能考虑:虽然Spring Boot提供了快速的启动时间和集成度,但在处理大量请求或复杂计算时,性能可能不是最优的。
- 过度依赖Spring生态:由于Spring Boot基于Spring框架,因此对Spring生态系统的依赖较强。对于非Spring框架的应用程序,集成可能会变得复杂。
- 第三方库的兼容性:在某些情况下,新版本的Spring Boot可能与第三方库不兼容,需要进行额外的测试和调整。
- 资源占用:在某些情况下,由于Spring Boot应用程序的复杂性,可能会导致资源占用较多,如内存占用、CPU占用等。
- 不易调试:当应用程序出现错误时,由于其高度的集成性和自动配置特性,调试可能会变得复杂。
- 版本更新快:由于技术的快速发展,Spring Boot的版本更新速度较快。这可能导致对旧版本的支持有限,以及学习新版本的额外成本。
结论
综上所述,Spring Boot具有许多优点,如简化开发过程、快速应用程序启动、易于测试和部署等。然而,也存在一些缺点,如陡峭的学习曲线、配置复杂性、性能考虑等。在使用Spring Boot时,需要根据项目的具体需求和场景进行权衡,以充分发挥其优势并避免潜在的问题。
SpringBoot加载配置的方法,封装ResourceLoader对象,读取项目目录下的src/main/resources的yml文件。以为Resource ,文件的形式进行加载,转换成字符串,在转成LinkedHashSet 键值对的方式。
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.io;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import org.springframework.lang.Nullable;
/**
* Interface for a resource descriptor that abstracts from the actual
* type of underlying resource, such as a file or class path resource.
*
* <p>An InputStream can be opened for every resource if it exists in
* physical form, but a URL or File handle can just be returned for
* certain resources. The actual behavior is implementation-specific.
*
* @author Juergen Hoeller
* @since 28.12.2003
* @see #getInputStream()
* @see #getURL()
* @see #getURI()
* @see #getFile()
* @see WritableResource
* @see ContextResource
* @see UrlResource
* @see FileUrlResource
* @see FileSystemResource
* @see ClassPathResource
* @see ByteArrayResource
* @see InputStreamResource
*/
public interface Resource extends InputStreamSource {
/**
* Determine whether this resource actually exists in physical form.
* <p>This method performs a definitive existence check, whereas the
* existence of a {@code Resource} handle only guarantees a valid
* descriptor handle.
*/
boolean exists();
/**
* Indicate whether non-empty contents of this resource can be read via
* {@link #getInputStream()}.
* <p>Will be {@code true} for typical resource descriptors that exist
* since it strictly implies {@link #exists()} semantics as of 5.1.
* Note that actual content reading may still fail when attempted.
* However, a value of {@code false} is a definitive indication
* that the resource content cannot be read.
* @see #getInputStream()
* @see #exists()
*/
default boolean isReadable() {
return exists();
}
/**
* Indicate whether this resource represents a handle with an open stream.
* If {@code true}, the InputStream cannot be read multiple times,
* and must be read and closed to avoid resource leaks.
* <p>Will be {@code false} for typical resource descriptors.
*/
default boolean isOpen() {
return false;
}
/**
* Determine whether this resource represents a file in a file system.
* A value of {@code true} strongly suggests (but does not guarantee)
* that a {@link #getFile()} call will succeed.
* <p>This is conservatively {@code false} by default.
* @since 5.0
* @see #getFile()
*/
default boolean isFile() {
return false;
}
/**
* Return a URL handle for this resource.
* @throws IOException if the resource cannot be resolved as URL,
* i.e. if the resource is not available as descriptor
*/
URL getURL() throws IOException;
/**
* Return a URI handle for this resource.
* @throws IOException if the resource cannot be resolved as URI,
* i.e. if the resource is not available as descriptor
* @since 2.5
*/
URI getURI() throws IOException;
/**
* Return a File handle for this resource.
* @throws java.io.FileNotFoundException if the resource cannot be resolved as
* absolute file path, i.e. if the resource is not available in a file system
* @throws IOException in case of general resolution/reading failures
* @see #getInputStream()
*/
File getFile() throws IOException;
/**
* Return a {@link ReadableByteChannel}.
* <p>It is expected that each call creates a <i>fresh</i> channel.
* <p>The default implementation returns {@link Channels#newChannel(InputStream)}
* with the result of {@link #getInputStream()}.
* @return the byte channel for the underlying resource (must not be {@code null})
* @throws java.io.FileNotFoundException if the underlying resource doesn't exist
* @throws IOException if the content channel could not be opened
* @since 5.0
* @see #getInputStream()
*/
default ReadableByteChannel readableChannel() throws IOException {
return Channels.newChannel(getInputStream());
}
/**
* Determine the content length for this resource.
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/
long contentLength() throws IOException;
/**
* Determine the last-modified timestamp for this resource.
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/
long lastModified() throws IOException;
/**
* Create a resource relative to this resource.
* @param relativePath the relative path (relative to this resource)
* @return the resource handle for the relative resource
* @throws IOException if the relative resource cannot be determined
*/
Resource createRelative(String relativePath) throws IOException;
/**
* Determine a filename for this resource, i.e. typically the last
* part of the path: for example, "myfile.txt".
* <p>Returns {@code null} if this type of resource does not
* have a filename.
*/
@Nullable
String getFilename();
/**
* Return a description for this resource,
* to be used for error output when working with the resource.
* <p>Implementations are also encouraged to return this value
* from their {@code toString} method.
* @see Object#toString()
*/
String getDescription();
}
获取到c/main/resources的yml文件的文件二次加工。
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}