SpringBoot的事务/调度/缓存/邮件发送和一些Spring知识点总结

目录

1、SpringBoot的事务管理

2、SpringBoot的异步任务

3、SpringBoot定时任务调度

4、SpringBoot整合Mail发送邮件

5、Spring框架中的Bean的作用域

6、Spring框架中的Bean的线程安全

7、 Spring框架中的Bean生命周期

8、Spring框架如何解决循环依赖?

9、Spring框架中有哪些注解?

10、Spring框架中用到的设计模式


1、SpringBoot的事务管理

        在mybatis中,我们还要创建一个动态代理来处理业务中的事务,但是SpringBoot提供了注解的方式快速的实现了事务的相关逻辑。

        如果我们现在有一个方法是批量创建多个Consume对象,创建了一个bathAdd()方法,方法中如果出现了一个异常代码片段,没有事务的情况下前面的对象会被新增在数据库中,后面的则不会执行新增。这样的逻辑是不对的,所以我们在这个方法前面加上@Transaction的注解。

Service层代码: 

@Service
public class CustomerServiceImp extends ServiceImpl<ConsumeMapper, Consumer> implements ICustomerService{@Resourceprivate ConsumeMapper dao;@Transactional@Overridepublic void batchAdd() {dao.insert(new Consumer(7,"牛",new Date(),"男"));int a = 10/0;dao.insert(new Consumer(8,"牛1",new Date(),"男"));dao.insert(new Consumer(9,"牛2",new Date(),"男"));}}

         @Transactional:表示这个方法中的所有数据库操作将在一个事务中执行。如果在方法执行过程中抛出异常,事务将会回滚。

        @Resource 

        private ConsumeMapper dao;

         表示注入了一个名为dao的ConsumeMapper对象,用于执行数据库操作。

controller层代码:

@RestController
public class ConsumerControllerImp {@Autowiredprivate ICustomerService service;@RequestMapping("/add")public String batchAdd() {service.batchAdd();return "成功";}
}

         @RestController:标记这个类是一个Spring MVC控制器,并且返回的内容会直接作为HTTP响应的Body(通常是JSON格式)。相比于@Controller,@RestController省去了额外的@ResponseBody注解。

        通过controller层调用方法batchAdd()是调用service层的batchAdd()。

测试类主入口:

@SpringBootApplication
@EnableTransactionManagement
public class Springboot01CenterTxApplication {public static void main(String[] args) {SpringApplication.run(Springboot01CenterTxApplication.class, args);}}

         @EnableTransactionManagement:启用Spring的注解驱动的事务管理功能。它使得Spring能够识别和处理类或方法上的@Transactional注解,从而管理事务边界,对有@Transactional的方法或类进行事务管理。

2、SpringBoot的异步任务

        在项目开发中,绝大多数情况下都是通过同步方式处理业务逻辑的,但是比如批量处理数据,批量发送邮件,批量发送短信等操作容易造成阻塞的情况,之前大部分都是使用多线程来完成此类任务,而在 Spring 3+之后,就已经内置了@Async注解来完美解决这个问题,从而提高效率。

        异步执行核心概念是任务在不同线程中执行,而不是在同一个线程中按照顺序执行。具体来说,异步执行允许任务几乎同时进行,但它们是在不同线程中并行处理的,,而不是像同步执行那样在同一个线程中按顺序完成。

        从controller层调用方法batchAdd()到service层:

service层代码:

@Service
public class CustomerServiceImp implements ICustomerService{@Override@Asyncpublic void batchAdd() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("======>批量新增");}
}

         @Async:这是Spring提供的异步处理注解。标记在方法上时,该方法将在单独的线程中异步执行,不会阻塞调用者线程。使用这个注解的前提是需要在配置类或启动类中启用异步功能,例如通过@EnableAsync来实现。

        Thread.sleep(3000);: 这行代码让当前线程休眠3秒钟,模拟批量添加操作的延迟。

测试类主入口:

@SpringBootApplication
@EnableAsync // 开启异步处理
public class Springboot04CenterAysncApplication {public static void main(String[] args) {SpringApplication.run(Springboot04CenterAysncApplication.class, args);}}

        @EnableAsync:当你在启动类中使用了@EnableAsync时,Spring会扫描整个应用程序,识别并处理所有标记了@Async注解的方法。标记了@Async的方法会在一个单独的线程池异步执行,而不是在主线程中执行。这使得主线程不会被这些方法阻塞,从而可以继续处理其他任务。

3、SpringBoot定时任务调度

        SpringTask:在项目开发中,经常需要执行一些定时任务,比如每月1号凌晨需要汇总上个月的数据分析报表;每天凌晨分析前一天的日志信息等定时操作。Spring 为我们提供了异步执行定时任务调度的方式。

        就比如我想要每隔4秒给我发送一个提醒:

之间创建一个MyJob类:

@Component
public class MyJob {//秒 分 时 日 月 星期 年// 从3秒开始每隔4秒执行一次@Scheduled(cron = "3/4 00 22 15 8 ?")public void show(){System.out.println("陕西发布暴雪蓝色预警");}
}

         @Scheduled标识的方法会进行定时处理,需要通过 cron 属性来指定 cron 表达式:秒 分 时 日 月 星期 年。

        在上面的代码中,‘3/4’代表从第三秒开始,每个寺庙执行一次。'00'代表在 0 分钟时执行。其他的就是对应的时、日、月星期执行,一般不加年,加年会报错。

        总体可理解为:在8月15号的22点00分第三秒的时候开始执行,每隔4秒执行一次。

测试类主入口:

@SpringBootApplication
@EnableScheduling // 开启任务调度
public class Springboot03CenterJobApplication {public static void main(String[] args) {SpringApplication.run(Springboot03CenterJobApplication.class, args);}}

        其中@EnableScheduling用于启用 Spring 的定时任务执行功能。当你在配置类上使用 @EnableScheduling 注解时,Spring 会扫描并识别使用了 @Scheduled 注解的方法,并按照指定的时间间隔或时间点执行这些方法。

4、SpringBoot整合Mail发送邮件

首先添加坐标:

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

其次是配置yml信息,用来配置你的发送邮箱。

spring:mail:password: 邮箱授权码username: 邮箱账号,不用加后缀host: smtp.qq.com (邮箱类型)properties:smtp:ssl:enable: true

         最后是在测试类中去完成方法并测试:

        首先是简单的发送邮件,只有文字发送:

    @Autowired(required = false)private JavaMailSenderImpl javaMailSender;//发送简单邮件@Testvoid show1() {//1.创建邮件对象SimpleMailMessage simpleMailMessage = new SimpleMailMessage();//2.设置信息simpleMailMessage.setSubject("疫情全面放开");simpleMailMessage.setText("2022年好难,做了11个月的核酸,结果在第12个月阳了~~~");simpleMailMessage.setFrom("?@qq.com");simpleMailMessage.setTo("?@qq.com");//3.发送邮件javaMailSender.send(simpleMailMessage);System.out.println("发送成功~~~");}

          这里面首先用使用 SimpleMailMessage 类创建一个简单的邮件对象。

  •         setSubject("疫情全面放开"):设置邮件的主题为 "疫情全面放开"。
  •         setText("2022年好难,做了11个月的核酸,结果在第12个月阳了~~~"):设置邮件的正文内容。
  •         setFrom("?@qq.com"):设置发件人地址。
  •         setTo("?@qq.com"):设置收件人地址。

           其次是发送复杂邮件,就比如带张照片等等操作均是复杂发送:

@Testvoid show2()throws Exception {//1.创建邮件对象MimeMessage mimeMessage = javaMailSender.createMimeMessage();//2.创建MimeMessageHelperMimeMessageHelper mimeMessageHelper =  new MimeMessageHelper(mimeMessage,true);//3.设置信息mimeMessageHelper.setSubject("程序员的误解");mimeMessageHelper.setText("程序员是个<span style='color:red'>高薪,高危</span>的职业",true);mimeMessageHelper.addAttachment("1.jpg",new File("?.jpg"));mimeMessageHelper.setFrom("?4@qq.com");mimeMessageHelper.setTo("?@qq.com");//4.发送邮件javaMailSender.send(mimeMessage);}

        其他的跟上面的代码一致,新增了一个addAttachment()方法,第一个参数为附件在邮件中显示的文件名,收件人下载附件时,看到的文件名将是这个参数指定的名称。第二个参数为这是一个 File 对象,表示需要附加到邮件中的实际文件。它可以是本地存储在文件系统中的任何文件。

5、Spring框架中的Bean的作用域

        singleton:Spring只会为该bean对象只会创建唯一实例Spring中的bean默认都是单例:
        prototype:每次获取bean,Spring会创建一个新的bean实例;
        request:每一次HTTP请求,Spring会创建一个新的bean实例;
        session:不同的HTTP会话,Spring会创建不同的bean实例;

        通过XML方式设置bean的作用域:

<bean id="demoDaoBean" class="com.apesource.dao.DemoDAOImpl" scope="singleton"/> 

         通过注解方式设置bean的作用域:

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoDAOImpl implements IDemoDAO{ }
6、Spring框架中的Bean的线程安全

        对于prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。

        对于singleton作用域的Bean,所有的线程都共享一个单例状态的Bean,存在资源竞争,因此是存在线程安全问题的。

        解决办法:对于singleton作用域的单例bean ,它的线程安全问题,常见有两种解决办法:

  • 在bean中尽量避免定义可变的成员变量(用于保存数据的成员变量);
  • 在类中定义一个ThreadLocal 成员变量,将需要可变的成员变量保存 ThreadLocal 中;
7、 Spring框架中的Bean生命周期

        Spring Bean的生命周期总体分四个阶段实例化=>属性注入=>初始化=>销毁。

        Step1 实例化Bean:根据配置文件中Bean 的定义,利用| Java Reflection 反射技术创建Bean的实例。

        Step2 注入对象依赖的属性值(或对象)。

        Step3 处理各种Aware接口:Spring会检测该Bean 是否实现了xxxAware 接口,通过Aware类型的接口,可以让Spring框架为当前 Bean 注入相应的内容

  • 如果Bean实现BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,注入Bean的名字;
  • 如果Bean实现BeanClassLoaderAware 接口,调用setBeanClassLoader()方法,注入ClassLoader对象的实例;
  • 如果Bean实现BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,注入的是Spring工厂;
  • 如果Bean实现ApplicationContextAware接口,会调用setApplicationContext()方法,注入Spring上下文;

        Step4 执行BeanPostProcessor前置处理:如果想对Bean进行一-些自定义的前置处理, 那么可以让Bean实现了BeanPostProcessor 接口,将会在该阶段调用postProcessBeforeInitialization(0bject obj,String s)方法。

        Step5 执行InitializingBean初始化方法:如果 Bean 实现了InitializingBean接口,执行afeterPropertiesSet()方法。

        Step6 执行init-method自定义初始化方法:如果 Bean在Spring配置文件中配置了init-method属性,则会自动调用其配置的初始化方法。

        Step7 执行BeanPostProcessor后置处理:如果这个Bean 实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法,由于这个方法是在Bean初始化结束后调用;

        以上几个步骤完成后, Bean已经被正确创建,可以正常使用这个Bean了。

        Step8 执行DisposableBean销毁Bean:当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean 这个接口,会调用其实现的destroy() 方法执行销毁;

        Step9 执行destroy-method自定义销毁方法:如果这个Bean的Spring配置中配置了destroy
-method属性,会自动调用其配置的自定义销毁方法。

8、Spring框架如何解决循环依赖?

        循环依赖问题是指:类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。例如A类依赖了B类,B类依赖了C类,而最后C类又依赖了A类,这样就形成了循环依赖问题;

9、Spring框架中有哪些注解?

        用于声明Bean的注解:

  • @Component:定义通用Bean的注解,可标注任意类为Bean。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注。
  • @Repository:定义数据访问层Bean的注解。
  • @Service:定义业务层Bean的注解。
  • @Controller:定义控制器Bean的注解。

        用于注入的注解: 

  • @Autowired:按类型自动注入
  • @Qualifier:按名称自动注入

         声明配置、扫描、启用特性的注解:

  • @Configuration:声明配置类
  • @ComponentScan:组件扫描
  • @EnableScheduling:启用任务调度
  • @EnableAspectJAutoProxy:启用自动代理工厂
10、Spring框架中用到的设计模式
  • 工厂模式:Spring 使用工厂模式,通过BeanFactory 或Applicat ionContext来创建对象;
  • 单例模式:Bean 默认作用域为单例,按照单例设计模式进行设计实现;
  • 策略模式:Resource 的实现类,针对不同的资源文件,实现了不同方式的资源获取策略;
  • 代理模式:Spring的AOP的实现依靠动态代理(JDK的反射和CGLIB);
  • 模板方法:Spring提供了JdbcTemplate,RedisTemplate 等模板对象,将相同的操作步骤进行了封装;
  • 适配器模式:Spring AOP的增强或通知( Advice )使用到了适配器模式, Spring MVC中也用到了适配器模式适配Controller;

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

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

相关文章

HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现(十一)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

Golang | Leetcode Golang题解之第337题打家劫舍III

题目&#xff1a; 题解&#xff1a; func rob(root *TreeNode) int {val : dfs(root)return max(val[0], val[1]) }func dfs(node *TreeNode) []int {if node nil {return []int{0, 0}}l, r : dfs(node.Left), dfs(node.Right)selected : node.Val l[1] r[1]notSelected : …

mysql windows安装与远程连接配置

安装包在主页资源中 一、安装(此安装教程为“mysql-installer-community-5.7.41.0.msi”安装教程&#xff0c;安装到win10环境) 保持默认选项&#xff0c;点击”Next“。 点开第一行加号展开一路展开找到“MySQL Server 5,7,41 - X64”点击选中点击一下中间只想右侧的箭头看到…

Element-02.组件-Table表格

一.常见组件-表格 二.具体操作 <template><el-table:data"tableData"borderstyle"width: 100%"><el-table-columnprop"date"label"日期"width"180"></el-table-column><el-table-columnprop&q…

Chat App 项目之解析(二)

Chat App 项目介绍与解析&#xff08;一&#xff09;-CSDN博客文章浏览阅读76次。Chat App 是一个实时聊天应用程序&#xff0c;旨在为用户提供一个简单、直观的聊天平台。该应用程序不仅支持普通用户的注册和登录&#xff0c;还提供了管理员登录功能&#xff0c;以便管理员可以…

SpringBoot项目部署时application.yml文件的加载优先级和启动脚本

文章目录 application.yml文件的加载优先级(由高到低)第一级命令行参数第二级Jar包同级目录 /config第三级Jar包同级目录第四级classpath 下的/config第五级classpath 根路径/总结&#xff1a; logback.xml 文件加载顺序当application.yml 和 bootstrap.yml 同时存在时java jar…

【iOS】Block底层分析

目录 前言Block底层结构Block捕获变量原理捕获局部变量&#xff08;auto、static&#xff09;全局变量捕获实例self Block类型Block的copyBlock作为返回值将Block赋值给__strong指针Block作为Cocoa API中方法名含有usingBlock的方法参数Block作为GCD API的方法参数Block属性的写…

使用QGraphicsView思想做一个简单图片查看器

使用QGraphicsView思想做一个简单图片查看器 如果要做一个图片查看器&#xff0c;支持放大、滚动操作&#xff0c;比较直接的方法是&#xff0c;使用QWidget来显示完整图片&#xff0c;将QWidget放入QScrollArea。缩放时调整QWidget的尺寸&#xff0c;QScrollArea会自动调整滚…

MBR20200FCT-ASEMI智能AI专用MBR20200FCT

编辑&#xff1a;ll MBR20200FCT-ASEMI智能AI专用MBR20200FCT 型号&#xff1a;MBR20200FCT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 批号&#xff1a;最新 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;20A 最大循环峰值反向电压&#xff08;VRRM&a…

别再问了!微信小程序的那些事儿,一文搞定

微信小程序是一种无需下载安装即可使用的应用&#xff0c;它嵌入在微信生态中&#xff0c;用户通过微信扫一扫或搜索即可快速访问。 无论是购物、订餐、预约服务&#xff0c;还是玩个小游戏、看篇文章&#xff0c;都不需要下载额外的APP&#xff0c;直接就能在微信里搞定。不会…

联想电脑如何查看ip地址?详细介绍几种方法

随着互联网的普及和技术的飞速发展&#xff0c;IP地址已成为我们日常网络活动中不可或缺的一部分。无论是访问网站、远程办公还是进行网络游戏&#xff0c;IP地址都扮演着重要的角色。对于联想电脑用户来说&#xff0c;了解如何查看自己的IP地址是一项基本技能。虎观代理小二将…

JSON Web Token (JWT): 理解与应用

JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;它定义了一种紧凑且自包含的方式&#xff0c;用于在各方之间以JSON对象的形式安全地传输信息。JWT通常用于身份验证和授权目的&#xff0c;因为它可以使用JSON对象在各方…

【向量数据库】Ubuntu编译安装FAISS

参考官方的安装指导&#xff1a;https://github.com/facebookresearch/faiss/blob/main/INSTALL.md&#xff0c;不需要安装的可以跳过 ~$ wget https://github.com/facebookresearch/faiss/archive/refs/tags/v1.8.0.tar.gz ~$ tar -zxvf v1.8.0.tar.gz ~$ cd faiss-1.8.0 ~$ …

易基因:RNA修饰N4-乙酰胞苷(ac4C)的调控机制、检测方法及其在癌症中的作用最新研究进展|新方向

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 N4-乙酰胞苷&#xff08;ac4C&#xff09;是一种高度保守的化学修饰&#xff0c;广泛存在于真核和原核生物RNA中&#xff0c;如tRNA、rRNA和mRNA。这种修饰与多种人类疾病显著相关&#…

vuex的原理和使用方法

简介 Vuex 是 Vue.js 应用的状态管理模式&#xff0c;它为应用内的所有组件提供集中式的状态&#xff08;数据&#xff09;管理。可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。 Vuex的构成 state&#xff1a;state 是 Vuex 的数据中心&#xff0c;也就是说state是用来…

职业院校云计算实训室建设方案全景剖析

在信息化社会的今天&#xff0c;云计算作为一项关键技术&#xff0c;正在迅速改变着教育和培训的方式。本文旨在探讨如何通过"职业院校云计算实训室建设方案"&#xff0c;为学生提供一个现代化、高效的学习和研究环境&#xff0c;以适应云计算技术的发展和市场需求。…

软件测试---接口测试

一、接口及接口测试概念 &#xff08;1&#xff09;接口的类型 &#xff08;2&#xff09;接口测试的概念 &#xff08;3&#xff09;接口测试的原理 &#xff08;4&#xff09;接口测试的特点 &#xff08;5&#xff09;接口测试的实现方式 二、HTTP协议 &#xff08;1&#…

Qt 实现抽屉效果

1、实现效果和UI设计界面 2、工程目录 3、mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QToolButton> #include <QPushButton> #include <vector> using namespace std;QT_BEGIN_NAMESPACE namespace…

生成式:PolyGen: An Autoregressive Generative Model of 3D Meshes【附件】

论文:PolyGen: An Autoregressive Generative Model of 3D Meshes OBJ坐标变换: # Transpose so that z-axis is vertical.vertices = vertices[:, [2, 0, 1]]变换前: 对应数据:

C++模板(初阶)

1.引入 在之前的笔记中有提到&#xff1a;函数重载&#xff08;特别是交换函数&#xff08;Swap&#xff09;的实现&#xff09; void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {do…