SpringBoot学习笔记

目录

入门

第一个SpringBoot程序

修改 tomcat 端口号

彩蛋

配置文件

YAML的语法

基本语法

不同类型值的写法

配置文件注入

通过 yaml 配置文件来对对象的属性赋值

通过 properties 向对象属性赋值(了解)

yaml设置随机数

yaml获取前面配置的值

JSR303数据校验

配置文件的加载位置

多环境配置

使用properties配置多套环境

yaml支持的多文档块方式

静态资源

Thymeleaf模板引擎

Thymeleaf语法规则

扩展SpringMVC

员工管理系统

首页实现

登录功能实现

登录拦截器

CRUD之员工列表

thymeleaf公共页面抽取

员工列表展示

CRUD之添加员工

CRUD之修改员工

CRUD之删除员工

注销

配置404页面

SpringBoot操作数据库

整合德鲁伊数据源

整合MyBatis

SpringSecurity

异步任务、邮件发送、定时任务

异步任务

邮件发送

​ 定时任务

入门

第一个SpringBoot程序

我们要创建一个 SpringBoot 项目,步骤如下:

首先新建一个 project,选择 Spring Initializr,其中的一些配置根据实际情况配置即可

点击 next

点击 finish 即可,创建完成后,删除一些没用的文件

 

删除完成后,项目结构就和之前的 web 项目一样了,注意:FirstExampleApplication 不能删除

 

点击 FirstExampleApplication ,就可以启动

 然后我们来测试一下

编写一个 controller,向页面输入文字

@Controller
@RequestMapping("/test")
public class HelloController {
    @RequestMapping("/hello")
    @ResponseBody
    public String testHello(){
        return "hello,SpringBoot";
    }
}

 注意:我们要将诸如 controller 包写在与 FirstExampleApplication 同一级

点击启动,由于我的端口号是 8080,因此输入 localhost:8080/test/hello

 

我们可以发现整个过程中我们没有向之前一样配置一些像 web.xml,前端控制器,tomcat 等等东西,简化了我们开发

修改 tomcat 端口号

在下面文件中添加

 

 

重新启动,即可生效

 

彩蛋

默认启动后,上方会有这样一个图案,我们想对其进行修改

先去找到修改后的样式,可以去关于佛祖的ascii艺术字,Spring Boot 佛祖 Banner-bootschool.net 中选择

在 resources 目录下创建一个 banner.txt,将要修改的复制进去,重启

我们可以发现修改成功了😊😊😊

配置文件

SpringBoot 使用了一个全局的配置文件,它的名字是固定的

application.properties

application.yaml

配置文件的作用:可以用来修改 SpringBoot 自动配置的默认值

YAML的语法

基本语法

语法结构:key:(空格)value,表示一对键值对,必须保证冒号后面有个空格;以空格来控制层级关系,如果一列数据是左对齐的,那么它们就是同一层级的

 

不同类型值的写法

基本类型

直接 key: value

字符串默认是不同加引号的,不同的引号有不同的作用

"" (双引号):不会转义字符串里的特殊字符,这里的 \n 就表示换行

 

'' (单引号):会将字符串中的特殊字符转为普通字符串

对象

有两种方式

student:
  name: king
  age: 25

 ②:行内写法

student1: {name: king, age: 25}

数组

两种方式

pets:
  - cat
  - dog
  - pig

②:行内写法

pets1: [cat, dog, pig]

配置文件注入

通过 yaml 配置文件来对对象的属性赋值

配置文件

person:
  name: spring
  age: 21
  happy: false
  birth: 2022/2/7
  map: {k1: v1, k2: v2}
  list:
    - code
    - music
    - girl
  dog:
    name: 旺财
    age: 3

JavaBean

 

导入该依赖配置文件处理器,编写配置就会有提示

通过 properties 向对象属性赋值(了解)

配置文件

 

再使用 @PropertySource 来加载指定配置文件

