Spring boot 论坛项目实战_01
0. 技术架构
-
Spring Boot
-
Spring、SpringMVC、MyBatis
-
Redis、Kafka、Elasticsearch
-
Spring Security、Spring Actuator
1. 开发环境
-
-
集成开发环境:IDEA
-
数据库:MySQL、Redis
-
应用服务器:Apache、Tomcat
-
版本控制工具:Git
2. 搭建开发环境
Apache Maven
-
可以帮助我们构建项目、管理项目中的 jar 包
-
Maven 仓库:存放构件位置
-
本地仓库:默认是 ~/.m2/repostity
-
远程仓库:中央仓库【官网】、镜像仓库【第三方,优选】、私服仓库【公司搭建的】
-
-
示例:安装、配置、常用命令
-
jar 包查询网站:https://mvnrepository.com/
Spring Initializr
-
创建 Spring Boot 项目的引导工具
-
示例:创建 “牛客社区” 项目
-
创建完项目,解压用IDEA打开,记得把 pom.xml 文件加载到 Maven 里面
-
<!-- 参考 pom.xml 文件 --> <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.16.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.nowcoder</groupId> <artifactId>community</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>community</name> <description>nowcoder community</description> <properties> <java.version>11</java.version> </properties> <!-- 重点在依赖文件的配置 --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Spring Boot
-
Spring Boot 核心作用
-
起步依赖、自动配置、端点监控
-
-
示例:
-
一个简单的处理客户端请求案例
-
3. Spring 入门
Spring 全家桶
Spring Framework
Spring Boot
Spring Cloud:微服务
Spring Cloud Data Flow:做数据集成
Spring Framework
-
Spring Core
-
IoC、AOP【管理对象】
-
-
Spring Data Access【访问数据库的功能,管理事务】
-
Transactions、Spring Mybatis
-
-
Web Servlet【Web开发】
-
Spring MVC
-
-
Integration
-
Email、Scheduling、AMQP、Security
-
Spring 常用注解 | 注解对象 |
---|---|
@Controller | Controller对象,控制组件的注解,处理浏览器请求 |
@Service | Service对象,业务组件的注解,处理当前业务 |
@Repository | Repository对象,数据库处理的注解,访问数据库 |
@Component | 全部都可以用 |
Spring IoC
减少 Bean 对象之间的耦合,不用专门实例化对象
-
Inversion of Control
-
控制反转,是一种面向对象编程的设计思想。
-
-
Dependency Injection
-
依赖注入,是 IoC 思想的实现方式。
-
-
IoC Container
-
IoC容器,是实现依赖注入的关键,本质上是一个工厂。
-
被 Spring 管理的 Bean , 默认是 单例——单一实例
如果要修改为多例,需要添加注解:
// 默认单例, single:默认参数
Test文件的注释
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = main实现类名.class)
4. Spring MVC 入门
HTTP
HyperText Transfer Protocol
用于传输 HTML 等内容的 应用层 协议
规定了浏览器和服务器之间如何通信,以及通信时的数据格式
参考官网:https://www.ietf.org
Spring MVC
-
三层架构
-
表现层、业务层、数据访问层
-
-
MVC【解决表现层的问题】
-
Model:模型层
-
View:视图层
-
Controller:控制层
-
-
核心组件
-
前端控制器:DispatcherServlet
-
Thymeleaf
-
模版引擎【模版文件 + Model = 模版引擎 ---》HTML】
-
动态生成的HTML
-
-
Thymeleaf
-
倡导自然模版,即以HTML文件为模版
-
-
常用语法
-
标准表达式、判断与循环、模版的布局
-
5. Mybatis 入门
-
核心组件
-
SqlSessionFactory:用于创建SqlSession的工厂类
-
SqlSession:Mybatis的核心组件,用于向数据库执行SQL
-
主配置文件:XML配置文件,可以对MyBatis的底层行为做出详细的配置
-
【上面三个被 Spring boot 整合了】
-
Mapper接口:就是DAO接口,在Mybatis中习惯性的称之为Mapper
-
Mapper映射器:用于编写SQL,并将SQL和实体类映射的组件,采用XML、注解均可实现。
-
-
示例:
-
使用 Mybatis 对用户表进行 CRUD 操作。
-
参考网站:http://www.mybatis.org/mybatis-3
配置文件
# application.properties 配置
# ServerProperties # 设置服务器端口 server.port=8080 # 项目访问路径设置 server.servlet.context-path=/community # ThymeleafProperties #开发时: 关闭 Thymeleaf 的缓存,保证实时刷新;系统上线后 保持 缓存的开启。 spring.thymeleaf.cache=false # Spring boot 配置 mysql 和 mybatis # DataSourceProperties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/community?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=1234 # 连接池配置,spring boot 中性能最好的 HikariDataSource spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.maximum-pool-size=15 # 保留最小连接数 spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.idle-timeout=30000 # MybatisProperties mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.nowcoder.community.entity # 启用自动生成组件 mybatis.configuration.use-generated-keys=true # 自动匹配 下划线和驼峰,忽略大小写,数据源和实体类匹配 mybatis.configuration.map-underscore-to-camel-case=true # logger # 把这个包的级别设置为 debug logging.level.com.nowcoder.community=debug # 指定日志文件存放位置 logging.file=d:/work/data/nowcoder/community.log
<!-- Pom.xml -->
<!-- 添加 mysql 数据库依赖 和 mybatis-springboot 依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency>
6. 开发社区首页
开发流程
1次清楚的执行过程
分布式先
开发社区首页, 显示前10个帖子
开发分页组件, 分页显示所有的帖子
<!-- 设置表头, 声明所用模板 --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <!-- 非绝对路径的文件, 加上标头, 表示 用 thymeleaf 去查找相应文件 用 "@{....}" ,不会产生歧义 --> th:href="@{/css/global.css}" th:src="@{/js/global.js}" th:utext ----> 会自动转义 文本内的转义字符 <!-- th: 内置工具 #工具名.方法名(...) --> th:text="${#dates.format(map.post.createTime,'yyyy-MM-dd HH:mm:ss')}" <!-- 页面跳转: th:href="@{ 路径(传递的参数)}" th:href="@{${page.path}(current=1,limit=5)}" LIKE: th:href="@{/index?current=1&limit=5}" --> th:href="@{${page.path}(current=1,limit=5)}" <!-- th: 工具 #numbers: 返回一个由连续数字组成的数组 th:each="${#numbers.sequence(起始数, 终止数)}" --> <!-- 所有变量: ${page.XXX} 都是在: 调用 page.getXXX() 方法 --> <!-- 动态判断: th:class="|静态变量 ${动态变量}|" // 当前是第一页, 就不可用 th:class="|page-item ${page.current==1?'disabled':''}|" -->
7. 项目调试技巧
响应状态码的含义
常见状态码:
200: 一切正常
302: 重定向方面
404: 访问出错
500: 服务端有问题
服务端断点调试技巧
IDEA 的 Debug 快捷键 [ 打断点后, Debug 运行 ]:
F8: 向下执行一行
F7: 进入当前行所调用方法内部
F9: 向下执行到下一个断点, 如果没有断点 直接到程序末尾
IDEA 批量管理断点:
批量删除断点:
点这个 “ — ” 实现删除,或着 “delete”键
客户端断点调试技巧
浏览器:Sources中:
F10: 向下执行一步
F11: 进入当前行所调用方法内部
F8: 向下执行到下一个断点, 如果没有断点 直接到程序末尾
设置日志级别,并将日志输出到不同的终端
【建议先看日志分析,再断点调试】
Spring boot 内置默认日志:logback
参考网站: https://logback.qos.ch
五个级别:trace < debug < info < warn < error, 向上兼容的
开发时:常用级别:
error:捕捉到异常
info:线程池,定时任务,特殊任务
debug:暂时调试程序
保存日志到文件:
配置文件(application.properties)中声明:
# 指定日志文件存放位置[笼统的]
logging.file=d:/work/data/nowcoder/community.log取名字:logback-spring.xml 放在 resources 根目录下,spring boot 会自动发现并加载 日志配置
logback-spring.xml
根据项目需求,照着下面的注释改就行
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 声明项目名 --> <contextName>community</contextName> <!-- 日志存放目录 --> <property name="LOG_PATH" value="D:/work/data"/> <!-- 追加日志目录名 --> <property name="APPDIR" value="community"/> <!-- 根据日志类型不同 分别设置 --> <!-- error file --> <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APPDIR}/log_error.log</file> <!-- 日志滚动策略, 设置单一日志大小【超过大小看 append 方式?true【追加】:false【覆盖】】, 时间【超过时间删除】 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>5MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>30</maxHistory> </rollingPolicy> <append>true</append> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!-- 控制台输出日志格式 %d:date 日期 %level:日志级别 %thread:线程 %msg:详细消息 --> <pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> <charset>utf-8</charset> </encoder> <!-- 过滤器:指定过滤类型 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>error</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- warn file --> <appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APPDIR}/log_warn.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>5MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>30</maxHistory> </rollingPolicy> <append>true</append> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> <charset>utf-8</charset> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>warn</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- info file --> <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APPDIR}/log_info.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>5MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>30</maxHistory> </rollingPolicy> <append>true</append> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> <charset>utf-8</charset> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>info</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- console --> <!-- 把日志打印到控制台 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> <charset>utf-8</charset> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>debug</level> </filter> </appender> <logger name="com.nowcoder.community" level="debug"/> <root level="info"> <appender-ref ref="FILE_ERROR"/> <appender-ref ref="FILE_WARN"/> <appender-ref ref="FILE_INFO"/> <appender-ref ref="STDOUT"/> </root> </configuration>
8.版本控制
认识Git
Git简介
Git的安装于配置
Git常用命令
将代码提交至本地仓库
将代码上传至远程仓库
IDEA集成Git
在IEDA中配置并使用Git
参考网站: https://git-scm.com
-
IDEA中为当前项目配置Git
-
如上图所示,在 Git 的安装目录下,选择 bin 目录下的 git.exe
配置好本地 Git 环境后,要在先创建本地仓库,再将本地仓库推送到远程仓库中。
-
-
如上图所示, 选中当前项目的根目录, 然后 选择工具栏中的 VCS [ 版本控制系统 ]
选择当前项目的实际位置
Git 初始化完成
对当前项目进行提交操作
一般就选择上面的几个文件进行提交,.mvn 的自带文件不要勾选
写本次提交的描述,然后点击提交按钮,完成对代码的提交
在远程 Git 仓库建立对应仓库项目【建议与本地仓库同名】,这里我选用的是码云。
建立完成远程仓库后,回到IDEA
【Push:从本地提交到远程仓库,Pull:从远程仓库拉到本地】
初次点击 Push 需要先定义远程仓库位置【】