SpringBoot复习

发布于:2025-07-25 ⋅ 阅读:(18) ⋅ 点赞:(0)

SprintBoot笔记

1、IOC 模式

在 Java 中,IOC(Inversion of Control,控制反转)是一种设计原则,用于降低代码间的耦合度,是 Spring 等主流框架的核心思想之一。

简单来说,控制反转指的是将对象的创建、依赖关系的管理等 “控制权” 从代码本身转移到外部容器(如 Spring 容器)。

  • 传统方式:对象 A 需要依赖对象 B 时,通常会在 A 的代码中直接创建 B 的实例(如B b = new B()),此时 A 完全控制着 B 的创建,耦合度高。
  • IOC 方式:对象的创建和依赖注入由外部容器负责,A 只需要声明需要 B,容器会自动将 B 的实例 “注入” 到 A 中,无需 A 主动创建。
  • 核心思想
  1. 反转控制权:将对象的创建、组装、生命周期管理等控制权交给容器,而非由代码主动控制。
  2. 依赖注入(DI):IOC 的实现方式之一,容器通过构造函数、setter 方法等方式,将对象依赖的组件自动注入到对象中。
  3. 解耦:减少类与类之间的直接依赖,提高代码的灵活性、可维护性和可测试性。
2、AOP编程

(Aspect-Oriented Programming,面向切面编程)。一种编程范式,旨在通过 “切面” 思想解决代码中横切关注点(Cross-cutting Concerns)的问题,与 OOP(面向对象编程)相辅相成。

核心概念

  1. 横切关注点:指那些在应用中多处重复出现的功能,如日志记录、事务管理、权限验证、异常处理等。这些功能若分散在业务代码中,会导致代码冗余且难以维护。
  2. 切面(Aspect):将横切关注点模块化封装的组件,例如一个日志切面类专门处理所有日志相关逻辑。
  3. 连接点(Join Point):程序执行过程中的特定点(如方法调用、异常抛出等),是切面可以插入的位置。
  4. 切入点(Pointcut):定义切面要作用的连接点集合(通过表达式指定),例如 “所有 Service 层的 save 方法”。
  5. 通知(Advice):切面在特定连接点执行的代码,分为 5 种类型:
    • 前置通知(Before):目标方法执行前执行
    • 后置通知(After):目标方法执行后执行(无论是否异常)
    • 返回通知(AfterReturning):目标方法正常返回后执行
    • 异常通知(AfterThrowing):目标方法抛出异常后执行
    • 环绕通知(Around):包裹目标方法,可自定义执行逻辑
  6. 目标对象(Target Object):被切面增强的对象(原始业务对象)。
  7. 代理对象(Proxy):AOP 框架创建的、包含原始对象功能和切面逻辑的代理对象。

工作原理

AOP 通过动态代理实现:在不修改原始代码的情况下,生成代理对象,将切面逻辑织入(Weaving)到目标方法的执行过程中,实现横切关注点与业务逻辑的分离。

3、SprintBoot注解

@SpringBootConfiguration:标注在某个类上 , 表示这是一个SpringBoot的配置类;

@EnableAutoConfiguration :开启自动配置功能

@SpringBootApplication:表示该类是启动类

这个类主要做了以下四件事情:

1、推断应用的类型是普通的项目还是Web项目

2、查找并加载所有可用初始化器 , 设置到initializers属性中

3、找出所有的应用程序监听器,设置到listeners属性中

4、推断并设置main方法的定义类,找到运行的主类

4、配置文件
  • application.properties

    • 语法结构 :key=value
  • application.yml

    • 语法结构 :key:空格 value

yaml注入配置文件

@Component //注册bean,将Dog类创建放入到IOC容器中
public class Dog {
    @Value("阿黄")   //给Bean注入属性值
    private String name;
    @Value("18")
    private Integer age;
}



//从yaml文件中读取数据自动配置属性值
@Component
@ConfigurationProperties(prefix = "person")  //这里在Yaml写的有对应的数据
public class Person {
    private String name;
    private Integer age;
}

