Java之SpringBoot基础夯实——八股文【2024面试题&&案例代码】

1、什么是 Spring Boot?

Spring Boot 是一个开源的Java开发框架,由Pivotal团队开发,其核心目标是简化新Spring应用的初始搭建和开发流程。它以Spring框架为基础,通过自动配置和约定优于配置的原则,极大程度地减少了手动配置的工作量,使开发者能够快速构建独立、生产级别的应用程序。

Spring Boot的主要特性包括:

  1. 快速启动:内嵌了如Tomcat、Jetty或Undertow等Servlet容器,使得Spring应用可以作为一个独立的可执行JAR文件运行,无需单独部署到外部的应用服务器。

  2. 自动配置:基于类路径分析、 beans定义以及各种属性值来智能地决定需要为应用开启哪些Spring特性,避免了大量的XML或Java配置。

  3. 起步依赖(Starter Dependencies):提供了一系列便捷的依赖管理模块,只需要在项目中声明使用对应的"起步器",即可引入相关的依赖集合,简化Maven和Gradle构建配置。

  4. 命令行界面(CLI)工具:提供了Spring Boot CLI,允许快速创建和运行Groovy应用。

  5. 健康检查与监控:内置了Actuator模块用于应用状态管理和监控。

  6. 生产就绪:包含许多用于日志记录、安全、性能指标收集等功能,确保构建的应用可以直接应用于生产环境。

通过这些特性,Spring Boot不仅降低了Spring应用的入门门槛,也提高了开发效率和维护性,成为了现代微服务架构中广泛采用的技术栈之一。

2、 SpringBoot与SpringCloud 区别

Spring Boot 和 Spring Cloud 是 Spring 生态系统中两个互补但作用不同的框架:

Spring Boot:

  • 主要目标是简化新应用程序的初始设置、配置和部署过程,尤其是基于微服务架构的应用。
  • 提供了一系列"开箱即用"的默认配置,通过自动配置机制减少了大量的手动配置工作。
  • 内嵌了如Tomcat等Web容器,使得开发的服务可以被打包成独立可执行的JAR或WAR文件,易于部署和运行。
  • 通过"起步依赖(Starter Dependencies)"简化Maven和Gradle构建配置,方便开发者快速集成第三方库。
  • 强调快速开发单个微服务应用,并提供了一套用于健康检查、监控和外部化配置等功能。

Spring Cloud:

  • 设计目的是为了实现微服务架构下的服务治理和服务间协调,是在Spring Boot基础之上构建的一系列工具集。
  • 包含一系列子项目,每个子项目解决微服务架构中的特定问题,如:
    • 服务发现与注册(Eureka, Consul)
    • 配置中心(Config Server)
    • 负载均衡(Ribbon, Zuul, Gateway)
    • 断路器(Hystrix, Resilience4j)
    • 分布式追踪(Sleuth, Zipkin)
    • 熔断器模式支持
    • API网关设计
    • 服务之间的消息传递(Stream, Bus)
  • 使用Spring Boot来创建各个微服务,而Spring Cloud则提供了这些微服务之间如何协作、管理和通信的解决方案。

总结来说,Spring Boot是一个让开发者快速构建单个微服务的框架,而Spring Cloud则是一个针对微服务架构的服务治理框架,它依赖于Spring Boot并扩展其功能以解决分布式系统的复杂性问题。

3、 SpringBoot常用注解有哪些

Spring Boot 中常用的注解非常多,以下是一些核心和常见的注解以及它们的简单应用案例:

Spring Boot 应用启动类注解:

@SpringBootApplication:这是Spring Boot应用的主入口类上的注解,它组合了@Configuration(配置类)、@EnableAutoConfiguration(自动配置)和@ComponentScan(组件扫描)的功能。

java 复制代码
// 核心注解,标识该类是Spring Boot应用的入口
@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

Spring MVC 控制器相关注解:

java 复制代码
@RestController // 表示这是一个RESTful风格的控制器,自动将返回的对象转换为JSON响应
@RequestMapping("/api/users") // 绑定URL路径到控制器类级别
public class UserController {

    @GetMapping("/{id}") // 处理GET请求,根据用户ID获取用户信息
    public User getUser(@PathVariable Long id) {
        // 这里通常会从数据库或服务中查找用户并返回
        return new User(id, "用户名");
    }

    @PostMapping // 处理POST请求,创建新用户
    public ResponseEntity<User> createUser(@RequestBody User user) {
        // 创建用户逻辑...
        return ResponseEntity.ok(user);
    }
}

Spring Data JPA 相关注解:

java 复制代码
// 在实体类上标注,表示该类是一个JPA实体
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    // getters and setters...
}

// 定义一个继承自JpaRepository的接口来操作User实体
public interface UserRepository extends JpaRepository<User, Long> {
    
    // 自定义查询方法
    List<User> findByName(String name);
}

@Entity 注解是 Java Persistence API (JPA) 的一部分,它用于标记一个Java类为持久化实体类。

在 Spring Boot 应用中,结合 Spring Data JPA 或 Hibernate 等 ORM 框架使用时,此注解具有以下作用:

@Id:这是一个标记注解,表示该字段(这里是id字段)是实体类的主键。在数据库表中,主键是唯一标识每条记录的字段。

@GeneratedValue(strategy = GenerationType.IDENTITY):这个注解用于主键字段,表明主键值由数据库自动生成。

参数strategy指定了生成策略,此处为GenerationType.IDENTITY,意味着主键值在插入新记录时,会根据数据库支持的自增特性自动获取下一个可用的唯一值。

@Column(nullable = false):此注解用于描述持久化字段如何与数据库表中的列进行映射。参数nullable设置为false,意味着对应的数据库列不允许为NULL,即name字段在数据库中不能为空。

  1. 标识实体类 :当一个类被 @Entity 注解时,表明这个类将映射到数据库中的一个表。ORM框架会基于这个实体类的属性和注解来创建或操作对应的数据库表。

  2. 表映射 :默认情况下,实体类名会被转化为数据库表名(通常是驼峰命名法转下划线分隔),但也可以通过 @Table 注解明确指定表名、schema、catalog等信息。

  3. 属性映射 :实体类中的字段对应数据库表中的列。可以通过如 @Id@GeneratedValue@Column 等注解进行详细的列映射配置,如主键生成策略、列名、是否可为空等。

  4. 关系映射 :对于关联关系,可以使用如 @OneToOne@OneToMany@ManyToOne@ManyToMany 等注解来表示实体之间的关系,并进行关联查询和维护。

例如:

java 复制代码
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity // 标记该类为一个持久化实体类,映射到数据库表
public class User {

    @Id // 标识为主键字段
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键生成策略
    private Long id;

    @Column(nullable = false) // 映射到名为 "username" 的列,且该列不允许为空
    private String username;

    // 其他属性和 getter、setter 方法...
}

在这个例子中,User 类会被 ORM 框架映射为数据库中的一个用户表,其中 id 字段作为主键,username 字段则映射为一个非空的列。

Spring Framework 相关注解(部分):

@Configuration 是 Spring Framework 中的核心注解,用于标记一个类作为配置类。在Spring IoC容器中,它起到了定义和组装Bean的作用。通过在类上使用 @Configuration 注解,表明这个类可以包含一系列的 @Bean 注解的方法,这些方法将返回要添加到IoC容器中的对象(即Bean)。

详解:

  1. 声明配置类 :标注了 @Configuration 的类会被Spring视为一个"配置类",Spring会处理其中定义的所有带有 @Bean 注解的方法,并将它们所创建的对象注册为Spring容器中的Bean。

  2. 替代XML配置 :在传统的Spring应用中,我们通常使用XML文件来定义Bean。而在Java配置风格中,我们可以用 @Configuration@Bean 替代XML进行Bean的定义和配置,实现了代码层面的配置,增强了可读性和维护性。

  3. 支持依赖注入 :配置类本身也可以被Spring容器管理,因此其内部可以引用其他的 @Bean 方法或者外部已存在的Bean,实现依赖注入。

使用案例:

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // 标记这是一个配置类
public class AppConfig {

    // 使用@Bean注解的方法将返回的对象注册为Spring Bean
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }

    @Bean
    public AnotherService anotherService(MyService myService) {
        // 这里注入了myService Bean,展示了Bean之间的依赖关系
        return new AnotherServiceImpl(myService);
    }
}

// 定义服务接口与实现类
public interface MyService { ... }
public class MyServiceImpl implements MyService { ... }

public interface AnotherService { ... }
public class AnotherServiceImpl implements AnotherService {
    private final MyService myService;