配置文件yml还是properties他们都能获取到值;

如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;

如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;

yaml设置随机数

yaml 中可以设置配置一些随机数,如下

 

yaml获取前面配置的值

JSR303数据校验

首先开启 validation 启动器

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

 再在类上加上 @Validated 注解

举例:让 person 的 name 属性满足 email 格式

空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.

Boolean检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false

长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) 验证字符串的长度在min和max范围之内.

日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前,验证成立的话被注释的元素一定是一个过去的日期
@Future 验证 Date 和 Calendar 对象是否在当前时间之后 ,验证成立的话被注释的元素一定是一个将来的日期
@Pattern 验证 String 对象是否符合正则表达式的规则,被注释的元素符合制定的正则表达式,regexp:正则表达式 flags: 指定 Pattern.Flag 的数组,表示正则表达式的相关选项。

数值检查
建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为""时无法转换为int,但可以转换为Stirng为"",Integer为null
@Min 验证 Number 和 String 对象是否大等于指定的值
@Max 验证 Number 和 String 对象是否小等于指定的值
@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits 验证 Number 和 String 的构成是否合法
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
@Range(min=, max=) 被指定的元素必须在合适的范围内
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber信用卡验证
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)

配置文件的加载位置

SpringBoot 会将下面四个位置的 application.properties 或者 application.yaml 文件作为 SpringBoot 的默认配置文件

优先级由高到低,高优先级的配置会覆盖低优先级的配置,四个地方的配置文件互补

–file:./config/

–file:./

–classpath:/config/

–classpath:/

多环境配置

使用properties配置多套环境

现在有三个环境,SpringBoot 默认会使用 application.properties

 

如果我们想修改环境,只需在 application.properties 中添加如下

 

yaml支持的多文档块方式

同样是三个环境,不同的文档使用 --- 进行分割

server:
  port: 8081
spring:
  profiles:
    active: test #表示激活 test 环境,如果不设置就为默认环境 8081
---
server:
  port: 8082
spring:
  config:
    activate:
      on-profile: dev
---
server:
  port: 8083
spring:
  config:
    activate:
      on-profile: test

静态资源

在 SpringBoot 中我们可以使用以下方式处理静态资源

①:webjars:以jar包的方式引入静态资源;(少用,不过多说明)

②:在下面几个文件夹中找,并且优先级为 resources > static > public

定制首页

将 index.html 页面放在 public、resources、static 三个任意一个包下,都可以被识别为首页,如果要放在 templates 包下则需要使用 controller 跳转,使用 controller 就需要引入模板引擎

Thymeleaf模板引擎

导入下面依赖

<!--Thymeleaf-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>

 或者在创建新项目时,引入

可以发现我们只需将 html 页面放在 templates 包下,thymeleaf 就会自动去渲染,就可以像之前一样使用 controller 来进行跳转

Thymeleaf语法规则

使用前需先声明名称空间

xmlns:th="http://www.thymeleaf.org"

基本语法

${...} 变量表达式

*{...} 选择变量表达式

#{...} 消息表达式

@{...} 链接url表达式

~{...} 代码块表达式

th属性

th:text :设置当前元素的文本内容,相同功能的还有th:utext,两者的区别在于前者不会转义html标签,后者会。

th:value:设置当前元素的value值,类似修改指定属性的还有th:src,th:href。

th:each:遍历循环元素,和th:text或th:value一起使用。

th:if:条件判断,类似的还有th:unless,th:switch,th:case。

th:insert:代码块引入

th:fragment:定义代码块,方便被th:insert引用。

th:object:声明变量,一般和*{}一起配合使用

th:attr:修改任意属性,类似的还有th:attrappend,th:attrprepend。

其他具体使用到再详细去了解

扩展SpringMVC

SpringBoot在自动配置很多组件的时候,会先看容器中是否有用户自己配置的,如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,例如视图解析器,那么就将用户配置的和自己默认的组合起来。