//需要文件处理器
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>

加载指定的配置文件

//在项目目录下创建一个新的配置文件,然后加上注解就可以指定加载
@PropertySource(value = "classpath:person.properties")
@Component //注册bean
public class Person {

    @Value("${name}")
    private String name;

    ......  
}

配置文件占位符

//在这里可以使用${}进行展占位,里面放一些函数或变量
person:
    name: qinjiang${random.uuid} # 随机uuid
    age: ${random.int}  # 随机int
    happy: false
    birth: 2000/01/01
    maps: {k1: v1,k2: v2}
    lists:
      - code
      - girl
      - music
    dog:
      name: ${person.hello:other}_旺财
      age: 1
5、JSR303数据校验

Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。

//在类上面加入@Validated注解可以启动数据校验,在需要校验的字段上面加入注解就可以检验字段的值格式是否正确

@Component //注册bean
@ConfigurationProperties(prefix = "person")
@Validated  //数据校验
public class Person {

    @Email(message="邮箱格式错误") //name必须是邮箱格式
    private String name;
}

常见校验规则


@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;

空检查
@Null       验证对象是否为null
@NotNull    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty   检查约束元素是否为NULL或者是EMPTY.
    
Booelan检查
@AssertTrue     验证 Boolean 对象是否为 true  
@AssertFalse    验证 Boolean 对象是否为 false  
    
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=) string is between min and max included.

日期检查
@Past       验证 DateCalendar 对象是否在当前时间之前  
@Future     验证 DateCalendar 对象是否在当前时间之后  
@Pattern    验证 String 对象是否符合正则表达式的规则
6、整合JDBC

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

编写配置文件


spring:
  datasource:
    username: root
    password: 123456
    #?serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver   # MySQL 8+ 必须显式声明

测试连接

@SpringBootTest
class SpringbootDataJdbcApplicationTests {

    //DI注入数据源
    @Autowired
    DataSource dataSource;

    @Test
    public void contextLoads() throws SQLException {
        //看一下默认数据源
        System.out.println(dataSource.getClass());
        //获得连接
        Connection connection =   dataSource.getConnection();
        System.out.println(connection);
        //关闭连接
        connection.close();
    }
}

JDBCTemplate

  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
  • query方法及queryForXXX方法:用于执行查询相关语句;
  • call方法:用于执行存储过程、函数相关语句。
7、整合Druid

添加依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.23</version>
</dependency>

切换数据源,Spring Boot 2.0 以上默认使用 com.zaxxer.hikari.HikariDataSource 数据源,但可以 通过 spring.datasource.type 指定数据源。

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源

设置Druid的基础配置信息


spring:
  datasource:
    username: root
    password: 123456
    #?serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

自定义Druid配置

@Configuration
public class DruidConfig {

    /*
    将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
    绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
    @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
    前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
  */
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }


    //配置 Druid 监控管理后台的Servlet;
//内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");

        // 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet
        // 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
        Map<String, String> initParams = new HashMap<>();
        initParams.put("loginUsername", "admin"); //后台管理界面的登录账号
        initParams.put("loginPassword", "123456"); //后台管理界面的登录密码

        //后台允许谁可以访问
        //initParams.put("allow", "localhost"):表示只有本机可以访问
        //initParams.put("allow", ""):为空或者为null时,表示允许所有访问
        initParams.put("allow", "");
        //deny:Druid 后台拒绝谁访问
        //initParams.put("kuangshen", "192.168.1.20");表示禁止此ip访问

        //设置初始化参数
        bean.setInitParameters(initParams);
        return bean;
    }

    //配置 Druid web 监控 filter 过滤器
    //配置 Druid 监控 之  web 监控的 filter
//WebStatFilter:用于配置Web和Druid数据源之间的管理关联监控统计
    @Bean
    public FilterRegistrationBean webStatFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        //exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
        Map<String, String> initParams = new HashMap<>();
        initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");
        bean.setInitParameters(initParams);

        //"/*" 表示过滤所有请求
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}
8、整合MyBatis

