spring-boot

寇靖
2023-12-01

Springboot

一. springboot诞生的背景

​ 出现spring、mybatis、springmvc框架能够帮助我们去解决在Servlet中大量重复代码的问题,但是他们又引入了新的问题,虽然能够帮我们简化重复代码的书写,但是要写很多的配置;springboot的出现就是为了解决这些框架大量配置的问题。

二. springboot搭建

第一步,创建一个 quickstart 工程

第二步,引入依赖pom依赖

<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.3.5.RELEASE</version>
</parent>
 <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

第三步,编写启动类

@SpringBootApplication
public class FirstSpringBootApplication {   // FirstSpringBootApplication也会被纳入到IOC容器中
    public static void main( String[] args) {
        /**
         * 启动springboot的项目,第一个参数是标注了 @SpringBootApplication 这个注解的类型
         */
        ConfigurableApplicationContext ctx = SpringApplication.run(FirstSpringBootApplication.class, args);

//        Stream.of(ctx.getBeanDefinitionNames()).forEach(System.out::println);  // 可以拿到整个IOC容器中所有的Bean的名字
    }
}

第四部,编写任意的 Controller, 启动服务,即可实现访问。

三. 属性注入

将属性配置注入到Spring 的Bean中,在很多中间件中都需要去定义一些属性的,方式总共有四种:

第一种方式,@ConfigurationProperties 和 @Component 搭配使用,属性需要在 application.yml 中进行配置;

@ConfigurationProperties(prefix = "person")
@Component
public class Person {
    private Integer id;
    private String name;
    private List<String> interests;
    
    // setter and getter 
}
# yaml 文件中内容
person:
   id: 10
   name: 李四
   interests:
     - movie
     - sport
     - read

第二种方式,@ConfigurationProperties 和 @EnableConfigurationProperties 搭配使用,但是要注意以下两点:

  1. @EnableConfigurationProperties 需要放在一个被纳入到 IOC 容器的Bean的头顶;
  2. @EnableConfigurationProperties 和 @ConfigurationProperties 不是在一起使用的;
  3. @EnableConfigurationProperties 的值是头顶加了 @ConfigurationProperties 这个类的 Class 类型的对象
@ConfigurationProperties(prefix = "person")
public class Person {
    private Integer id;
    private String name;
    private List<String> interests;
    
    // setter and getter 
}
@SpringBootApplication
@EnableConfigurationProperties(Person.class)
public class FirstSpringBootApplication {   // FirstSpringBootApplication也会被纳入到IOC容器中
    public static void main( String[] args) {
        /**
         * 启动springboot的项目,第一个参数是标注了 @SpringBootApplication 这个注解的类型
         */
		SpringApplication.run(FirstSpringBootApplication.class, args);
    }
}
# yaml 文件中内容
person:
   id: 10
   name: 李四
   interests:
     - movie
     - sport
     - read

第三种方式,@PropertySource(“classpath: /config.properties”) 和 @Component 搭配使用,然后属性要使用 @Value 实现注入

@PropertySource(value="classpath:/config.properties", encoding = "utf-8")
@Component
public class User {
    @Value("${user.id}")
    private Integer id;
    @Value("${user.nickname}")
    private String name;
    @Value("${user.interests}")
    private List<String> interests;
    // 
}

第四种方式,@PropertySource 和 @ConfigurationProperties 、@Component 搭配使用,@PropertySource来指定外部资源; @ConfigurationProperties 指定前缀。不需要使用 @Value 来实现属性的注入

@PropertySource("classpath:/config.properties")
@ConfigurationProperties(prefix = "wx")
@Component
public class Pay {
    private String appKey;
    private String tradeId;
    
    // setter and getter 
}

四. logback日志

logback和log4j的作者是同一人,log4j是同步记录日志,但是logback是异步的方式来记录日志的。

<?xml version="1.0" encoding="UTF-8"?>

<!-- scan: 当配置文件被修改后, 将会被重新载入。
	 scanPeriod: 置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
	 debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 输出到控制台 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 配置日志输出到控制台的格式 --> debug info warn error fatal
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -- %-4relative %-5level %logger{32} %thread -- %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
    </appender>

    <!-- 将日志记录到文件当中 -->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 基于时间和大小的的滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名, 必须包含%i, 从1开始-->
            <FileNamePattern>D:/logs/logback.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
            <!-- 最大20KB 超过最大值,会重新建一个文件-->
            <maxFileSize>20MB</maxFileSize>
            <!-- 所有的日志加起来最大的大小, 以它为基准 -->
            <totalSizeCap>400MB</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %thread -- %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
    </appender>

    <!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。 -->
    <root level="info">
        <!-- 标识这个appender将会添加到这个loger。 -->
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    </root>

</configuration>

五. springboot与mybatis的整合

第一步,引入依赖

<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.3.5.RELEASE</version>
</parent>
<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
	<dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.2.0</version>
    </dependency>
    <!-- 替代 druid  -->
    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP-java7</artifactId>
      <version>2.4.13</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- 分页插件 -->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>1.2.12</version>
    </dependency>
 </dependencies>

第二步,application.yml 文件配置

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/es?serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      # 链接池的最大链接数量
      maximum-pool-size: 20
	  # 链接池的最小链接数量
      minimum-idle: 5
      # 链接初始化的时候发送的sql, 进而验证sql是否有效
      connection-init-sql: select 1