如果我们想要扩展 SpringMVC,我们就需要去编写一个 @Configuration 注解类,并且实现接口 WebMvcConfigurer,而且不能标注 @EnableWebMvc 注解,如果标注了该注解,那么我们的配置类将会全面接管 SpringBoot,就会使 SpringBoot 的默认配置失效

@Configuration
public class MyMVCConfig implements WebMvcConfigurer {
    //视图跳转
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/hello").setViewName("hello");
    }
}

员工管理系统

首页实现

所有页面的静态资源都需要用 thymeleaf 接管:@{}

@Controller
public class IndexController implements WebMvcConfigurer{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }
}

登录功能实现

具体的代码写法和 SpringMVC 一模一样,这里没有用数据库,只是简单的测试

@Controller
public class LoginController {
    @RequestMapping("/user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model){
        //具体的业务
        if (username.equals("root") && password.equals("123456")){
            return "redirect:/main.html";
        }else {
            //告诉用户登录失败
            model.addAttribute("error", "用户名或密码错误");
            return "index";
        }
    }
}

登录拦截器

也是 SpringMVC 中一样配置

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登录成功后应该存在用户session
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser != null){
            return true;
        }else {
            request.setAttribute("error", "请先登录");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        }
    }
}

 在实现了 WebMvcConfigurer 接口的 controller 中进行扩展

CRUD之员工列表

thymeleaf公共页面抽取

有三种方式进行抽取:

th:insert:将公共片段整个插入到声明引入的元素中

th:replace:将声明引入的元素替换为公共片段

th:include:将被引入的片段的内容包含进这个标签中

将 dashboard.html 中的侧边栏抽取出来进行复用

在其他页面引用

 

我们一般把公用的抽取出来放在一个 html 里,其他页面要使用时直接从该页面引用即可

在引入时我们还可以传递参数给引入的部分

获取传入的参数

员工列表展示

后台查询所有员工

@Controller
public class EmployeeController {
    @Autowired
    EmployeeMapper employeeMapper;
    //查询全部员工
    @RequestMapping("/employees")
    public String employees(Model model){
        Collection<Employee> employees = employeeMapper.getAll();
        model.addAttribute("emps", employees);
        return "list";
    }
}

前台直接获取遍历展示即可

这里 birth 显示出现了问题

可以进行如下修改

 

CRUD之添加员工

form 表单

<form action="">
                <div class="form-group">
                    <label>LastName</label>
                    <input type="text" name="lastName" class="form-control" placeholder="海绵宝宝">
                </div>
                <div class="form-group">
                    <label>Email</label>
                    <input type="email" name="email" class="form-control" placeholder="1176244270@qq.com">
                </div>
                <div class="form-group">
                    <label>Gender</label><br>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" value="1">
                        <label class="form-check-label">男</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" value="0">
                        <label class="form-check-label">女</label>
                    </div>
                </div>
                <div class="form-group">
                    <label>department</label>
                    <select class="form-control" name="department.id">
                        <option th:each="department:${departments}" th:text="${department.getDepartmentName()}" th:value="${department.getId()}"></option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Birth</label>
                    <input type="text" name="birth" class="form-control" placeholder="嘤嘤嘤">
                </div>
                <button type="submit" class="btn btn-primary">添加</button>
            </form>

 后台代码

    @RequestMapping("/toAdd")
    public String toAdd(Model model){
        //查出所有部门的信息
        Collection<Department> departments = departmentMapper.getDepartments();
        model.addAttribute("departments", departments);
        return "add";
    }
    @RequestMapping("/addEmployee")
    public String addEmployee(Employee employee){
        employeeMapper.addEmployee(employee);
        return "redirect:/employees";
    }

CRUD之修改员工

修改页面表单