添加依赖

<!-- MyBatis-Plus 核心依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

创建实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    private String name;
    private int age;
    private String sex;
}

创建mapper目录、创建mapper类

//@Mapper : 表示本类是一个 MyBatis 的 Mapper
//@Repository 是 Spring 的注解,主要用于让 Spring 识别该接口为数据访问层组件,并进行管理。
@Mapper
@Repository
public interface UserMapper extends BaseMapper<User> {

    //获取所有用户信息
    List<User> getAllUsers();
}

创建对应的Mapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.daitools.learn.mapper.UserMapper">

    <select id="getAllUsers" resultType="com.daitools.learn.entity.User">
        select * from user;
    </select>
</mapper>

Maven配置资源过滤


<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
    </resource>
</resources>

测试代码

@Autowired
UserMapper userMapper;
@Test
public void getUsers(){
    List<User> allUsers = userMapper.getAllUsers();
    for(User user:allUsers)
        System.out.println(user);
}
9、配置静态资源

配置静态资源路径src/main/resources/static

spring:
  # 配置静态资源
  resources:
    static-locations=classpath: /static

SpringBoot默认在static 目录中存放静态资源,而 templates 中放动态页面。

先添加thymeleaf依赖

<!--thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

在resources目录下创建templates目录,在这个目录中创建动态页面

创建controller,这个controller是可以直接返回模板页面的

@Controller
public class thymeleafController {

    //直接返回模板目录下的test页面
    @RequestMapping("/t1")
    public String test1(){
        return "test";
    }
}

想要在页面中增加数据,那么需要修改controller中的方法,以及模板页面

//方法中传入Model实例化对象
//使用Model中的方法添加数据
    @RequestMapping("/t1")
    public String test1(Model model){
        // 向模板文件中添加数据
        model.addAttribute("msg","我是在模板中添加的数据。");
        return "test";
    }

在模板文件中添加thymeleaf的命名空间约束,然后使用thymeleaf语法取出model中的数据

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
<div>将添加到模板中的数据取出来显示</div>
<div th:text="${msg}"></div>
</body>
</html>
10、整合Swagger

Swagger号称世界上最流行的API框架,用于生成API文档,还可以直接在线运行测试

好像是只能找到有@RestController注解的接口,普通Controller注解的接口无法显示到Swagger中

添加Swagger依赖

<!-- SpringDoc OpenAPI 依赖 -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.6.15</version> <!-- 此版本兼容 Spring Boot 2.7.x -->
</dependency>

添加路径匹配策略配置(解决 Spring Boot 2.6+ 后的路径匹配问题)

# Swagger路径匹配策略
spring:
    mvc:
      pathmatch:
        matching-strategy: ANT_PATH_MATCHER

直接访问 http://localhost:8080/swagger-ui.html查看自动生成的文档

11、异步任务

在 Spring Boot 中,异步任务是处理耗时操作的重要方式,它可以避免主线程阻塞,提高应用的并发处理能力。@Async 注解是实现异步任务的核心工具。

适用于:发送邮件、文件上传、数据同步等耗时操作。

开启异步支持,在 Spring Boot 主类或配置类上添加 @EnableAsync 注解

@SpringBootApplication
@EnableAsync
@MapperScan("com.daitools.learn.mapper")
public class LearnApplication {
    public static void main(String[] args) {
        SpringApplication.run(LearnApplication.class, args);
    }

}

在需要异步执行的方法上面添加@Async注解