    public AnotherServiceImpl(MyService myService) {
        this.myService = myService;
    }

    // ...
}

在这个例子中,AppConfig 类是一个配置类,它定义了两个Bean:myServiceanotherService

当Spring容器启动时,会调用这两个 @Bean 注解的方法,并将返回的对象作为Bean注册到容器中。

同时,anotherService Bean的构造器需要 myService Bean作为参数,Spring框架会自动处理这种依赖关系,确保在初始化 anotherService 时注入已经实例化的 myService 实例。

Spring Security 相关注解(部分):

java 复制代码
@Configuration
@EnableWebSecurity // 启用Spring Security配置
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER")
            .and()
            .withUser("admin").password("{noop}adminPass").roles("USER", "ADMIN");
    }
}

这只是 Spring Boot 中一部分常用注解及其基本使用示例。实际开发过程中,还会涉及到更多与数据绑定、缓存处理、异步任务等相关的注解。

4、 Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?

Spring Boot 的核心注解是 @SpringBootApplication。这个注解是用来标识一个 Spring Boot 应用程序的主配置类,通常位于项目的入口点。它整合了多个其他注解的功能,简化了 Spring Boot 应用的开发和配置过程。

@SpringBootApplication 主要由以下三个注解组成:

  1. @SpringBootConfiguration :这实际上扩展自 @Configuration 注解,表明该类是一个配置类,其中可以包含 @Bean 方法来定义 Spring 容器中的 Bean。

  2. @EnableAutoConfiguration:这个注解启用自动配置功能,根据应用所依赖的类库以及各种属性设置来自动生成并配置 Bean。它让 Spring Boot 根据项目类路径(classpath)的内容、jar 包和其他条件来智能地决定应该启用哪些组件和特性。

  3. @ComponentScan :默认情况下,@SpringBootApplication 会自动扫描与使用该注解的类相同的包及其子包中的所有组件(如 @Component、@Service、@Repository、@Controller 等)。这有助于 Spring 容器发现并管理这些类作为 Bean。

因此,通过使用 @SpringBootApplication 注解,开发者可以快速搭建起一个基于 Spring Boot 的应用程序,并享受到开箱即用的诸多便利特性。

5、 SpringBoot支持哪几种配置文件的格式?默认使用哪一种格式的配置文件?