<form th:action="@{/updateEmployee}" method="post">
                <input type="hidden" name="id" th:value="${employee.getId()}">
                <div class="form-group">
                    <label>LastName</label>
                    <input th:value="${employee.getLastName()}" type="text" name="lastName" class="form-control" placeholder="海绵宝宝">
                </div>
                <div class="form-group">
                    <label>Email</label>
                    <input th:value="${employee.getEmail()}" type="email" name="email" class="form-control" placeholder="1176244270@qq.com">
                </div>
                <div class="form-group">
                    <label>Gender</label><br>
                    <div class="form-check form-check-inline">
                        <input th:checked="${employee.getGender()==1}" class="form-check-input" type="radio" name="gender" value="1">
                        <label class="form-check-label">男</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input th:checked="${employee.getGender()==0}" class="form-check-input" type="radio" name="gender" value="0">
                        <label class="form-check-label">女</label>
                    </div>
                </div>
                <div class="form-group">
                    <label>department</label>
                    <select class="form-control" name="department.id">
                        <option th:each="department:${departments}" th:text="${department.getDepartmentName()}" th:value="${department.getId()}" th:selected="${department.getId()==employee.getDepartment().getId()}"></option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Birth</label>
                    <input th:value="${#dates.format(employee.getBirth(), 'yyyy-MM-dd HH:mm:ss')}" type="text" name="birth" class="form-control" placeholder="嘤嘤嘤">
                </div>
                <button type="submit" class="btn btn-primary">修改</button>
            </form>

后台代码

    @RequestMapping("/toUpdate/{id}")
    public String toUpdate(@PathVariable("id")Integer id, Model model){
        Employee employee = employeeMapper.getEmployeeById(id);
        model.addAttribute("employee", employee);
        //查出所有部门的信息
        Collection<Department> departments = departmentMapper.getDepartments();
        model.addAttribute("departments", departments);
        return "update";
    }
    @RequestMapping("/updateEmployee")
    public String updateEmployee(Employee employee){
        employeeMapper.update(employee);
        return "redirect:/employees";
    }

CRUD之删除员工

后台代码

    @RequestMapping("/delEmployee/{id}")
    public String delEmployee(@PathVariable("id")Integer id){
        employeeMapper.delete(id);
        return "redirect:/employees";
    }

注销

清除 session,返回至登陆页面即可

    @RequestMapping("/loginOut")
    public String loginOut(HttpSession session){
        session.invalidate();
        return "redirect:/employees";
    }

配置404页面

在 templates 包下创建一个 error 包,将诸如 404、500等错误页面放在里面即可自动识别

SpringBoot操作数据库

新建项目

 我们可以使用 SpringBoot 默认的数据源,也可以配置德鲁伊数据源

整合德鲁伊数据源

导入依赖  

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>

在 application.yaml 文件中设置

可以自己设置一些 druid 数据源的配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    #SpringBoot默认是不注入这些的,需要自己绑定
    #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.Properity
    #则导入log4j 依赖就行
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionoProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

自定义德鲁伊数据源配置

@Configuration
public class DruidConfig {

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }
    //后台监控:web.xml,ServletRegistrationBean
    //因为 SpringBoot 内置了 Servlet 容器,没有 web.xml,替代方法:
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        //后台需要有人登录,账号密码配置
        HashMap<String, String> initParameters = new HashMap<>();
        //配置账号密码,key 是固定的
        initParameters.put("loginUsername", "admin");
        initParameters.put("loginPassword", "123456");
        //允许谁能访问
        initParameters.put("allow", "");
        bean.setInitParameters(initParameters);//设置初始化参数
        return bean;
    }
    //过滤器filter,跟上面一样
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new WebStatFilter());
        //可以过滤哪些请求
        Map<String, String> initParameters = new HashMap<>();
        //这些东西不进行统计
        initParameters.put("exclusions", "*.js,*.css,/druid/*");
        bean.setInitParameters(initParameters);
        return bean;
    }
}

druid后台监控页面

整合MyBatis