@Service
public class AsyncService {
    // 异步执行该方法
    @Async
    public void asyncTask() {
        try {
            // 模拟耗时操作(如:发送邮件)
            Thread.sleep(3000);
            System.out.println("异步任务执行完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在controller类中调用异步方法,在这里直是直接为异步方法开启一个子线程进行,而主线程会继续向下进行。

//调用异步方法
    @Autowired
    private AsyncService asyncService;
    @GetMapping("/testAsync")
    public String testAsync() {
        // 调用异步方法(主线程不等待)
        asyncService.asyncTask();
        // 立即返回结果,无需等待异步任务完成
        return "请求已接收,异步任务正在执行...";
    }
12、定时任务

在 Spring 框架中,定时任务是实现周期性执行特定逻辑的重要机制,而 @EnableScheduling@Scheduled 是实现这一功能的核心注解。

@EnableScheduling:开启定时任务支持,标记在配置类或主类上,用于开启 Spring 的定时任务调度功能。

@SpringBootApplication
@EnableScheduling // 开启定时任务支持
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@Scheduled:定义定时任务执行规则,标记在方法上,指定该方法为定时任务,并定义执行时机(如固定间隔、固定延迟、Cron 表达式等)。

  • 方法必须是 无返回值(void) 的。
  • 方法不能有参数(若需参数,需通过其他方式注入)。
  • 方法所在类必须被 Spring 管理(如标注 @Component@Service 等)。
@Component
public class ScheduledTasks {

    // 每 5 秒执行一次(单位:毫秒)
    @Scheduled(fixedRate = 5000)
    public void taskWithFixedRate() {
        System.out.println("固定间隔任务执行:" + new Date());
    }
}

常用注解

// 每 5 秒执行一次(单位:毫秒)
//在 Spring 中使用 @Scheduled(fixedRate = 5000) 注解的定时任务,项目启动后不会立刻执行,而是会等待第一个间隔时间(5 秒)后才执行第一次。
@Scheduled(fixedRate = 5000)
// 上一次任务完成后,间隔 3 秒再执行(单位:毫秒)
@Scheduled(fixedDelay = 3000)
// 应用启动后延迟 10 秒,之后每 5 秒执行一次
@Scheduled(initialDelay = 10000, fixedRate = 5000)
//Cron 表达式(cron)
// 每天凌晨 2 点执行
@Scheduled(cron = "0 0 2 * * ?")
// 每周一上午 10:30 执行
@Scheduled(cron = "0 30 10 ? * MON")
// 每小时的第 15 分钟执行(如 1:15、2:15...)
@Scheduled(cron = "0 15 * * * ?")

Cron 表达式特殊字符说明:
*:匹配所有值(如分钟字段为 * 表示每分钟)。
?:仅用于日和周字段,标识不指定值(避免日和周冲突)。
-:指定范围(如小时字段 9-17 表示 9 点到 17 点)。
,:指定多个值(如周字段 MON,WED,FRI 表示周一、三、五)。
/:指定增量(如秒字段 0/10 表示每 10 秒)。

定时任务的执行机制

  • 默认单线程:Spring 定时任务默认使用单线程调度,若一个任务执行时间过长,会阻塞后续所有任务。
  • 自定义线程池
@Configuration
public class SchedulerConfig {

    @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5); // 线程池大小
        scheduler.setThreadNamePrefix("Scheduled-"); // 线程名前缀
        scheduler.setAwaitTerminationSeconds(60); // 关闭时等待时间
        scheduler.setWaitForTasksToCompleteOnShutdown(true); // 关闭时等待任务完成
        return scheduler;
    }
}

定时任务和前端请求是用的两个独立的线程池,如果定时任务执行过程中,前端发起请求,则定时任务和请求的任务独立进行,互不影响。

13、邮件任务

邮件发送基于 SMTP 协议(简单邮件传输协议),接收则基于 POP3 或 IMAP 协议。SpringBoot 通过 spring-boot-starter-mail starter 封装了 JavaMail 的操作,简化了配置和发送流程。

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

application.propertiesapplication.yml 中配置 SMTP 服务器参数。

spring:
  mail:
    # SMTP服务器地址(QQ邮箱为smtp.qq.com,163为smtp.163.com)
    host: smtp.qq.com
    # 发送者邮箱账号
    username: your-qq@qq.com
    # 授权码(非登录密码,需在邮箱设置中开启SMTP并获取)
    password: your-auth-code
    # 端口(SSL加密端口通常为465,非加密为25)
    port: 465
    # 协议
    protocol: smtp
    # 额外配置(启用SSL加密)
    properties:
      mail:
        smtp:
          ssl:
            enable: true
          auth: true  # 开启认证
        debug: false  # 是否开启调试模式(打印发送日志)

编写测试函数

@Autowired
    private JavaMailSender javaMailSender;

    /**
     * 发送简单文本邮件
     */
    public void sendSimpleEmail() {
        // 创建简单邮件消息对象
        SimpleMailMessage message = new SimpleMailMessage();
        // 设置发送者(需与配置文件中username一致)
        message.setFrom("your-qq@qq.com");
        // 收件人(可多个,用逗号分隔)
        message.setTo("recipient1@example.com", "recipient2@example.com");
        // 抄送(可选)
        message.setCc("cc@example.com");
        // 密送(可选)
        message.setBcc("bcc@example.com");
        // 主题
        message.setSubject("【简单文本邮件】测试主题");
        // 内容
        message.setText("这是一封简单的文本邮件,来自SpringBoot。");
        // 发送邮件
        javaMailSender.send(message);
    }

Html邮件

@Component
public class EmailService {

    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 发送HTML邮件
     */
    public void sendHtmlEmail() throws MessagingException {
        // 创建MimeMessage对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        // 创建MimeMessageHelper(第二个参数为true表示支持多部分内容)
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

        // 设置基本信息
        helper.setFrom("your-qq@qq.com"); // 发送者
        helper.setTo("recipient@example.com"); // 收件人
        helper.setSubject("【HTML邮件】测试主题"); // 主题

        // HTML内容(支持CSS样式)
        String htmlContent = "<h3>这是一封HTML邮件</h3>" +
                             "<p style='color: red;'>红色文本内容</p>" +
                             "<a href='https://www.baidu.com'>百度链接</a>";
        helper.setText(htmlContent, true); // 第二个参数为true表示启用HTML

        // 发送
        javaMailSender.send(mimeMessage);
    }
}

带附件的邮件

@Component
public class EmailService {

    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 发送带附件的邮件
     */
    public void sendEmailWithAttachment() throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        // 第二个参数true表示支持多部分(附件属于多部分内容)
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

        // 基本信息
        helper.setFrom("your-qq@qq.com");
        helper.setTo("recipient@example.com");
        helper.setSubject("【带附件邮件】测试主题");
        helper.setText("这是一封带附件的邮件,请查收。", false); // 纯文本内容

        // 添加附件(本地文件)
        File attachmentFile = new File("D:/test.pdf"); // 附件路径
        FileSystemResource resource = new FileSystemResource(attachmentFile);
        String attachmentName = "测试附件.pdf"; // 附件显示名称
        helper.addAttachment(attachmentName, resource);

        // 发送
        javaMailSender.send(mimeMessage);
    }
}

带图片的邮件

@Component
public class EmailService {

    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 发送带内嵌图片的HTML邮件
     */
    public void sendHtmlWithImageEmail() throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

        helper.setFrom("your-qq@qq.com");
        helper.setTo("recipient@example.com");
        helper.setSubject("【带图片的HTML邮件】测试主题");

        // HTML内容,通过cid:imageId引用内嵌图片
        String htmlContent = "<h3>这是一封带内嵌图片的邮件</h3>" +
                             "<p>图片展示:</p>" +
                             "<img src='cid:imageId' width='300' height='200'/>";
        helper.setText(htmlContent, true);

        // 内嵌图片(本地图片)
        File imageFile = new File("D:/test.jpg");
        FileSystemResource imageResource = new FileSystemResource(imageFile);
        // 第一个参数为资源ID(需与HTML中的cid:imageId一致),第二个参数为资源
        helper.addInline("imageId", imageResource);

        // 发送
        javaMailSender.send(mimeMessage);
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到