Spring Boot 支持以下几种配置文件格式:

  1. application.properties :这是传统的基于键值对的 properties 文件格式,以 .properties 为扩展名。

  2. application.ymlapplication.yaml :这两种是 YAML(YAML Ain't Markup Language)格式的配置文件,.yml.yaml 都可以使用。相比 properties 文件,YAML 更加灵活,支持更丰富的数据结构表示,如列表、映射等,并且具有更好的可读性和层次性。

默认情况下,Spring Boot 会自动查找类路径下的 application.propertiesapplication.yml(如果存在的话),并根据这些文件中的属性来配置应用。

具体案例代码(配置文件):

application.properties 示例:

properties 复制代码
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb

application.yml 示例:

yaml 复制代码
server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: mypassword

在 Spring Boot 应用中,无论哪种格式的配置文件,都可以通过 @Value 注解或 @ConfigurationProperties 注解将配置信息注入到 Bean 中:

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyConfig {

    @Value("${server.port}")
    private int serverPort;

    public void printPort() {
        System.out.println("Server port is " + serverPort);
    }
}

或者通过 @ConfigurationProperties 绑定到一个实体类上:

java 复制代码
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceConfig {

    private String url;
    private String username;
    private String password;

    // getters and setters...
}

6、 如何快速构建一个SpringBoot项目?

快速构建一个Spring Boot项目可以通过以下几种方式:

方法一:使用IntelliJ IDEA

  1. 通过 Spring Initializr(在线版)创建项目

    • 打开 IntelliJ IDEA,点击 File -> New -> Project
    • 在新建项目的向导中选择 Spring Initializr 选项卡。
    • 设置 Project SDK(如果尚未配置,请先添加并选择合适的Java版本)。
    • Project Settings 中填写项目名称、存储路径等基本信息。
    • Dependencies 部分勾选需要的依赖,例如 Spring Web 用于开发web应用。
    • 点击 Next,然后 Finish,IDEA会从Spring Initializr服务下载并初始化项目结构。
  2. 通过内置的Spring Initializr工具创建项目

    • 同样在新建项目时,选择 Spring Initializr,但这次IDEA将直接与本地或网络资源交互来生成项目结构。
    • 填写项目的基本信息和依赖项,按照提示步骤操作即可。

方法二:手动通过Maven或Gradle构建

如果你不使用IDEA,也可以通过命令行和构建工具来创建项目:

  • 使用Maven

    1. 访问 Spring Initializr 网站。
    2. 在网页上配置项目基本信息(如Group, Artifact, Java Version, Packaging等),并选择所需依赖。
    3. 点击"Generate"按钮下载ZIP文件。
    4. 解压文件到本地,导入解压后的目录为Maven项目到IDE中,如Eclipse或VS Code。
    5. 使用IDE的Maven插件进行构建和运行项目。
  • 使用Gradle

    类似地,在Spring Initializr网站上选择Gradle作为构建工具,下载项目后解压,并使用支持Gradle的IDE打开项目。通过执行./gradlew bootRun命令来运行项目(Windows系统下是gradlew.bat bootRun)。

具体步骤(以IntelliJ IDEA为例):

  1. 使用内置Spring Initializr
    • 打开IntelliJ IDEA,点击 File -> New -> Project
    • 在左侧列表选择 Spring Initializr,点击 Next 按钮。
    • 填写项目相关信息,包括 GroupIdArtifactIdVersion
    • 在右侧依赖列表中搜索并勾选所需的依赖,比如 Web 用于 web 应用开发。
    • 点击 Next,确认项目设置无误后,点击 Finish 来下载和创建项目。

完成上述步骤后,你将得到一个基本的Spring Boot项目结构,其中包含pom.xml(Maven项目)或build.gradle(Gradle项目)以及src/main/java下的启动类(带有@SpringBootApplication注解)。只需运行主类中的main方法即可启动Spring Boot应用。

7、SpringBoot启动方式?

Spring Boot项目可以采用以下几种常见启动方式:

  1. 使用IDE(如IntelliJ IDEA)直接运行

    • 在集成开发环境中,找到项目中包含@SpringBootApplication注解的主类。
    • 右键点击该主类,选择"Run 'XXXApplication.main()'"(其中XXX是你的主类名),IDE会自动编译并执行该项目,启动内置的Tomcat服务器或Jetty服务器。
  2. 命令行通过Maven启动

    • 首先确保已安装Maven,并在项目的根目录下打开命令行终端。
    • 输入命令 mvn spring-boot:run 来运行项目。Maven会下载所需的依赖并编译项目,然后启动Spring Boot应用。
  3. 命令行通过Gradle启动

    • 如果项目使用Gradle构建工具,可以在项目根目录下通过命令行输入:

      ./gradlew bootRun
      

      (对于Windows系统则是 gradlew.bat bootRun)来启动Spring Boot应用。

  4. 打包为可执行jar文件运行

    • 使用Maven打包:在命令行执行 mvn clean package,这将生成一个带所有依赖的可执行jar文件(通常在target目录下)。

    • 使用Gradle打包:执行 ./gradlew build(Windows上是 gradlew build),同样会生成一个可执行的jar文件。

    • 然后可以通过命令行启动这个jar文件:

      java -jar target/my-app.jar
      

      其中my-app.jar替换为你实际生成的jar文件名。

以上就是Spring Boot项目常见的启动方式。

  1. 打包为war文件运行

将SpringBoot项目打包为war后部署到Tomcat当中

8、Spring Boot 支持哪些日志框架?默认的日志框架是哪个?

Spring Boot 支持多种日志框架,包括但不限于:

  1. Java Util Logging (JUL)
  2. Log4j
  3. Log4j 2
  4. Logback

默认的日志框架是 Logback。Spring Boot 的选择依据通常是依赖库的加载顺序和版本兼容性,由于 Logback 是 SLF4J(Simple Logging Facade for Java)的一个实现,并且性能优秀、配置灵活,所以 Spring Boot 默认将其作为日志后端。

具体使用方法如下:

默认配置下使用Logback

  • 在默认配置中,Spring Boot 会自动配置 Logback 来记录日志。
  • 应用程序启动时,如果没有自定义日志配置文件(如logback.xmllogback-spring.xml),Spring Boot 会提供一个合理的默认配置,将INFO级别的日志输出到控制台。

如果你想调整日志级别或者修改输出格式等,可以通过以下步骤操作:

  • 创建一个 src/main/resources/logback.xml 文件,然后按照Logback的语法编写自定义配置。
  • 配置内容可以包括设置全局日志级别、定义不同的日志输出器(appender)、以及指定哪些日志信息应被哪些输出器处理等。

例如,一个基本的logback.xml配置文件可能包含如下内容:

xml 复制代码
<configuration>
    <property name="LOG_FILE" value="logs/app.log" />

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>logs/archived/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- keep 30 days' worth of history -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

此配置文件指定了两个输出器:一个是输出到控制台(CONSOLE),另一个是滚动记录到文件(FILE)。同时设置了根 logger 的日志级别为 info。

如果想切换到其他日志框架,比如 Log4j2,需要排除默认的Logback依赖并引入相应的Log4j2 starter依赖,同时提供对应的日志配置文件。

9、开启 Spring Boot 特性有哪几种方式?

开启 Spring Boot 的特性主要通过以下几种方式:

  1. 依赖管理与自动配置

    • 继承 spring-boot-starter-parent 项目 :在 Maven 项目中,将 spring-boot-starter-parent 设置为项目的父项目。
      这会引入默认的依赖管理和构建插件,包括版本管理和自动配置功能。
    xml 复制代码
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>当前Spring Boot版本号</version>
    </parent>
    • 导入 spring-boot-dependencies BOM(Bill of Materials):如果不想直接继承 starter parent,可以在 Maven 或 Gradle 中引入 spring-boot-dependencies BOM 来管理所有 Spring Boot 相关依赖的版本。
  2. 使用 Spring Boot Starter POMs

    • 添加特定领域的"起步器"(starter),例如 spring-boot-starter-web 用于 web 开发,这些起步器包含了启动特定功能所需的全部依赖。
    xml 复制代码
    <!-- 在Maven项目的pom.xml文件中添加 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  3. 应用类上的注解

    • 使用 @SpringBootApplication 注解标记主类,它聚合了 @Configuration@EnableAutoConfiguration@ComponentScan 注解的功能,允许自动配置和组件扫描以启用相关特性。
  4. 自定义配置属性

    • 通过 application.propertiesapplication.yml 文件提供自定义配置,Spring Boot 将根据这些属性来调整其自动配置的行为。
  5. 条件化或覆盖自动配置

    • 创建自己的 @Configuration 类并使用 @ConditionalOnMissingBean 等注解来控制特定 bean 是否创建,或者使用 @Bean 注解提供自定义bean以覆盖默认的自动配置。
  6. 使用Spring Boot Actuator

    • 添加 spring-boot-starter-actuator 起步器来启用生产就绪的特性,如健康检查、审计、监控等。

具体方法示例:

java 复制代码
// 主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
xml 复制代码
<!-- Maven pom.xml中的部分依赖配置 -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- 其他需要的起步器 -->
</dependencies>

<!-- 引入BOM进行版本统一管理 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>当前Spring Boot版本号</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

10、Springboot约定优于配置的理解?具体案例

Spring Boot 的"约定优于配置"(Convention over Configuration,COC)设计原则意味着它预先设定了许多默认配置和项目结构约定,使得开发者在构建应用时可以尽量减少显式的配置工作。这种理念体现在以下几个方面:

  1. 自动配置

    Spring Boot 自动检测类路径上的依赖,并基于这些依赖自动配置Bean。例如,如果在项目的类路径中发现了HSQLDB数据库驱动,Spring Boot会自动配置内存数据库并创建相关的DataSource Bean,同时设置好Hibernate等JPA相关配置。

    案例:当引入spring-boot-starter-data-jpa起步器时,无需手动配置数据库连接、事务管理器、Entity扫描路径等,Spring Boot会根据classpath中的数据库驱动自动配置。

  2. 默认组件的启用与禁用

    Spring Boot对一些常见的功能提供默认实现,比如内嵌Servlet容器(如Tomcat或Jetty)、静态资源处理、模板引擎(如Thymeleaf)等。除非有特殊需求需要自定义配置,否则开发人员可以直接使用这些默认配置。

    案例:启动一个Web应用时,只需添加spring-boot-starter-web起步器,Spring Boot就会自动配置并启动内嵌的Servlet容器,无需额外配置web.xml或Servlet容器的部署描述符。

  3. 约定的文件位置

    Spring Boot遵循特定的目录结构和资源配置文件的位置约定。例如,Spring Boot默认会在src/main/resources目录下查找名为application.properties或application.yml的应用程序属性配置文件。

    案例:将日志配置写入src/main/resources/logback-spring.xml文件中,Spring Boot会自动识别并加载该配置,无需额外指定日志框架的配置路径。

  4. 约定的命名规则

    对于某些特定的Bean或者接口,Spring Boot遵循一定的命名规则来发现和注入。例如,如果你有一个实现了CommandLineRunner接口的类,只要将其命名为合适的Java bean名称,Spring Boot就会自动识别并在应用启动后执行其run方法。

  5. starter POMs依赖管理

    Spring Boot的starter包集合了多个库,它们之间有着默认的版本协调和合理的依赖关系,开发者只需声明对应的starter依赖即可快速集成功能模块。

总之,Spring Boot通过"约定优于配置"的设计理念,极大地简化了Spring应用程序的搭建和开发过程,让开发者能够更多地专注于业务逻辑开发,而非基础环境配置。

11、Springboot约定优于配置的理解?具体案例

在微服务架构中,由于每个服务通常独立部署并拥有自己的内存空间,传统的基于内存的HTTP Session无法直接跨服务共享。为了实现Session共享,Spring Boot提供了多种解决方案,其中一种常见的方法是通过Spring Session和Spring Session Data Redis来实现。

以下是一个使用Spring Session和Redis作为会话存储介质的简单案例:

  1. 首先,在所有需要共享Session的微服务项目中引入Spring Session和Spring Session Data Redis依赖:

    Maven配置:

    xml 复制代码
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. 配置Redis连接信息(application.properties或application.yml):

    properties 复制代码
    spring.redis.host=localhost
    spring.redis.port=6379
  3. 在Spring Boot应用的主类上启用@EnableRedisHttpSession注解以启用Redis支持的HttpSession:

    java 复制代码
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
    
    @SpringBootApplication
    @EnableRedisHttpSession
    public class MyMicroserviceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MyMicroserviceApplication.class, args);
        }
    }
  4. 现在,当用户在微服务间切换时,其Session数据将自动保存到Redis,并且在请求到达其他微服务时,会从Redis中检索和复用相同的Session。

这样,所有的微服务都将通过Redis服务器来存取用户的Session信息,从而实现了Session共享。

注意:实际生产环境中,还需要考虑诸如Redis集群、Session过期策略、安全性等方面的配置与优化。同时,对于无状态服务设计的趋势,也可以采用JWT等Token方式替代Session进行认证与授权管理。

12、SpringBoot项目当中常用的Starter

Spring Boot Starter 是一组预定义依赖,它们简化了添加特定功能到项目中的过程。以下是一些常用的 Spring Boot Starter 以及它们在项目中如何使用:

1. Web 开发相关

  • spring-boot-starter-web:用于开发 web 应用,包括 Tomcat 内嵌服务器和 Spring MVC。
xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

案例代码:

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class MyApp {

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

}

@RestController
class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}

2. 数据库支持

  • spring-boot-starter-data-jpa:集成JPA(Java Persistence API)与Hibernate实现关系型数据库操作。
xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- 还需要添加对应的数据库驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

配置数据源和实体类示例:

properties 复制代码
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=secret

# 实体类示例
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    // getters and setters...
}

3. 安全性

  • spring-boot-starter-security:提供基础的Spring Security支持。
xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>

4. Actuator 监控

  • spring-boot-starter-actuator:提供生产级别的应用监控端点。
xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

这些只是Spring Boot众多Starter中的一部分,根据项目需求可以引入更多不同的Starter来快速集成所需的功能模块。

5、mybatis-plus-boot-starter

  • mybatis-plus-boot-starter
    mybatis-plus-boot-starter 是 MyBatis-Plus 提供的一个 Spring Boot Starter,用于简化在 Spring Boot 项目中集成 MyBatis 和 MyBatis-Plus 的过程。MyBatis-Plus 是对 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

引入 mybatis-plus-boot-starter 的步骤如下:

  1. 在 Maven 或 Gradle 项目的构建文件(pom.xml 或 build.gradle)中添加依赖:

Maven:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <!-- 使用最新版本,请查询 https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <version>3.4.0</version>
    </dependency>
</dependencies>

Gradle:

groovy 复制代码
dependencies {
    implementation 'com.baomidou:mybatis-plus-boot-starter:3.4.0'
}
  1. 配置数据库连接信息以及MyBatis相关配置,通常在 application.properties 或 application.yml 文件中:
properties 复制代码
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# MyBatis-Plus 相关配置
mybatis-plus.mapper-locations=classpath:mapper/*.xml
  1. 创建实体类和对应的Mapper接口,并使用 @TableName 注解指定表名,使用 @Mapper 注解标记Mapper接口。
java 复制代码
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("user")
public class User {

    private Long id;
    private String name;
    // 其他字段...
}

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 可以在此处添加自定义SQL方法
}
  1. 启动Spring Boot应用,MyBatis-Plus将自动完成Bean的初始化和注入,可以开始进行数据库操作。

通过以上步骤,就成功在Spring Boot项目中集成了MyBatis-Plus,可以利用其提供的强大功能如通用CRUD操作、条件构造器、分页插件等,大大简化持久层代码编写。

13、SpringBoot如何实现热部署?

什么是热部署

热部署(Hot Deployment)是一种软件开发技术,允许开发者在应用运行时更新代码或配置文件,并且无需重启整个应用程序就能立即看到这些更改的效果。这意味着在不中断服务的前提下,可以提高开发效率、缩短迭代周期。

对于基于Java的Web应用服务器,如Tomcat、Jetty以及使用Spring Boot框架的应用,可以通过类加载器的机制实现热部署。当检测到源代码发生变化并重新编译后,新的字节码会被加载到内存中,替换掉原有的类定义,从而实现功能的即时更新。

例如,在Spring Boot项目中,通过集成spring-boot-devtools工具,能够提供更快捷的热部署体验,即每次修改代码后保存,IDE会自动触发重新编译和资源重载,使得开发者可以在短时间内看到代码改动的效果。

此外,还有一些第三方工具,比如JRebel,可以更深入地支持Java应用的热部署,包括类结构变化、新增删除方法等复杂场景。

Spring Boot 应用实现热部署(无需重启应用即可加载新代码)可以通过以下几种方式:

  1. IDEA 或 Eclipse 插件

    • IntelliJ IDEA:使用 Spring Boot 插件或者 JRebel 插件。对于 IntelliJ IDEA,启用插件的步骤如下:
      • 安装并启用 IntelliJ IDEA 的 Build Tools 中的 Make 功能,确保勾选了 Build project automatically
      • 在 Run/Debug 配置中选择你的 Spring Boot 应用,然后在 Edit Configurations... 的配置窗口里,找到 Before launch 栏目,点击 + 添加 Make 任务,这样每次保存文件时都会自动编译并重新加载类。
  2. DevTools 实现热部署

    Spring Boot 自带了一个名为 DevTools 的模块,它可以自动检测类路径下的文件变化并触发应用重启,非常适合开发阶段快速迭代。

    要启用 DevTools,请将 spring-boot-devtools 依赖添加到项目中:

    Maven:

    xml 复制代码
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 可选属性,避免传递依赖 -->
        </dependency>
    </dependencies>

    Gradle:

    groovy 复制代码
    dependencies {
        developmentOnly("org.springframework.boot:spring-boot-devtools")
    }

    注意,DevTools 不会立即重启整个应用程序,而是通过Class Reloading机制仅重载有变动的部分。这使得热部署变得非常迅速且高效。

  3. 第三方工具如JRebel

    如果你希望获得更强大的热部署功能,可以考虑使用像 JRebel 这样的商业产品,它能够实现在运行时即时替换类和资源而无需重启服务器。

示例代码(Maven 项目)

xml 复制代码
<!-- 在pom.xml中添加devtools依赖 -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    <!-- 其他依赖项... -->
</dependencies>

完成上述配置后,在开发过程中,每当您修改了源代码并保存后,由于 DevTools 的存在,您的更改将被自动编译并在下一次HTTP请求时生效。无需手动重启服务器或执行任何其他命令。

14、SpringBoot自动配置原理?

Spring Boot 的自动配置原理基于条件注解(@Conditional)和starter模块的机制。当我们在项目中引入某个starter依赖时,比如 spring-boot-starter-data-jpa,Spring Boot 会自动扫描并加载对应的自动配置类,这些类通常位于 org.springframework.boot.autoconfigure 包及其子包下。

以下是Spring Boot 自动配置的核心步骤:

  1. 起步依赖(Starters) :Spring Boot 提供了一系列 starters,它们是预定义的一组依赖描述符,简化了Maven或Gradle构建配置。例如,当你添加 spring-boot-starter-data-jpa 到你的项目中,它不仅包含了JPA相关的库,还包含了用于自动配置JPA的类。

  2. 自动配置类 :每个starter都关联了一些自动配置类,如 JpaAutoConfiguration。这些类使用了 @Configuration 注解表明它们可以作为bean定义的来源,并通过 @EnableConfigurationProperties 注解启用特定的配置属性绑定。

  3. 条件注解 (@Conditional) :在自动配置类中的bean定义上,使用了 @ConditionalOnClass@ConditionalOnBean@ConditionalOnMissingBean 等条件注解,这些注解使得只有满足特定条件(如类路径中有特定类,或者没有用户自定义的同类型bean)时,才会实例化相应的bean。

  4. 配置属性与条件判断 :Spring Boot 读取 application.propertiesapplication.yml 中的属性来决定如何配置bean。如果用户在配置文件中指定了相关属性,则自动配置将根据这些属性进行调整,否则使用默认值。

具体案例代码:

java 复制代码
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

@Configuration
@ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class)
public class JpaAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        // 设置Hibernate的一些默认配置
        return adapter;
    }

    // ... 其他自动配置的bean

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(...) {
        // 根据条件创建并配置EntityManagerFactoryBean
        // ...
    }

    // ...
}

在这个例子中,JpaAutoConfiguration 类会在类路径中存在 LocalContainerEntityManagerFactoryBean 类的时候被激活,并且如果没有用户自己定义的 JpaVendorAdapter bean,则会自动配置一个 HibernateJpaVendorAdapter 实例。

Spring Boot 就是通过这种方式,为各种常见场景提供了开箱即用的配置支持,大大简化了开发者的工作。

15、「bootstrap.yml」 和「application.yml」?

在Spring Boot应用中,bootstrap.ymlapplication.yml 都是用来配置应用属性的文件,但它们的作用和加载时机有所不同:

bootstrap.yml

  • 用途 :主要用于从外部源(如Config Server)获取配置信息,或者用于加密解密配置等初始化阶段就需要使用的配置。例如,如果你的应用使用了Spring Cloud Config Server来集中管理配置,则需要在bootstrap.ymlbootstrap.properties中指定Config Server的位置。

  • 加载顺序bootstrap.yml 的加载优先于 application.yml,并且它的加载发生在Spring Application Context创建之前,即环境变量和系统属性的解析阶段。

  • 案例代码(配置文件内容):

yaml 复制代码
# bootstrap.yml
spring:
  application:
    name: my-service
  cloud:
    config:
      uri: http://config-server-host:8888 # 指定Config Server地址

application.yml

  • 用途:主要用来配置应用自身的常规运行时参数,包括数据源、视图层、服务器端口、日志级别、自定义bean配置等大部分应用程序所需的属性。

  • 加载顺序 :在Spring Boot启动过程中,当bootstrap.yml完成加载并初始化了基本环境后,application.yml才会被加载。

  • 案例代码(配置文件内容):

yaml 复制代码
# application.yml
server:
  port: 8080 # 应用服务端口

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: dbuser
    password: dbpass
    driver-class-name: com.mysql.cj.jdbc.Driver

logging:
  level:
    org.springframework.web: DEBUG
    com.example.myapp: INFO

总结来说,bootstrap.yml 关注于引导应用启动时所需要的配置,尤其是那些影响到应用环境和外部资源访问的配置;而 application.yml 则关注于应用核心功能和服务本身的配置。在实际开发中,根据应用场景选择合适的配置文件放置相应的配置项。

16、SpringBoot如何修改端口号?

在Spring Boot应用中修改端口号可以通过编辑配置文件来实现,以下是两种常见的方式:

通过application.properties文件修改

src/main/resources/application.properties文件中添加或修改以下行:

properties 复制代码
server.port=8081

这里将端口号更改为 8081,根据需要替换为你想要的任意有效端口。

通过application.yml文件修改

如果你的应用使用的是YAML格式的配置文件(src/main/resources/application.yml),则可以按照以下方式修改:

yaml 复制代码
server:
  port: 8081

同样,这里的 8081 是示例端口号,你可以将其替换为所需的任何有效端口。

重启你的Spring Boot应用后,它就会监听新的端口号了。

17、SpringBoot如何兼容Spring项目?

Spring Boot 是对 Spring 框架的扩展和简化,它集成了很多自动配置功能,并提供了一种快速构建可运行独立应用的方式。如果你有一个老的 Spring 项目想要迁移到或整合到 Spring Boot 中,通常不需要大规模修改代码结构,而是主要关注以下几点:

  1. Maven/Gradle 构建系统调整

    • 将依赖从传统的 Spring 组件改为使用 Spring Boot 的 "starter" 依赖。
    • pom.xml(对于 Maven)或 build.gradle(对于 Gradle)中添加 Spring Boot 的父 POM 或插件。
    xml 复制代码
    <!-- Maven 示例 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.x</version> <!-- 使用最新稳定版 -->
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 其他需要的 starter 包 -->
    </dependencies>

    或者

    groovy 复制代码
    // Gradle 示例
    plugins {
        id 'org.springframework.boot' version '2.7.x'
        // ...
    }
    
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-web'
        // 其他需要的 starter 包
    }
  2. 主类调整

    • 创建一个包含 @SpringBootApplication 注解的主类,这个注解组合了 @Configuration@EnableAutoConfiguration@ComponentScan,使得 Spring Boot 可以自动配置并启动应用程序。
    java 复制代码
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MyApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MyApplication.class, args);
        }
    }
  3. XML 配置迁移至 Java Config

    • 如果你的老 Spring 项目使用了大量的 XML 配置文件,可以将它们转换为 Java 配置类或者尽量利用 Spring Boot 的自动配置特性减少手动配置。
  4. 属性配置迁移

    • 将原有的 properties 文件中的配置项移植到 application.propertiesapplication.yml 文件中。
  5. 处理老项目的自定义 Bean

    • 确保自定义的 Bean 被正确扫描到,如果有必要,可以通过在配置类上使用 @ComponentScan 明确指定包扫描范围。
  6. 检查兼容性问题

    • 检查原有 Spring 项目的第三方库版本是否与 Spring Boot 兼容,如有必要升级版本。

总的来说,Spring Boot 并不排斥老的 Spring 项目中的组件和配置方式,而是通过简化和标准化来提升开发效率和可维护性。关键在于如何合理地引入 Spring Boot 的自动化配置和管理机制,同时保持老项目的核心业务逻辑不变。

18、SpringBoot配置监控?

Spring Boot 提供了对应用监控的内置支持,并可以集成各种第三方监控工具,例如 Actuator、Prometheus、Micrometer 等。以下是如何配置 Spring Boot 的健康检查和基础监控(如通过 Actuator)的具体案例代码:

1. 添加 Actuator 依赖

在 Maven 构建项目中,在 pom.xml 文件中添加 Actuator 依赖:

xml 复制代码
<dependencies>
    <!-- 其他依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

对于 Gradle 项目,在 build.gradle 文件中添加:

groovy 复制代码
dependencies {
    // 其他依赖
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

2. 配置 Actuator 端点

默认情况下,Actuator 提供了一些端点用于查看应用状态、metrics、health check等信息。为了安全起见,生产环境可能需要关闭或限制某些端点的访问。

application.ymlapplication.properties 中进行配置:

yaml 复制代码
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: '*' # 允许所有端点公开,默认仅暴露health, info端点
  endpoint:
    health:
      show-details: always # 显示详细健康信息

或者

properties 复制代码
# application.properties
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

3. 访问端点

启动应用后,可以通过以下 URL 访问一些基本端点(假设应用监听的是8080端口):

4. 安全配置(可选)

如果你希望保护这些端点不被匿名访问,可以使用 Spring Security 进行整合:

java 复制代码
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR") // 或其他权限控制策略
            .and()
            .formLogin() // 如果需要登录认证
            // ... 其他安全配置
    }
}

5. 集成 Prometheus 监控(可选)

若要集成 Prometheus 监控,除了 Actuator 外,还需要增加 Prometheus 的 exporter 支持:

xml 复制代码
<!-- Maven 引入 Prometheus 对应的 starter -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

然后开启 Prometheus 端点:

yaml 复制代码
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: prometheus # 启动 Prometheus 端点

之后可以在 Prometheus 的配置文件中添加 Spring Boot 应用作为目标源,收集指标数据。 Prometheus 会定期抓取 /actuator/prometheus 端点的数据。

以上是基本的监控配置示例。实际应用中,还可以根据需求调整更多配置项以满足不同监控需求。

19、SpringBoot获得Bean装配报告信息访问哪个端点?

在Spring Boot应用中,若要获取Bean装配报告信息,可以访问/actuator Beans端点。不过请注意,自Spring Boot 2.0起,默认并未启用Beans端点,需要手动配置才能开启。

首先,确保你的项目已经引入了Spring Boot Actuator依赖:

Maven

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

Gradle

groovy 复制代码
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

然后,在application.propertiesapplication.yml文件中启用并暴露Beans端点:

properties 复制代码
# application.properties
management.endpoints.web.exposure.include=beans

或者

yaml 复制代码
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: beans

之后,启动应用并在浏览器或通过curl命令访问如下URL(假设应用监听8080端口):

bash 复制代码
http://localhost:8080/actuator/beans

将会返回JSON格式的Bean装配报告信息。

注意:对于敏感信息,如详细的Bean定义,生产环境中通常会限制或关闭这些端点以避免泄露内部结构和实现细节。务必遵循最佳安全实践进行配置。

20、SpringBoot有哪几种读取配置的方式

SpringBoot可以通过@PropertySource,@Value,@Environment,@ConfigurationProperties注解来绑定变量

Spring Boot 提供了多种方式来读取和绑定配置文件中的属性到应用的bean中。以下是五种常见的方法,包括具体的案例代码:

  1. 使用@Value注解

    java 复制代码
    @Component
    public class SomeService {
    
        @Value("${property.name}")
        private String propertyName;
    
        // ...
    }

    在这里,@Value注解可以直接从application.properties或application.yml中读取指定的属性值并注入到变量中。

  2. 使用Environment接口

    java 复制代码
    @Component
    public class AnotherService {
    
        @Autowired
        private Environment env;
    
        public void someMethod() {
            String propertyName = env.getProperty("property.name");
            // ...
        }
    }

    Environment是Spring框架提供的一个接口,它允许你访问所有环境属性,包括那些在配置文件中定义的属性。

  3. 使用@ConfigurationProperties注解

    java 复制代码
    // 创建一个Java Bean类与配置文件映射
    @ConfigurationProperties(prefix = "user")
    public class UserProperties {
        private String name;
        private int age;
    
        // getter和setter方法
        // ...
    }
    
    // 将UserProperties类与Spring容器绑定
    @EnableConfigurationProperties(UserProperties.class)
    @Configuration
    public class AppConfig { }
    
    // 然后可以将其注入到需要使用的组件中
    @Component
    public class UserService {
        @Autowired
        private UserProperties userProps;
        
        // ...
    }

    使用@ConfigurationProperties可以将配置文件中的多个相关属性组织成一个POJO(Plain Old Java Object)对象,方便管理和复用。

  4. 使用@PropertySource注解

    java 复制代码
    @Configuration
    @PropertySource("classpath:custom.properties")
    public class CustomConfig {
        @Autowired
        private Environment env;
    
        @Bean
        public MyBean myBean() {
            String customProp = env.getProperty("my.custom.property");
            return new MyBean(customProp);
        }
    }

    @PropertySource用于加载额外的properties文件,并将其内容合并到环境中。这个注解主要用于更加细粒度的配置划分,或者引入非默认的配置源。

  5. 原生方式读取配置文件

    这里提到的"原生方式"可能是指直接通过Spring Boot的ConfigurableEnvironment接口或者org.springframework.core.io.Resource来读取配置文件,但这种方式不如前几种常见且直接,一般不推荐在常规的业务逻辑中使用。

注意:在实际开发中,Spring Boot默认会自动加载src/main/resources/application.propertiessrc/main/resources/application.yml中的配置,无需特别处理。而@PropertySource通常用于添加额外的、自定义的配置源。

21、什么是JavaConfig

JavaConfig是Spring框架中一种基于纯Java类的配置方式,它替代了传统的XML配置文件来定义Bean以及它们之间的依赖关系。在Spring Boot中,JavaConfig扮演着核心角色,因为Spring Boot推崇零配置或尽可能少的XML配置理念,鼓励开发者使用Java代码来完成应用程序的所有配置工作。

JavaConfig通过使用一系列注解如@Configuration@Bean等,允许开发人员以更加类型安全和直观的方式来组织和管理Spring容器中的组件。例如:

java 复制代码
@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }

    @Bean
    public MyRepository myRepository() {
        return new MyRepositoryImpl();
    }
}

在这个例子中,AppConfig类使用了@Configuration注解表明这是一个配置类,其中的方法使用@Bean注解来声明并实例化一个Bean。当Spring容器启动时,它会自动识别并处理这些注解,将方法返回的对象注册到IoC容器中。

通过这种方式,Spring Boot和Spring框架利用JavaConfig可以更易于编写、理解和测试配置,同时也能够更好地与Java 8及以后版本的功能(如默认方法、lambda表达式)集成,进一步简化配置逻辑。

22、如何理解SpringBoot配置加载顺序

Spring Boot 配置加载顺序是指在启动应用时,系统是如何按照优先级查找并合并配置属性的。以下是Spring Boot加载配置的具体顺序:

  1. 命令行参数

    最高优先级,通过--spring.config.name=value--property=value的形式直接在启动命令中指定配置值。

    shell 复制代码
    java -jar myapp.jar --server.port=8080
  2. 环境变量

    次于命令行参数的优先级,Spring Boot会自动识别前缀为SPRING_APPLICATION_JSON(以JSON格式提供多个属性)、SPRING_以及不带前缀但符合配置项格式的环境变量,并将它们转换为配置属性。

    bash 复制代码
    export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/mydb
  3. 来自spring.config.locationspring.config.additional-location的外部配置文件

    如果指定了这些环境变量或系统属性,它们所指向的配置文件会被优先加载。

    shell 复制代码
    java -jar myapp.jar --spring.config.location=file:/path/to/application.properties
  4. 打包在jar包之外的应用程序属性文件

    Spring Boot默认会从以下路径查找application.propertiesapplication.yml文件:

    • 当前目录下的/config子目录下
    • 当前目录下
  5. 打包在jar包内的应用程序属性文件

    如果应用被打包成jar文件,则内部的BOOT-INF/classes/目录下的application.propertiesapplication.yml也会被加载。

  6. 多环境配置文件

    Spring Boot支持使用Profile进行多环境配置,如application-{profile}.propertiesapplication-{profile}.yml,这里的{profile}是环境标识,比如:application-dev.properties

  7. @ConfigurationProperties注解绑定的对象

    与@ConfigurationProperties注解的类相关的属性值也会在此阶段注入。

  8. Java系统属性 (System.getProperties())

    可以通过System.setProperty()设置的属性具有较低的优先级。

  9. 全局配置文件(bootstrap.properties/yml)
    bootstrap.*系列的配置文件用于引导阶段的配置,比常规的application.*文件优先加载。

  10. 默认属性

    Spring Boot内建的一些默认属性值。

具体案例可能涉及创建不同优先级的配置源,并检查最终应用使用的属性值。例如,在一个项目中分别在命令行、环境变量、外部配置文件、内部配置文件等多个位置设置server.port属性,并观察实际运行时应用监听的端口,以此验证配置加载顺序。不过,由于这通常是一个系统层面的交互过程,没有具体的代码片段可以直接展示这一顺序,而是通过实践和测试来理解。

23、什么是yaml

在Spring Boot中,YAML(YAML Ain't Markup Language)是一种数据序列化格式,用于编写和存储配置信息。相比于传统的properties文件,YAML以更简洁、更易读的语法来表示数据结构,尤其适合描述层次化的复杂配置。

在Spring Boot应用中,开发者可以使用YAML格式的application.ymlapplication.yaml文件来替代或补充application.properties作为应用程序的配置源。YAML的优点包括:

  1. 清晰的层次结构:通过缩进和键值对的形式表示层级关系,使得配置文件具有很好的可读性。
  2. 支持多种数据类型:可以方便地表示字符串、数字、布尔值、列表、映射等多种数据结构。
  3. 简化复杂配置:对于多级嵌套的属性设置,YAML更加直观且易于维护。

以下是一个简单的Spring Boot YAML配置文件示例:

yaml 复制代码
server:
  port: 8080
  ssl:
    enabled: false

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: dbuser
    password: secret

myapp:
  someProperty: value
  listOfItems:
    - item1
    - item2
    - item3

在这个例子中,配置被划分为多个section,如serverspring等,每个section下又包含一系列子属性。Spring Boot会自动识别这些配置并将其绑定到对应的bean中去。通过@ConfigurationProperties注解,还可以将这些YAML配置直接映射到Java对象中,便于在代码中处理和访问。

24、SpringBoot是否可以使用xml配置

Spring Boot 本身提倡基于Java的配置和注解驱动,但并不排斥XML配置。尽管Spring Boot的设计理念是减少XML配置以简化开发过程,但在某些情况下,开发者仍然可以选择使用XML来配置部分或全部Spring Bean。

若要在Spring Boot中使用XML配置文件,可以使用@ImportResource注解将XML配置导入到Spring Boot应用中。下面是一个具体案例和代码:

src
└── main
    └── resources
        └── applicationContext.xml

首先,创建一个名为applicationContext.xml的XML配置文件,例如:

xml 复制代码
<!-- src/main/resources/applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myBean" class="com.example.MyBean">
        <property name="message" value="Hello from XML configuration"/>
    </bean>

</beans>

然后,在Spring Boot的Java配置类中导入这个XML配置文件:

java 复制代码
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ImportResource(locations = {"classpath:applicationContext.xml"})
public class XmlConfiguredApplication {

    // ...
}

在这个例子中,@ImportResource(locations = {"classpath:applicationContext.xml"})注解使得Spring Boot容器在启动时会加载并解析指定路径下的XML配置文件,并根据其中定义的Bean进行实例化和管理。

请注意,为了遵循Spring Boot的最佳实践,建议尽量采用Java配置和自动配置,仅在必要时才引入XML配置。

25、SpringBoot核心配置文件是什么?bootstrap.properties和applicationContext.properties有何区别

Spring Boot的核心配置文件主要包括:

  1. application.propertiesapplication.yml

    这是Spring Boot应用的主要配置文件,用于定义应用程序运行时的各项设置。比如数据库连接信息、服务器端口、日志级别等。这些属性会通过@Value注解或@ConfigurationProperties绑定到Spring容器中的Bean上。

    示例(application.properties):

    properties 复制代码
    spring.datasource.url=jdbc:mysql://localhost:3306/mydb
    server.port=8080
  2. bootstrap.propertiesbootstrap.yml

    bootstrap配置文件在Spring Boot应用的引导阶段被加载,比application配置文件更早读取。它主要用于定制Spring Application Context的初始化过程,如配置加密/解密工具类,外部化配置源(例如Config Server)或者特定的环境变量和系统属性。

    例如,你可能需要在bootstrap配置中指定一个从外部获取所有其他配置的配置服务器地址:

    properties 复制代码
    spring.cloud.config.uri=http://config-server.example.com

    具体案例:如果你的应用程序使用了Spring Cloud Config Server来集中管理配置,那么bootstrap配置文件将用于连接到这个配置服务器。

总结它们的区别:

  • application.properties 主要针对应用的一般性配置,包括数据源、视图解析器、服务器设置等,并且是在Spring Boot主ApplicationContext创建之后加载的。
  • bootstrap.properties 主要用于对Spring Boot启动过程本身进行配置,特别是在涉及外部化配置源的情况下,确保应用能够正确初始化并找到其运行所需的完整配置信息。

注意:在实际项目中,.yml格式的文件因为其支持结构化数据而更加常用,因此上述文件也可以是.yml扩展名。此外,Spring Boot 2.4后推荐使用.yaml扩展名代替.yml

26、什么是Spring Profiles

Spring Profiles 是 Spring Framework 提供的一种特性,允许开发者根据不同的环境或条件来切换应用程序的不同配置。通过使用Profiles,同一个应用可以在开发、测试、生产等不同环境中加载不同的配置信息,使得应用更加灵活和可移植。

具体案例:

假设我们有一个Spring Boot应用,在不同的环境下数据库连接参数是不一样的。为了在dev(开发)和prod(生产)环境下分别加载不同的数据库配置,可以按照以下方式设置Profile相关的配置文件和代码:

  1. 创建Profile特定的配置文件

    • src/main/resources/目录下创建针对不同环境的配置文件:

      plaintext 复制代码
      application-dev.properties
      application-prod.properties
  2. 在配置文件中添加环境特定的配置

    • application-dev.properties:

      properties 复制代码
      spring.datasource.url=jdbc:mysql://localhost:3306/devdb
      spring.datasource.username=devuser
      spring.datasource.password=devpass
    • application-prod.properties:

      properties 复制代码
      spring.datasource.url=jdbc:mysql://production-db.example.com:3306/proddb
      spring.datasource.username=produser
      spring.datasource.password=prodpass
  3. 激活特定Profile

    • 通过系统属性或命令行参数激活Profile:

      shell 复制代码
      java -jar myapp.jar --spring.profiles.active=dev

      或者在操作系统环境变量中设置:

      bash 复制代码
      export SPRING_PROFILES_ACTIVE=prod
  4. 在代码中注入并使用Profile相关的配置

    java 复制代码
    @Configuration
    public class AppConfig {
    
        @Value("${spring.datasource.url}")
        private String dataSourceUrl;
    
        // ... 其他注入和配置
    
        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource ds = new DriverManagerDataSource();
            ds.setUrl(dataSourceUrl);
            // 设置其他数据源属性如用户名、密码...
            return ds;
        }
    }
  5. 注解驱动Profile

    如果希望某个类或Bean只在特定Profile激活时才生效,可以使用@Profile注解:

    java 复制代码
    @Service
    @Profile("dev")
    public class DevSpecificService {
        // ...
    }
    
    @Service
    @Profile("prod")
    public class ProdSpecificService {
        // ...
    }

这样,当应用启动时,会根据指定的Profile加载相应的配置,并且带有@Profile注解的Bean也会根据当前激活的Profile决定是否实例化并注入到Spring容器中。

IDEA当中使用

在IntelliJ IDEA中配置Spring Boot项目以支持多环境切换,通常涉及以下几个步骤:

配置启动参数

  1. 通过Program Arguments设置

    • 打开IDEA中的Spring Boot项目。

    • 右键点击main()方法或应用启动类,选择"Run/Debug Configurations"(运行/调试配置)。

    • 在弹出窗口中,选择你的Spring Boot运行配置或者新建一个(点击"+"按钮)。

    • 在"VM options"区域不需要填写,而在"Program arguments"区域填入环境激活指令:

      --spring.profiles.active=dev
      

      dev替换为你想要激活的环境名称。

  2. 通过Active Profiles设置

    • 在相同的"Run/Debug Configurations"窗口,在"Environment Variables"部分添加或编辑变量:
      • 变量名:spring.profiles.active
      • 变量值:你希望激活的环境名,如dev
  3. 使用环境变量配置

    • 同样在"Run/Debug Configurations"窗口,可以在"VM options"中指定环境变量来激活Profile:

      -Dspring.profiles.active=prod
      

创建多个启动配置项

为了方便地针对不同环境进行快速启动,可以创建多个启动配置,每个配置对应不同的环境Profile。

  • 每个配置分别设置不同的spring.profiles.active参数。

应用配置文件准备

确保你的项目中有对应的环境配置文件,例如:

  • application-dev.propertiesapplication-dev.yml
  • application-prod.propertiesapplication-prod.yml

当正确配置并启动应用时,Spring Boot会根据指定的Profile加载相应的环境特定配置文件。

27、如何实现SpringBoot多数据源

在Spring Boot中实现多数据源配置,可以通过以下步骤进行:

1. 添加依赖

确保你的项目包含所需的数据库驱动依赖。例如,如果你要连接MySQL和PostgreSQL:

xml 复制代码
<!-- MySQL -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<!-- PostgreSQL -->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
</dependency>

2. 配置多个数据源

application.ymlapplication.properties中配置两个数据源:

yaml 复制代码
# application.yml
spring:
  datasource:
    primary: # 主数据源
      url: jdbc:mysql://localhost:3306/primary_db
      username: primary_user
      password: primary_password
      driver-class-name: com.mysql.cj.jdbc.Driver

    secondary: # 第二个数据源
      url: jdbc:postgresql://localhost:5432/secondary_db
      username: secondary_user
      password: secondary_password
      driver-class-name: org.postgresql.Driver

3. 创建数据源配置类

创建一个Java配置类来定义并注册两个不同数据源的DataSource Bean。

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class DataSourceConfig {

    @Bean(name = "primaryDataSource", destroyMethod = "close")
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    @Primary // 标记主数据源
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryDataSource", destroyMethod = "close")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

4. 配置多数据源JdbcTemplate或JPA

为每个数据源配置JdbcTemplate或JpaRepository。这里以JPA为例:

java 复制代码
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "primaryEntityManagerFactory",
        transactionManagerRef = "primaryTransactionManager",
        basePackages = {"com.example.primary.repository"}
)
public class PrimaryPersistenceConfig {

    @Autowired
    private DataSource primaryDataSource;

    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(primaryDataSource)
                .packages("com.example.primary.entity")
                .build();
    }

    @Bean(name = "primaryTransactionManager")
    public PlatformTransactionManager primaryTransactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactoryBuilder factory) {
        return new JpaTransactionManager(factory.getObject());
    }

    // 类似地,为第二个数据源编写SecondaryPersistenceConfig类...
}

5. 使用多数据源

然后在需要使用特定数据源的地方注入对应的JdbcTemplate、EntityManager或Repository,并通过注解(如@Qualifier)指定具体的数据源。

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

@Service
public class UserService {

    @PersistenceContext(unitName = "primaryEntityManagerFactory")
    private EntityManager primaryEntityManager;

    // 对于第二个数据源,可以注入secondaryEntityManager

    @Transactional("primaryTransactionManager") // 指定事务管理器
    public void someTransactionalMethod() {
        // 使用primaryEntityManager执行操作
    }
}

这样就实现了Spring Boot应用中的多数据源支持。根据实际需求,也可以结合AbstractRoutingDataSource或其他方式动态切换数据源。

28、SpringBoot当中关于使用Sync检查你的依赖关系

在Spring Boot项目中,当你提及"使用Sync检查依赖关系",可能是指IDE(如IntelliJ IDEA)中的Maven或Gradle同步功能来确保本地项目的依赖库与pom.xml或build.gradle文件中声明的依赖版本一致。

对于Maven项目:

  1. 在IntelliJ IDEA中打开你的Spring Boot项目。
  2. 如果需要更新依赖到最新版本或者解决依赖冲突,可以右键点击pom.xml文件,在弹出菜单中选择Maven > Reimport。这将重新解析和下载pom.xml中定义的所有依赖项,并根据dependencyManagement中的规则进行版本控制。

对于Gradle项目:

  1. 对于Gradle项目,你可以通过以下方式更新并检查依赖关系:
    • 右键点击build.gradle文件,选择Gradle > Refresh Gradle Project,这会刷新并重新加载Gradle构建脚本,检查并下载所需的依赖包。
    • 或者在IDEA底部的Gradle工具窗口中找到对应的任务(例如builddependencies等),点击执行该任务,IDEA会自动处理依赖的下载和更新。

此外,为了保持所有依赖始终是最新的稳定版本,Spring Boot项目通常会引用一个父POM,即spring-boot-starter-parent,它提供了spring-boot-dependencies BOM (Bill of Materials),在这个BOM中,Spring Boot团队已经为大部分常用的依赖管理了合适的版本范围。这样,开发者无需在自己的pom.xml中显式指定每个依赖的具体版本,而是继承父POM即可获得兼容性良好的版本组合。

如果你想要手动检查并升级某个特定依赖到其最新的稳定版,可以查看spring-boot-dependencies BOM中该依赖的最新版本范围,然后在自己的pom.xml或build.gradle文件中调整版本号,之后执行上述同步操作。

29、如何实现SpringBoot应用程序的安全性

在Spring Boot应用程序中实现安全性,通常会使用spring-boot-starter-security依赖来集成Spring Security框架。以下是一个基本的Spring Security配置示例:

步骤1:添加依赖

在你的pom.xmlbuild.gradle文件中引入spring-boot-starter-security依赖:

Maven:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle:

groovy 复制代码
implementation 'org.springframework.boot:spring-boot-starter-security'

步骤2:自定义安全配置类

创建一个继承自WebSecurityConfigurerAdapter的Java配置类,并重写其中的方法来自定义认证和授权规则。

java 复制代码
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // HTTP安全配置
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN") // 对/admin路径下的请求要求用户具有ADMIN角色
            .anyRequest().authenticated() // 其他所有请求需要经过身份验证
            .and()
            .formLogin() // 启用基于表单的身份验证
                .loginPage("/login") // 登录页面地址
                .permitAll() // 登录页面允许匿名访问
            .and()
            .logout() // 启用登出功能
                .logoutUrl("/logout") // 登出URL
                .logoutSuccessUrl("/") // 登出成功后的重定向地址
                .permitAll(); // 登出操作允许匿名访问
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // 基本的内存用户认证配置(生产环境中通常会连接到数据库或者LDAP等)
        auth.inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER")
            .and()
            .withUser("admin").password("{noop}adminPass").roles("USER", "ADMIN");
    }
}

上述代码中:

  • configure(HttpSecurity http)方法用于配置HTTP安全策略,包括哪些请求需要权限、登录页设置、登出功能等。
  • configureGlobal(AuthenticationManagerBuilder auth)方法用于配置认证管理器,这里我们简单地设置了两个内存中的用户和密码。

注意:密码使用了{noop}表示明文存储,实际项目中应使用加密方式存储密码。

步骤3:启动应用并测试

运行你的Spring Boot应用,尝试访问受保护的资源(例如 /admin)将会被重定向到登录页面。登录成功后才能访问受保护资源。

此外,你还可以根据需求扩展此配置以支持更多复杂的安全特性,如OAuth2、JWT、自定义用户DetailsService等。

30、比较一下SpringSecurity和Shiro各自优缺点

Spring Security 和 Apache Shiro 都是流行的Java安全框架,用于处理认证(Authentication)、授权(Authorization)以及会话管理等任务。以下是它们各自的优缺点以及一些使用案例概述:

Spring Security

优点:

  1. 深度集成Spring生态:Spring Security是Spring家族的一部分,与Spring框架的其他组件如Spring MVC、Spring Boot无缝集成。
  2. 强大的功能和灵活性:提供全面的安全解决方案,支持多种认证机制(包括OAuth2、JWT等),以及复杂的权限控制策略,如表达式访问控制(EL表达式)。
  3. 社区活跃,文档详尽:拥有广泛的用户群体和丰富的开源插件,官方文档和技术资源丰富。
  4. 企业级特性:如CSRF保护、Remember Me功能、Session Management、内置的过滤器链等。

缺点:

  1. 学习曲线陡峭:相比Shiro,Spring Security的配置可能更为复杂,对于初学者来说上手难度较大。
  2. 过于庞大:对于小型项目或简单应用,其丰富的功能可能显得过于冗余,且需要编写较多的配置代码。

示例代码片段

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .logoutSuccessUrl("/")
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER");
    }
}

Apache Shiro

优点:

  1. 轻量级和易于理解:Shiro的API设计相对简洁,配置更直观,对于简单的场景快速实现起来较为方便。
  2. 独立性:虽然可以很好地集成到任何Java应用中,但并不依赖于Spring框架,因此在非Spring环境下也能够良好工作。
  3. 灵活的认证和授权模型:支持多种Subject身份验证机制,并提供了自定义Realm的扩展能力,权限控制可通过角色、权限或者直接通过URL路径进行。

缺点:

  1. 功能相对较少:相比于Spring Security,Shiro在某些高级功能和特定领域的支持上可能略显不足,例如对OAuth2的支持不如Spring Security成熟。
  2. 社区规模较小:虽然也有一定的社区支持和更新维护,但在社区活跃度和第三方插件支持方面,Spring Security更为突出。

示例代码片段

java 复制代码
public class ShiroConfig {

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(customRealm());
        return securityManager;
    }

    @Bean
    public Realm customRealm() {
        SimpleAccountRealm realm = new SimpleAccountRealm();
        realm.addAccount("user", "password", "USER");
        return realm;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/admin/**", "roles[ADMIN]");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }
}

总结:选择Spring Security还是Apache Shiro主要取决于项目需求、现有技术栈以及团队对框架熟悉程度。Spring Security更适合大型企业级应用和与Spring深度集成的场景,而Shiro则适用于对安全性需求较明确且希望快速实施的中小型项目。

31、比较一下SpringSecurity和Shiro各自优缺点

在Spring Boot中解决跨域问题通常有以下几种方法:

1. 使用@CrossOrigin注解

具体案例代码:

java 复制代码
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600) // 允许所有来源,设置预检请求缓存有效期为3600秒
public class MyController {

    @GetMapping("/api/data")
    public String getData() {
        return "Hello, Cross-Origin!";
    }
}

在这个例子中,@CrossOrigin注解应用于控制器类级别,允许来自任何源("*")的请求,并且设置了预检请求(OPTIONS)的有效期。这样,来自不同域名的前端应用就可以访问这个API。

2. 配置全局跨域过滤器

如果你需要全局配置,可以创建一个全局的CorsFilter并注册到Spring容器中。

具体案例代码:

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许携带cookie
        config.addAllowedOrigin("*"); // 允许所有来源,也可以指定具体的源地址
        config.addAllowedHeader("*"); // 允许所有的头信息
        config.addAllowedMethod("*"); // 允许所有的HTTP方法(GET, POST等)
        
        source.registerCorsConfiguration("/**", config); // 对所有的路径都启用此配置
        
        return new CorsFilter(source);
    }
}

通过这种方式,配置的CORS策略将应用到整个应用程序的所有REST端点上。

3. 使用WebMvcConfigurer接口或WebFluxConfigurer接口(针对WebFlux)

对于基于Spring MVC的应用,可以通过实现WebMvcConfigurer接口并重写其提供的跨域相关方法进行自定义配置。

具体案例代码:

java 复制代码
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

以上代码实现了全局跨域配置,允许所有来源、所有方法和所有头部,并允许带凭证的请求,同时设置了预检请求的有效期为3600秒。

32、SpringBoot中的监视器是什么

Spring Boot 中的监视器通常是指 Spring Boot Actuator,它是一个提供生产就绪功能的模块,用于监控和管理应用程序的运行状态。

Actuator 提供了丰富的端点(endpoints),通过这些端点可以获取应用的各种健康状况信息、metrics指标、环境变量、beans列表、http跟踪等。

以下是一个简单的启用并使用Actuator的基本案例:

  1. 添加依赖:

    pom.xml中添加spring-boot-starter-actuator依赖以启用Actuator。

    xml 复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  2. 配置Actuator:

    默认情况下,部分敏感的端点如/env/metrics等可能被禁用或限制为只读访问。可以在application.propertiesapplication.yml中配置Actuator的详细行为。

    properties 复制代码
    # application.properties
    management.endpoints.web.exposure.include=*
    # 或者仅开启特定端点
    management.endpoints.web.exposure.include=health,info
    
    # 设置Actuator端点的安全性,例如开启basic认证
    management.security.enabled=true
    management.endpoint.health.show-details=always
    spring.security.user.name=admin
    spring.security.user.password=password
  3. 访问端点:

    启动应用后,可以通过HTTP客户端(如curl、Postman等)或者浏览器访问Actuator提供的端点,比如查看应用健康状态:

    bash 复制代码
    curl http://localhost:8080/actuator/health
  4. 使用安全策略:

    如果启用了安全策略,访问上述端点时需要提供基本认证信息。

  5. 示例代码(配置类):

    在某些场景下,你可能需要自定义Actuator的行为,例如自定义健康检查:

    java 复制代码
    import org.springframework.boot.actuate.health.Health;
    import org.springframework.boot.actuate.health.HealthIndicator;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomHealthIndicator implements HealthIndicator {
    
        @Override
        public Health health() {
            int errorCode = check(); // 实现你的检查逻辑
            if (errorCode != 0) {
                return Health.down().withDetail("Error Code", errorCode).build();
            }
            return Health.up().build();
        }
    
        private int check() {
            // 这里模拟一个检查过程,实际项目中应替换为真正的检查逻辑
            return someService.checkSystemStatus();
        }
    }

在以上示例中,我们创建了一个自定义的健康检查指示器,该指示器会报告系统的一个错误码作为健康检查的一部分。

总之,Spring Boot Actuator提供了强大的监控能力,帮助开发者更好地管理和维护应用程序的运行状态。

相关推荐
意疏6 分钟前
JDK动态代理、Cglib动态代理及Spring AOP
java·开发语言·spring
程序员_三木6 分钟前
使用 Three.js 创建圣诞树场景
开发语言·前端·javascript·ecmascript·three
hjxxlsx7 分钟前
什么是Spring Boot 应用开发?
spring boot
小王努力学编程8 分钟前
【C++篇】AVL树的实现
java·开发语言·c++
找了一圈尾巴19 分钟前
Wend看源码-Java-集合学习(List)
java·学习
无名之逆20 分钟前
lombok-macros
开发语言·windows·后端·算法·面试·rust·大学期末
yuanbenshidiaos23 分钟前
C++-----图
开发语言·c++·算法
逊嘘39 分钟前
【Java数据结构】链表相关的算法
java·数据结构·链表
爱编程的小新☆39 分钟前
不良人系列-复兴数据结构(二叉树)
java·数据结构·学习·二叉树
m0_7482478043 分钟前
SpringBoot集成Flowable
java·spring boot·后端