整合包

用法相差不大,注意细节方面即可,事务会自动提交不用配置

①:创建实体类以及对应 mapper

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String name;
    private String pwd;
}
//这个注解表示这是一个 mybatis 的 mapper 类
@Mapper
@Repository
public interface UserMapper {
    List<User> queryUsers();
    User queryUserById(@Param("uid") int id);
    int addUser(User user);
    int updateUser(User user);
    int delUser(int id);
}

②:有 mapper 后,我们就应该配置对应的 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.zhouyue.mapper.UserMapper">
    <select id="queryUsers" resultType="User">
        select * from user
    </select>
    <select id="queryUserById" resultType="User">
        select * from user where id = #{uid}
    </select>
</mapper>

 在 application.yaml 中配置别名和 mapper 等等

#整合mybatis
mybatis:
  type-aliases-package: com.zhouyue.pojo #配置别名
  mapper-locations: classpath:mybatis/mapper/*.xml #配置mapper

测试

@SpringBootTest
class DataBaseApplicationTests {
    @Autowired
    UserMapper userMapper;
    @Test
    void contextLoads() throws SQLException {
        List<User> users = userMapper.queryUsers();
        for (User user : users) {
            System.out.println(user);
        }
    }

}

SpringSecurity

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

记住三个类

  • WebSecurityConfigurerAdapter:自定义Security 策略

  • AuthenticationManagerBuilder:自定义认证策略

  • @EnableWebSecurity:开启WebSecurity模式

Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)

“认证”(Authentication)

“授权”(Authorization)

这三个概念是通用的,不只是在 Spring Security 中存在

设置认证和授权

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问,但是功能页只有对应权限的人才能访问
        //请求授权的规则
        http.authorizeRequests()
                .antMatchers("/").permitAll() //首页所有人都能访问
                .antMatchers("/level1/**").hasRole("vip1") //level1下的页面只有 vip1 才能访问
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //开启没有权限默认到登录页,是自带的登录页
        http.formLogin();
    }
    //认证
    //密码编码:There is no PasswordEncoder mapped for the id "null"
    //在 Spring Security 5.0+ 新增了很多加密方式
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //从内存中取
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) //设置密码加密方式
                .withUser("zyqqq").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2") //设置认证用户以及权限和密码加密
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("root")).roles("vip1","vip2","vip3");
        //从数据库中取
//        auth.jdbcAuthentication()
    }
}

 开启注销

//开启注销功能,注销成功跳转到首页
http.logout().logoutSuccessUrl("/");

开启记住我功能

        //开启记住我
        http.rememberMe();

 将登录页定制为自己的页面

绑定记住我

 

 

以上只是简单使用

异步任务、邮件发送、定时任务

异步任务

使用 @Async 注解来设置一个方法为异步方法

 //告诉Spring这是一个异步的方法
    @Async
    public void hello(){
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("数据正在处理");
    }

并且要在主程序中开启异步功能

邮件发送

设置 mail 启动器

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

 这里使用QQ邮箱,需要开启以下服务,开启后可以获得一个密码,之后要用

在 application 配置文件中配置以下信息

测试发送一个简单的邮件

测试发送一个带附件的复杂邮件

 定时任务

 

TaskScheduler 任务调度者
TaskExecutor 任务执行者

@EnableScheduling //开启定时功能的注解
@Scheduled //什么时候执行

Cron表达式

首先要了解 cron 表达式,可以参考这个大佬的博文

一看就懂:cron 表达式小白一个-CSDN博客cron表达式

可以使用下面工具来进行转换

quartz/Cron/Crontab表达式在线生成工具-BeJSON.com

测试

@Service
public class ScheduledService {
    //在一个特定的时间执行这个方法
    //cron表达式
    //举例:每个两秒执行一次
    @Scheduled(cron = "0/2 * * * * ?")
    public void hello(){
        System.out.println("hello,你被执行了");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值