【Java】SpringBoot应用简单示例

news2025/7/22 5:21:57

SpringBoot应用简单示例

  • SpringBoot应用简单示例
    • HelloWorld
      • 搭建项目
      • @ResponseBody的作用
      • @ComponentScan排除扫描bean
    • SpringBoot集成日志
      • SpringBoot日志初始化原理
    • 消息转换器
    • 拦截器
    • 过滤器
    • 操作数据库
      • Spring Data Jpa
      • Druid数据源
      • Mybatis-Plus
    • 事务处理
    • 操作缓存
    • AOP
      • 相关概念
      • 栗子
    • 定时任务
      • @Scheduled
      • Quartz
    • Spring Boot Admin
    • 参考资料

SpringBoot应用简单示例

HelloWorld

搭建项目

在这里插入图片描述
File -> new project 选择springboot项目初始化。

在这里插入图片描述
在这里插入图片描述
选择项目默认依赖。

在这里插入图片描述

在项目中建一个controller,代码如下:


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * hello world测试类
 * @author Alone
 */
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String Hello() {
        return "Hello,world!";
    }
}


输出结果:
在这里插入图片描述

@ResponseBody的作用

将方法的返回值,以特定的格式写入到response的body区域,进而将数据返回给客户端。当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。如果返回值是字符串,那么直接将字符串写到客户端;如果是一个对象,会将对象转化为json串,然后写到客户端。

@RequestMapping、@ResponseBody 等这些注解是干什么的? - 果真真的回答 - 知乎

前置知识-SpringMVC请求流程

DispatcherServlet#doDispatch

@ComponentScan排除扫描bean

在这里插入图片描述

SpringBoot集成日志

SpringBoot日志初始化原理

在这里插入图片描述

有个loggingApplicationListener的监听器,监听了spring的事件,读取了spring容器中的日志配置,进行了日志的初始化。
(springboot-actuator可以实现动态调整日志级别,待研究)

消息转换器

to be continue

拦截器

拦截器是一种动态拦截方法调用的机制。可以在指定方法前后执行预先设定的代码以及阻止方法调用。

拦截器的实现需要实现HandlerInterceptor 接口:

/**
 * 拦截器测试
 * @author Alone
 */
@Component
public class InterceptConfiguration implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...");
        // 此处返回false导致后面不再执行
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

将拦截器添加入SpringMVC的配置类:

/**
 * @author Alone
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private InterceptConfiguration interceptConfiguration;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptConfiguration);
    }
}

在这里插入图片描述
默认是返回true。

在这里插入图片描述
HandlerInterceptor 中三个方法的作用:

  1. preHandler(HttpServletRequest request, HttpServletResponse response, Object handler) : 方法在请求处理之前调用,在这个方法中进行一些前置预处理或初始化操作,也可以决定是否终止请求。当该方法返回false时,后续的interceptor和controller都不会执行。拦截器可以注册多个,调用时依据声明顺序依次执行。
    handler 参数本质上是一个方法对象,有了它就可以操作原始执行的方法。
  2. postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) : 在当前请求处理之后,DispatcherServlet进行视图渲染之前调用。此时可以对controller处理之后的modelAndView对象进行操作。
  3. afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) : 该方法在整个请求结束后进行调用,主要用于清理资源。

多拦截器的执行顺序:

在这里插入图片描述

过滤器

to be continue

操作数据库

Spring Data Jpa

  1. 引入依赖 pom.xml:
<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>

配置文件application.yml:

spring:
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
  datasource:
    url: jdbc:mysql://localhost:3306/gotest?useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 我是密码

spring.jpa.hibernate.ddl-auto 属性的选项说明:

  • create : 无论数据是否改变,每次hibernate 加载时都删除上一次生成的表
  • create-drop : 每次加载hibernate 时都根据实体类生成表,但是sessionFactory一关闭,表就自动删除。
  • update : 每次加载hibernate时根据model类会自动更新表的结构,不存在则新建。不会删除旧数据。
  • validate : 每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
  • none : 不做任何操作

实体类:

package com.alone.simpleusage.database.datajpa.entity;

import lombok.Data;

import javax.persistence.*;

/**
 * 学生实体类
 * @Entity 表示这是一个实体类
 * @Table 定义数据库表名,jpa在操作的时候会先去寻找这张表,没有这张表的话就创建
 *
 * @author Alone
 */
@Data
@Entity
@Table(name = "student")
public class Student {