mybatis:
  mapper-locations: classpath:org/example/**/*.xml
  configuration:
    # 控制日志打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
        
pagehelper:
  # 分页合理化, 当前页超过总页数,会查询最后一页
  reasonable: true

六. MyBatis-plus

​ Mybatis-plus 是 mybatis的增强版,但是其只适合单表操作,不影响 mybatis 现有的使用,对于单表操作我们可以不用书写 mapper 文件,但是如果存在多表或者复杂的查询还是需要定义 mapper 文件。

​ Mybatis-plus 在使用的时候,只需要在Mapper的接口上继承 BaseMapper<T>.

  1. 根据id查询
// Integer String 都是 Serializable 的子类
// Goods goods = goodMapper.selectById(Serializable id);

Goods goods = goodMapper.selectById(2001);
  1. id的in查询
// List<Goods> list = goodMapper.selectBatchIds(Collection<? extends Serializable> ids);

List<Goods> list = goodMapper.selectBatchIds(Arrays.asList(2001, 2002, 2003));
  1. 查询所有
// List<Goods> list = goodMapper.selectList(Wrappre wrapper);

List<Goods> list = goodMapper.selectList(null);
  1. 多条件查询
// List<Goods> list = goodMapper.selectList(Wrappre wrapper);

// select * from t_goods where id >= 2001 and id < 2010 and promo_words like '%锅%';
 QueryWrapper queryWrapper = new QueryWrapper();
 queryWrapper.le("id", 2010);
 queryWrapper.ge("id", 2001);
 queryWrapper.like("promo_words", "锅");

List<Goods> list = goodMapper.selectList(queryWrapper);

注解:

  1. @TableName() 当类名与表名不一致的时候,需要通过该注解来指定
  2. @TableField 当属性名与字段名不一致的时候,通过该注解来指定
  3. @TableId(type=IdType.AUTO) 表示注解由数据库来决定

七. springboot与mybatis-plus的整合

第一步,引入依赖

<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.3.5.RELEASE</version>
</parent>
<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
	<dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.3.2</version>
    </dependency>
    </dependency>
    <!-- 替代 druid  -->
    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP-java7</artifactId>
      <version>2.4.13</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- 分页插件 -->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>1.2.12</version>
    </dependency>
 </dependencies>

第二步,application.yml 文件配置

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/es?serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      # 链接池的最大链接数量
      maximum-pool-size: 20
	  # 链接池的最小链接数量
      minimum-idle: 5
      # 链接初始化的时候发送的sql, 进而验证sql是否有效
      connection-init-sql: select 1
mybatis-plus:
  mapper-locations: classpath:org/example/**/*.xml
  configuration:
    # 控制日志打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
        
pagehelper:
  # 分页合理化, 当前页超过总页数,会查询最后一页
  reasonable: true

八. springboot配置拦截以及过滤器

过滤器与拦截器的区别?都可以实现资源的拦截与过滤,但是过滤是Servlet中的内容,拦截器是 SpringMVC 框架的内容,在使用上过滤器用来过滤所有的资源,但是拦截 器只是针对 Controller.

8.1 配置过滤器

在 Servlet 阶段,书写过滤器的方式如下:

<filter>
	<filter-name>firstFilter</filter-name>
    <filter-class>org.FirstFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>firstFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

第一步,写一个过滤器,实现 Filter 接口

第二步,配置过滤器

 @Bean
 public FilterRegistrationBean<FirstFilter> filterRegistrationBean() {
    FilterRegistrationBean<FirstFilter> registrationBean = new FilterRegistrationBean<>();
    // 设置过滤器    
    registrationBean.setFilter(new FirstFilter());
    registrationBean.setName("firstFilter"); // 设置过滤器的名字
    registrationBean.addUrlPatterns("/*");  // 针对哪些资源进行过滤
    registrationBean.setOrder(11);  // 数字越小,越先执行
    return registrationBean;
}

8.2 配置拦截器

springmvc中设置拦截器的方式:

<mvc:interceptors>
         <mvc:interceptor>
             <!-- classpath:org/exmple/两个星星/*.xml, 这种语法在spring中叫 ant 语法 -->
             <mvc:mapping path="/user/**"></mvc:mapping>
             <mvc:mapping path="/person/**"></mvc:mapping>
             <mvc:exclude-mapping path="/user/edit"></mvc:exclude-mapping>
             <bean class="org.example.interceptor.UserInterceptor"></bean>
         </mvc:interceptor>
</mvc:interceptors>

第一步,编写拦截器,实现 HandlerInterceptor 接口

第二步,配置拦截器

@Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 创建拦截器的实例
        UserInterceptor userInterceptor = new UserInterceptor();
        registry.addInterceptor(userInterceptor)
                .addPathPatterns(Arrays.asList("/goods/**", "/first/**"))
                .excludePathPatterns("/first/test");
//                .addPathPatterns("/user/**", "/person")
}

九. BeanFactory和FactoryBean的区别

BeanFactory是SpringIOC容器的顶级接口,它也是IOC的容器,它规范了对IOC容器中Bean的一系列操作;

FactoryBean是一个对象,用来创建Spring容器中的Bean,在Spring中所有的代理对象都是通过该对象来生成的(代理对象的生成是Spring的第三级缓存中生成)。

 类似资料: