springboot 脚手架


先上github链接

1 创建一个新springboot项目

java1.8 + springboot 2.5.6 + maven 3.8.1

  • 最新版idea创建好项目后,将springboot降级
  • 由于最新版的springboot不支持java1.8,所以需要修改springboot版本,修改到2.4.1**
  • controller必须放在与启动类同一级目录,否则无法扫描到controller下的文件,如果需要不在同一级目录中生效**

    说明代码:

//在启动类上加入@ComponentScan(value = "com.hebut.base"),表示扫描该目录下所有文件
@ComponentScan(value = "com.hebut.base")
@SpringBootApplication()
public class BaseApplication {

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

}

2 集成mybatis plus 以及代码生成器

mybatis plus 3.3.2 + lombok1.18.26 + mybatis-plus-generator3.3.2 + velocity2.0

  • 自动生成代码
  • 解决lombok与新版idea不匹配报红问题
  • 解决无法扫描到mapper接口的问题
//在启动类中加入@MapperScan(value = "com.hebut.base.mapper")

@ComponentScan(value = "com.hebut.base")
@MapperScan(value = "com.hebut.base.mapper")
@SpringBootApplication()
public class BaseApplication {

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

}

3 集成swagger2 + knife4j

集成swagger2 + 控制台输出访问URL信息

  • 集成swagger2 + knife4j2.0.5

[knife4j]:SpringBoot整合Swagger2流程,超详细! - 掘金 (juejin.cn)

  • 控制台打印访问url
@Slf4j
@ComponentScan(value = "com.hebut.base")
@MapperScan(value = "com.hebut.base.mapper")
@SpringBootApplication()
@EnableSwagger2
public class BaseApplication {

    public static void main(String[] args) throws UnknownHostException {
        ConfigurableApplicationContext application =   SpringApplication.run(BaseApplication.class, args);

        //控制台输出访问信息
        Environment env = application.getEnvironment();
        String ip = InetAddress.getLocalHost().getHostAddress();
        String port = env.getProperty("server.port");
        port = port == null ? "8080" : port;
        String path = env.getProperty("server.servlet.context-path");
        path = path == null ? "" : path;
        log.info("\n----------------------------------------------------------\n\t" +
                "Application Demo is running! Access URLs:\n\t" +
                "本地访问地址: \thttp://localhost:" + port + path + "/\n\t" +
                "外部访问地址: \thttp://" + ip + ":" + port + path + "/\n\t" +
                "Swagger文档: \thttp://localhost:" + port + path + "/doc.html\n" +
                "----------------------------------------------------------");
    }

}

4 集成日志框架 Slf4j + logback

slf4j+ logback1.2.3

  • 将application.propertiesp配置文件改为application.yml
  • 集成**slf4j+ logback1.2.3**

    1先引入依赖:

     <!--日志框架-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!--自定义切片-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2在application.yml中设置配置文件位置:


//1 配置文件中配置文件的位置
 #slf4j
logging:
  config: classpath:logback-spring.xml

3在resource文件下新建logback-spring.xml,内容直接复制,可以查看官网看看参数的意思:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--定义日志文件的存储地址-->
    <property name="LOG_HOME" value="./logs" />
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wex}}" />
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="info"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/info/lable-server_%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
            <totalSizeCap>1GB</totalSizeCap>
            <maxFileSize>5MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="error"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/error/lable-server_%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
            <totalSizeCap>1GB</totalSizeCap>
            <maxFileSize>5MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    <!-- 日志输出级别 -->
    <root level="info">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="info" />
        <appender-ref ref="error" />
    </root>
    <!--日志中不输出 HikariCP连接池(它会在启动时输出一些信息)-->
    <logger name="com.zaxxer.hikari" level="OFF"/>

    <!--打印dao层用到的sql-->
    <logger name="com.hebut.base.mapper" level="debug" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>

</configuration>


解释一下部分代码:

	<!--定义日志文件的存储地址-->
    <property name="LOG_HOME" value="./logs" />
    这一句表示会在src同级目录建立一个logs文件夹,部署到服务器上后可以改成你需要的地址

      <!--打印dao层用到的sql-->
    <logger name="com.hebut.base.mapper" level="debug" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>

    这一句表示打印出函数用到的sql语句,注意把com.hebut.base.mapper修改成你目录中存储mapper接口的对应文件

4 最后再创建一个切片LoggingAspect.java,我的位置放在com.hebut.base.config.log:

package com.hebut.base.config.log;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @program: base
 * @description: 扫描controller目录下所有函数,所有执行函数的名称,入参·出参和执行时间
 * @author: cxc
 * @create: 2023-04-03 11:20
 **/
@Aspect
@Component
@Slf4j
public class LoggingAspect {

    /*execution(* com.example.demo.service.*.*(..))是一个切入点表达式,它指定了切入点的位置。
    这个表达式的意思是:拦截com.example.demo.service包下的所有类的所有方法。
    第一个星号表示任意返回类型,第二个星号表示任意类名,两个点表示任意方法名,括号里面的两个点表示任意参数类型和数量*/

    @Around("execution(* com.hebut.base.controller.*.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("====================== log start ======================");

        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long executionTime = System.currentTimeMillis() - start;
        log.info(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        log.info("Method arguments are : " + Arrays.toString(joinPoint.getArgs()));
        log.info("Method returned value is : " + proceed);

        log.info("======================= log end =======================");
        return proceed;
    }
}

注意修改 @Around("execution( com.hebut.base.controller..(…))")为你项目对应的controller层地址。*

实现的效果是打印controller文件夹下所有执行函数的函数名,入参,执行时间,返回结果

  • 名词:

    面向切片编程

5 集成redis

6 全局异常处理 + 统一返回结果类

7 热部署

注意idea新版本的Compiler autoMake allow when app running放在了File》setting》Advanced Setting》conpiler

  • 名词:

    热部署的实现与类加载

8 集成JWT + Shiro + redis

SpringBoot使用@Value给静态变量注入值_springboot @value_「已注销」的博客-CSDN博客

名词 :

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