    /**
     * @Id 表示这是主键
     * @GeneratedValue 主键生成策略
     * @Column 配置属性和数据库字段的对应
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer urid;

    @Column(name = "code")
    private String code;

    @Column
    private String name;
}

dao接口:

package com.alone.simpleusage.database.datajpa.dao;

import com.alone.simpleusage.database.datajpa.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;

public interface StudentRepository extends JpaRepository<Student, Integer> {
}

运行测试:

@SpringBootTest
public class RepositoryTest {

    @Autowired
    private StudentRepository studentRepository;

    @Test
    public void testInsert() {
        Student student = new Student();
        student.setCode("1");
        student.setName("顶不住了");
        studentRepository.save(student);
    }
}

运行结果:

在这里插入图片描述

Spring JPA实现的默认方法:
在这里插入图片描述
Spring jpa 动态查询:

public interface StudentRepository extends JpaRepository<Student, Integer>, JpaSpecificationExecutor<Student> {
}
@Test
    public void testQuery() {
        List<Student> userList = studentRepository.findAll(((root, criteriaQuery, criteriaBuilder) -> {
            // 定义集合,用于存放动态查询条件
            List<Predicate> predicateList = Lists.newArrayList();
            predicateList.add(criteriaBuilder.like(root.get("code").as(String.class), "%1%"));
            predicateList.add(criteriaBuilder.like(root.get("name").as(String.class), "%顶%"));
            return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
        }));
        userList.forEach(System.out::println);
    }

输出结果:
在这里插入图片描述
多表联查:
to be continue

分页查询:

@Test
    public void testPageQuery() {
        // 构造查询条件
        Specification<Student> spec = new Specification<Student>() {
            @Override
            public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                return null;
            }
        };
        // 分页查询接口
        PageRequest pageRequest = PageRequest.of(0, 1);
        Page<Student> students = studentRepository.findAll(spec, pageRequest);
        System.out.println("查询总页数:" + students.getTotalPages());
        System.out.println("查询总记录数:" + students.getTotalElements());
        System.out.println("数据集合列表:" + students.getContent());
    }

结果:
在这里插入图片描述
排序查询:

@Test
    public void testSortQuery() {
        Sort sort = Sort.by(Sort.Direction.DESC, "urid");
        Specification<Student> spec = new Specification<Student>() {
            @Override
            public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                return null;
            }
        };
        List<Student> studentList = studentRepository.findAll(spec, sort);
        for (Student student : studentList) {
            System.out.println(student);
        }
    }

在这里插入图片描述

Druid数据源

  1. 添加依赖引入druid数据源:
<!-- spring jdbc 操作模版 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- 引入druid数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.4</version>
        </dependency>
  1. 编写配置文件:
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/gotest?useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 密码
    type: com.alibaba.druid.pool.DruidDataSource
  1. 编写配置bean:
/**
 * Druid数据源配置类
 * @author Alone
 */
@Configuration
public class DruidConfig {

    /**
     * 配置绑定
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druid() {
        return new DruidDataSource();
    }
}

此处的前缀prefix要和application.yml中的前缀对应,不然会报java.sql.SQLException: url not set 的异常。
且该注解一定要标在对应bean上。

  1. 测试获取数据源
@Test
    public void testGetDruidDataBase() throws SQLException {
        System.out.println(dataSource.getClass());
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

Mybatis-Plus

  1. 引入依赖:
<!-- mybatis-plus 依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
  1. 配置文件:
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启sql语句打印
  1. 实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    private Long managerId;
    private LocalDateTime createTime;
}

此处简单说一下LocalDateTime相较于Date的优点:

  • Date类型的打印出的日期可读性差
  • Date使用SimpleDateFormat 进行格式化,该对象线程不安全
  • Date日期处理麻烦,getYear() getDay() 等方法均已被弃用
  1. 定义mapper接口
public interface UserMapper extends BaseMapper<User> {
}
  1. 启动类添加mapperscan注解
@SpringBootApplication
@MapperScan("com.alone.simpleusage.database.mpp")
public class SimpleusageApplication {

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

}
  1. 测试
@Test
    public void testUserMapper() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        User user = new User(6L, "test", 10, "123456@163.com", null, LocalDateTime.parse("2022-11-08 15:44:00", df));
        userMapper.insert(user);
    }

事务处理

【Java】Spring事务相关笔记

操作缓存

AOP

相关概念

栗子

springboot切面实现打印当前系统时间:

pom.xml:

<!-- aop依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

切面类:

package com.alone.simpleusage.aop.aspect;

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

import java.text.SimpleDateFormat;

/**
 * 切面类
 * @author Alone
 */
@Aspect
@Component
@Slf4j
public class SysOutTimeAspect {


    /**
     * 切入点方法
     */
    @Pointcut("execution(public * com.alone.simpleusage.aop.controller.*.*(..))")
    public void printTime() {

    }

    /**
     * 前置通知
     * 这里的方法名和入参都不能写错,不然会进不去需要被增强的方法
     * @param joinPoint
     */
    @Before("printTime()")
    public void doBefore(JoinPoint joinPoint) {
        log.info("开始打印");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info(df.format(System.currentTimeMillis()));

    }
}

测试类:

package com.alone.simpleusage.aop.controller;

import org.springframework.web.bind.annotation.*;

/**
 * 切面测试controller
 * @author Alone
 */
@RestController
@RequestMapping("/aoptest")
public class AopController {

    @RequestMapping("/hello")
    public String hello(@RequestParam(value = "name", required = false) String name) {
        System.out.println("进入hello方法");
        return "hello" + name;
    }
}

结果:

在这里插入图片描述
在这里插入图片描述

定时任务

@Scheduled

Quartz

Spring Boot Admin

参考资料

  1. springboot动态调整日志级别
  2. 玩转 Spring Boot 系列案例源码
  3. 优雅的使用spring boot: 消息转换器的介绍与使用
  4. SpringBoot实现过滤器、拦截器与切片
  5. 黑马程序员2022新版SSM框架教程
  6. SpringBoot图文教程12—SpringData Jpa的基本使用
  7. Springboot 系列(九)使用 Spring JDBC 和 Druid 数据源监控
  8. mybatis plus 看这篇就够了,一发入魂
  9. 学会了MybatisPlus,代码开发效率提高了10倍!
  10. Spring Boot (五): Redis缓存使用姿势盘点
  11. Spring boot学习(六)Spring boot实现AOP记录操作日志
  12. SpringBoot—集成AOP详解(面向切面编程Aspect)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/7748.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言解析JSON源码

它与 XML 的地位差不多&#xff0c;但就笔者而言&#xff0c;笔者更喜欢 JSON 的风格&#xff0c;因为它更符合我们的思维习惯&#xff0c;同样一份数据&#xff0c;JSON 格式的就是比 XML 要清晰明了一些。 最近笔者需要在 C语言 上解析 JSON 格式&#xff0c;在网上一顿找&am…

XC5VLX30T-2FF323I Virtex-5 LXT FPGA IC 产品参数

概述 Virtex-5 FPGA有-3&#xff0c;-2&#xff0c;-1速度等级&#xff0c;其中-3具有最高的性能。Virtex-5 FPGA直流和交流特性指定为商业和工业级别。除工作温度范围外&#xff0c;除非另有说明&#xff0c;所有直流和交流电气参数对于特定转速等级是相同的(即-1转速等级的工…

一夜登顶GitHub!字节内网数据结构与算法刷题笔记,看完直呼卧槽

网络上流传着一句段子“程序员两条腿&#xff0c;一条是算法&#xff0c;一条是英文&#xff0c;想跑的更远&#xff0c;这两条腿都不能弱”。英文&#xff0c;我们暂且不谈&#xff0c;我们先来谈谈算法。 算法之难&#xff0c;在于将精巧的逻辑&#xff0c;通过合适的数据结…

2 分钟,教你用 Serverless 每天给女朋友自动发土味情话

作者&#xff1a;安可 Serverless 简介 Serverless&#xff0c;中文意思是 “无服务器”&#xff0c;所谓的无服务器并非是说不需要依靠服务器等资源&#xff0c;而是说开发者再也不用过多考虑服务器的问题&#xff0c;可以更专注在产品代码上&#xff0c;同时计算资源也开始…

如何根据自己的SCI论文,匹配适合的期刊? - 易智编译EaseEditing

如何选择合适的目标期刊是需要慎重对待的问题&#xff0c;它决定了你论文的发表速度和被认可度。 可以遵循以下几个步骤来考虑&#xff1a; 1、从你论文的参考文献中选择合适的期刊&#xff08;如果引用文献较少&#xff0c;也可以从引文的参考文献中进行筛选&#xff09;&…

成功解决:ModuleNotFoundError: No module named ‘amp_C‘

在使用transformers时&#xff0c;在调用Trainer的时候遇到了这个问题&#xff0c;原因是apex包有问题&#xff0c; 这里有解决apex安装包的多一些教程 https://blog.csdn.net/Xidian185/article/details/122745427 https://blog.csdn.net/weixin_45225975/article/details/119…

倍福TwinCAT3中使用久同伺服

目录 一、测试设备说明 二、伺服通电和参数设置 1、恢复出厂参数设置 2、恢复出厂&#xff0c;重启后 3、伺服自己点动操作 4、增益、刚度调整 5、伺服零位设定 6、伺服转动一圈编码器脉冲量设定 7、参数保存 三、伺服操作面板 四、TwinCAT3工程配置 1、XML文件 2、…

【元宇宙欧米说】打造艺术与技术构建的交互式数字旅程

Web3 to Earn项目如何扩大应用功能和场景&#xff1f;在Web3时代怎么才能以更新颖、有趣的方式追赶潮流&#xff1f;各Web3领域项目及应用如何进行功能外延以满足用户需求&#xff1f; 11月17日晚上九点&#xff0c;ZenCats项目管理员Fred将以“打造艺术与技术构建的交互式数字…

编码格式转换方法

今天项目上遇到了需要将 SJIS(Shift-JIS) 格式与 UTF8 格式相互转换问题。 首先看一个编码格式问题引发的乱码现象&#xff0c;新建下面的文本文档&#xff0c;然后更名为 test.bat。 echo off echo test chinese character view 测试中文字符显示 pause双击运行 用 chcp 查…

正版授权| iObit Uninstaller 12 Pro 专业卸载器工具

前言 专业的Win系统卸载程序&#xff0c;它可以轻松删除不需要的程序&#xff0c;插件和Windows应用程序&#xff0c;还可以对电脑旧的应用一键更新。安装监视器会检测并记录安装中的所有系统更改&#xff0c;以确保在将来彻底卸载时可以还原所有更改。 功能特点 安装监视器 …

1053 Path of Equal Weight

Given a non-empty tree with root R, and with weight Wi​ assigned to each tree node Ti​. The weight of a path from R to L is defined to be the sum of the weights of all the nodes along the path from R to any leaf node L. Now given any weighted tree, you a…

QT获取计算机硬件信息

一、项目介绍 本文介绍利用QProcess获取计算机的CPU、主板、硬盘等电脑相关硬件信息。 windows提供了“wmic”&#xff08;Windows Management Instrumentation&#xff0c;Windows管理工具&#xff09;&#xff0c;提供了从命令行接口和批命令脚本执行系统管理的支持。可以打…

基于多个openEuler物理机执行mugen测试脚本

【原文链接】基于多个openEuler物理机执行mugen测试脚本 mugen脚本中有的脚本执行需要使用多个物理机&#xff0c;针对此场景&#xff0c;这里以需要两个物理机为例&#xff08;用openEuler虚拟机模拟物理机&#xff09; &#xff08;1&#xff09;首先安装两台openEuler虚拟…

【C++】C++基础知识(一)---基本概念

C基础知识&#xff08;一&#xff09;1. 输出“HelloWorld!”2. 添加注释3. 关键字4. 标识符5. 变量6. 常量1. 输出“HelloWorld!” 在visual studio中输出“HelloWorld!”。代码实现如下&#xff1a; #include <iostream> using namespace std;int main() {cout <&…

unity搭建xlua和emmy_lua的debug环境

配置步骤 1 环境 1.1 vscode 安装emmy_lua 1.2 安装对应的lua版本 1.3 安装java8并配置环境 1.4 emmy_lua的github上下载emmy_lua的64位版本&#xff0c;解压放到工程目录client\Tools\EmmyLua\ 下载地址&#xff1a;https://github.com/EmmyLua/EmmyLuaDebugger/release…

「Redis数据结构」动态字符串(SDS)

「Redis数据结构」动态字符串&#xff08;SDS&#xff09; 文章目录「Redis数据结构」动态字符串&#xff08;SDS&#xff09;[toc]一、前言二、概述三、C字符串与SDS的区别获取字符串长度复杂度杜绝缓冲区溢出减少修改字符串时的内存分配次数二进制安全兼容部分C字符串函数参考…

【PyTorch】Transforms基本使用

文章目录二、Transforms基本使用1、Transforms的结构及用法1.1 如何使用1.2 TensorBoard查看2、常用的Transforms2.1 ToTensor2.2 Normalize2.3 Resize2.4 Compose2.5 RandomCrop二、Transforms基本使用 Transforms主要是对特定格式的图片进行一些变化。 1、Transforms的结构及…

展锐UIS8310 CAT4物联网模块简介

1.简介 UIS8310是一个高度集成的应用处理器&#xff0c;支持TDD-LTE、FDD-LTE和WCDMA、GSM/GPRS/EDGE制式&#xff0c;并且支持LPDDR2。它的AP处理器是单核ARM CortexTM A7 1GHz&#xff0c;旨在为物联网提供经济高效、低功耗和高性能的解决方案。 UIS8310经过特别优化的架构可…

Servlet之RequestReponse 学习笔记

1 Request 1.1 Request继承关系 ServletRequest Java提供的请求对象根接口 HttpServletRequest Java提供的对Http协议封装的请求对象接口 RequestFacade Tomcat定义的实现类WebServlet("/demo2") public class Servlet2Demo extends HttpServlet {Overridep…

Vue 路由router的介绍以及使用方法

路由&#xff1a;简单来说类似于路由器&#xff0c;中转站。 1.理解: 一个路由&#xff08;route&#xff09;就是一组映射关系&#xff08;key - value&#xff09;&#xff0c;多个路由需要路由器&#xff08;router&#xff09;进行管理。 2.前端路由&#xff1a;key是路径&…