Spring boot 论坛项目实战_01

Spring boot 论坛项目实战

项目Git: https://github.com/LJ117/Nowcoder_Prac_community

0. 技术架构

  • Spring Boot

  • Spring、SpringMVC、MyBatis

  • Redis、Kafka、Elasticsearch

  • Spring Security、Spring Actuator

 

1. 开发环境

  • 构建工具:Apache Maven

  • 集成开发环境:IDEA

  • 数据库:MySQL、Redis

  • 应用服务器:Apache、Tomcat

  • 版本控制工具:Git

 

2. 搭建开发环境

Apache Maven

  • 可以帮助我们构建项目、管理项目中的 jar 包

  • Maven 仓库:存放构件位置

    • 本地仓库:默认是 ~/.m2/repostity

    • 远程仓库:中央仓库【官网】、镜像仓库【第三方,优选】、私服仓库【公司搭建的】

  • 示例:安装、配置、常用命令

  • 官网:http://maven.apache.org

  • jar 包查询网站:https://mvnrepository.com/

 

Spring Initializr

  • 创建 Spring Boot 项目的引导工具

  • 示例:创建 “牛客社区” 项目

  • 官网:https://start.spring.io

  • 创建完项目,解压用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:默认参数
@Scope("singleton")
// 修改为多例,实际工作中使用较少
@Scope("prototype")
@Autowired // 自动根据类型注入
@Qualifier("...") //多个同类型 bean下,指定名称注入对应名称的bean
// 项目中, 通常直接注入给属性。

 

Test文件的注释

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = main实现类名.class)

 

4. Spring MVC 入门

HTTP

  • HyperText Transfer Protocol

  • 用于传输 HTML 等内容的 应用层 协议

  • 规定了浏览器和服务器之间如何通信,以及通信时的数据格式

参考官网:https://www.ietf.org

https://developer.mozilla.org/zh-CN

 

Spring MVC

  • 三层架构

    • 表现层、业务层、数据访问层

  • MVC【解决表现层的问题】

    • Model:模型层

    • View:视图层

    • Controller:控制层

  • 核心组件

    • 前端控制器:DispatcherServlet

 

Thymeleaf

  • 模版引擎【模版文件 + Model = 模版引擎 ---》HTML】

    • 动态生成的HTML

  • Thymeleaf

    • 倡导自然模版,即以HTML文件为模版

  • 常用语法

    • 标准表达式、判断与循环、模版的布局

  • 官网:https://www.thymeleaf.org

 

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

http://www.mybatis.org/spring

配置文件

# 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 需要先定义远程仓库位置【】

    即远程仓库所在的 URL

原文地址:https://www.cnblogs.com/77-is-here/p/13585996.html