SpringBoot

第一个SpringBoot程序

官方:提供了一个快速生成的网站!IDEA集成了这个网站

  • 可以在官网直接下载后,导入idea开发(不推荐)

  • 直接使用idea创建一个springboot项目

spring-boot-maven-plugin 爆红解决

后面加上版本号,所加版本号需和springboot版本号相同

<build>
   <plugins>
       <plugin>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-maven-plugin</artifactId>
           <version>2.5.3</version>
       </plugin>
   </plugins>
</build>

 

修改banner

开机动画,网上搜索--> resource下建立banner.txt --> 复制进去自动识别

原理初探

自动配置:

 

pom.xml

  • spring-boot-dependencies:核心依赖在父工程中

  • 我们在写或者引入一些Springboot依赖的时候,不需要指定版本,就因为有这些版本仓库

 

启动器

  • <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter</artifactId>
    </dependency>
  • 启动器:说白了就是Springboot的启动场景;

  • 比如spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖

  • springboot会将所有的功能场景都变成一个个的启动器

  • 我们要使用什么功能,就只需要找到对应的启动器就行了 starter

 

主程序

//@SpringBootApplication: 标注这个类是一个springboot的应用:启动类下的所有资源被导入
@SpringBootApplication
public class Springboot01HelloworldApplication {

   public static void main(String[] args) {
       //将springboot应用启动
       SpringApplication.run(Springboot01HelloworldApplication.class, args
      );
  }
}

 

结论:springboot所有自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后配置成功!

  1. springboot在启动的时候,从类路径下/META-INF/spring.factories 获取指定的值;

  2. 将这些自动配置的类倒入容器,自动配置就会生效,帮我们进行自动配置!

  3. 以前我们需要配置的东西,现在springboot帮我们做了!

  4. 整合javaEE,解决方案和自动装配的东西都在 spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下

  5. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;

yaml语法

application.properties

- 语法结构: key=value

application.yaml

- 语法结构:key: 空格 value

 

#k=v
#对空格要求十分高!
#注入到我们的配置类中!

#普通的key-value
name:sr

#对象
student:
name:qinjiang
age:3

#行内写法
student:{name:sr,age:3}

#数组
pets:
- cat
- dog

pets:[cat,dog]

yaml可以直接给实体类赋值

dog类

@Component   //把这个类添加到spring组件里面
public class Dog {
   private String name;
   private Integer age;

   public Dog() {
  }

   public Dog(String name, Integer age) {
       this.name = name;
       this.age = age;
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public Integer getAge() {
       return age;
  }

   public void setAge(Integer age) {
       this.age = age;
  }


   @Override
   public String toString() {
       return "Dog{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
  }
}

Person类

@Component  //把类添加到组件中,为了被扫描到
@ConfigurationProperties(prefix="person")  //可以通过这个配置产生提示 ,如果不配置使用了这个注解就会提示爆红
public class Person {

   private String name;
   private Integer age;
   private Boolean happy;
   private Date birth;
   private Map<String,Object> maps;
   private List<Object> lists;
   private Dog dog;

   public Person(String name, Integer age, Boolean happy, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
       this.name = name;
       this.age = age;
       this.happy = happy;
       this.birth = birth;
       this.maps = maps;
       this.lists = lists;
       this.dog = dog;
  }

   public Person() {
  }

   @Override
   public String toString() {
       return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", happy=" + happy +
               ", birth=" + birth +
               ", maps=" + maps +
               ", lists=" + lists +
               ", dog=" + dog +
               '}';
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public Integer getAge() {
       return age;
  }

   public void setAge(Integer age) {
       this.age = age;
  }

   public Boolean getHappy() {
       return happy;
  }

   public void setHappy(Boolean happy) {
       this.happy = happy;
  }

   public Date getBirth() {
       return birth;
  }

   public void setBirth(Date birth) {
       this.birth = birth;
  }

   public Map<String, Object> getMaps() {
       return maps;
  }

   public void setMaps(Map<String, Object> maps) {
       this.maps = maps;
  }

   public List<Object> getLists() {
       return lists;
  }

   public void setLists(List<Object> lists) {
       this.lists = lists;
  }

   public Dog getDog() {
       return dog;
  }

   public void setDog(Dog dog) {
       this.dog = dog;
  }
}

application.yaml 进行赋值

person:
name: sr
age: 3
happy: false
birth: 2019/11/02
maps: {k1: v1,k2: v2}
lists:
  - code
  - music
  - girl
dog:
  name: ${person.hello:hello}_旺财
  age: 3

 

yaml支持驼峰命名(模糊匹配)

  以第一个大写为 - 后的第一个单词 :eg: firstName   first-name

JSR303 校验

百度搜索更多注解

@Validated //数据校验                     
public class Person {                
                                     
   @Email(message = "邮箱格式错误")        
   private String name;              

@Email需要添加依赖

<dependency>
   <groupId>org.hibernate.validator</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>7.0.1.Final</version>
</dependency>

配置文件位置

  1. file:./config/ file:代表项目,项目下的config目录下建立 applicayion.yaml

  2. file:./ 项目下直接建立yaml文件

  3. classpath:/config/ resource下建立config文件夹,然后建立yaml

  4. classpath:/ resource下直接建立yaml

 

多环境配置

properties

resource下建立多个properties

application.properties

application-test.properties

application-dev.properties

激活某个环境

application.properties

#写 - 后面的就可以
spring.profiles.active=dev

yaml

在一个yaml文件中用三个横杠分割每个配置

server:
port: 8081
spring:
profiles:
active:dev
---
server:
port: 8082
spring:
profiles: dev
---
server:
port: 8083
spring:
profiles: test

SpringBoot Web 开发

jar:webapp!

要解决的问题:

  • 导入静态资源。。

  • 首页

  • jsp,模板引擎Thymeleaf

  • 装配扩展SpringMVC

  • 增删改查

  • 拦截器

  • 国际化!

 

资源优先级:(resouces文件夹下)

resources > static (默认) > public

首页和图标定制

首页 index.html 放在 resouces 下面的 public 或者 static 下面

thymeleaf模板引擎

搜索thymeleaf官网
  1. 首先在pom.xml 中引入thymeleaf依赖

    <!--Thymeleaf,是基于3.x开发-->
    <dependency>
       <groupId>org.thymeleaf</groupId>
       <artifactId>thymeleaf-spring5</artifactId>
    </dependency>
    <dependency>
       <groupId>org.thymeleaf.extras</groupId>
       <artifactId>thymeleaf-extras-java8time</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
  2. 在页面上的头部引入如下:

    <html lang="en" xmlns:th="http://www.thymeleaf.org">

thymeleaf 语法

Getting started with the Standard dialects in 5 minutes - Thymeleaf

  • ${...} : Variable expressions.

  • *{...} : Selection expressions.

  • #{...} : Message (i18n) expressions.

  • @{...} : Link (URL) expressions.

  • ~{...} : Fragment expressions.

th:开头的代表thymeleaf

<div th:text="${msg}">
</div>

MVC配置原理

扩展视图解析器

config包下建立类

//如果你想diy一些定制化的功能,只要写这个组件,然后将它交给springboot
//扩展 springmvc dispatchservlet
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
  //ViewResolver 实现了视图解析器接口的类,我们就可以把它看作视图解析器

  //配置自己的视图解析器
  @Bean
  public ViewResolver myViewResolver(){
      return new MyViewResolver();
  }

  //自定义了一个自己的视图解析器MyViewResolver
  public static class MyViewResolver implements ViewResolver{

      @Override
      public View resolveViewName(String s, Locale locale) throws Exception {
          return null;
      }
  }
}

 

在springboot中,有非常多的 xxxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了!

 

springboot项目

导入页面模板

 

  1. 首页配置:

    1. 注意点,所有页面的静态资源都需要使用thymeleaf接管;

    2. url:@{}

  2. 页面国际化:

    1. 我么需要配置i18n文件

    2. 我们如果需要在项目中进行按钮自动切换,我们需要自定义一个组件LocaleResolver

    3. 记得将自己写的组件配置到spring容器 @Bean

    4. #{}

  3. 登录+拦截器

  4. 员工列表展示

    1. 提取公共页面

    2. 跳转到添加页面

    3. 添加员工成功

    4. 返回首页

 

前端:

  • 模板:别人写好的,我们拿来改成自己需要的

  • 框架:组件:自己手动组合拼接! Bootstrap,Layui,semantic-ui

    • 栅格系统

    • 导航栏

    • 侧边栏

    • 表单

 

写一个网站:

  1. 前端:页面什么样子;数据

  2. 设计数据库 (数据库设计难点!)

  3. 前端让他能够自动运行,独立化工程

  4. 数据接口如何对接:json , 对象 all in one!

  5. 前后端联调测试!

 

  1. 有一套自己熟悉的后台模板:工作必要!x-admin

  2. 前端界面至少自己能够通过前端框架组合出来一个网站页面、

    • index

    • about

    • blog

    • post

    • user

  3. 让这个网站能够独立运行

 

整合 JDBC 使用

application.yaml

spring:
datasource:
  username: root
  password: root
  url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
  driver-class-name: com.mysql.cj.jdbc.Driver

tests 进行测试

@SpringBootTest
class Springboot04DataApplicationTests {

   @Autowired
   DataSource dataSource;

   @Test
   void contextLoads() throws SQLException {
       //查看一下默认的数据源
       System.out.println(dataSource.getClass());
       //获得数据库连接
       Connection connection = dataSource.getConnection();
       System.out.println(connection);
       // xxxx Template: SpringBoot已经配置好模板bean,拿来即用
      connection.close();
  }
}

JDBCController

@RestController
public class JDBCController {
   @Autowired
   JdbcTemplate jdbcTemplate;

   //查询数据库的所有信息
   //没有实体类,数据库中的东西,怎么获取? Map
   @GetMapping("/userList")
   public List<Map<String,Object>> userList(){
       String sql="select * from mybatis.user";
       List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
       return list_maps;
  }

   @GetMapping("/addUser")
   public String addUser(){
       String sql = "insert into mybatis.user(id,name,pwd) values (4,'小明','123456')";
       jdbcTemplate.update(sql);
       return "update-ok";
  }
   @GetMapping("/updateUser/{id}")
   public String updateUser(@PathVariable("id") int id){
       String sql = "update mybatis.user set name=?,pwd=? where id=" +id;

       //封装
       Object[] objects = new Object[2];
       objects[0] = "小明2";
       objects[1] = "zzzzzz";
       jdbcTemplate.update(sql,objects);
       return "update-ok";
  }
   @GetMapping("/deleteUser/{id}")
   public String deleteUser(@PathVariable("id") int id){
       String sql = "delete from mybatis.user where id = ?";
       jdbcTemplate.update(sql,id);
       return "update-ok";
  }
}

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.5.3</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.sr</groupId>
   <artifactId>springboot-04-data</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>springboot-04-data</name>
   <description>Demo project for Spring Boot</description>
   <properties>
       <java.version>1.8</java.version>
   </properties>
   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-jdbc</artifactId>
       </dependency>

       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
           <exclusions>
               <exclusion>
                   <groupId>org.junit.vintage</groupId>
                   <artifactId>junit-vintage-engine</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
   </dependencies>

   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>
</project>

 

整合 Druid 数据源

pom.xml

<!--Druid-->
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.0.16</version>
</dependency>

application.yaml

#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
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

DruidConfig.java

@Configuration
public class DruidConfig {

   //将这个config文件和yaml文件绑定到一起
   @ConfigurationProperties(prefix = "spring.datasource")
   @Bean
   public DataSource druidDataSource(){
       return new DruidDataSource();
  }

   //后台监控 web.xml
   //固定代码,不用记
   //因为SpringBoot内置了servlet 容器,所以没有web.xml,替代方法:ServletRegistrationBean
   @Bean
   public ServletRegistrationBean StatViewServlet(){
       ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");

       //后台需要有人登录,账号密码配置
       HashMap<String,String> initParameters = new HashMap<>();
       //增加配置
       initParameters.put("loginUsername","admin"); //登录key 固定参数 loginUsername loginPassword
       initParameters.put("loginPassword","123456");
       //允许谁可以访问
       initParameters.put("allow",""); //如果后面参数为空代表所有人都可以访问
       //禁止谁能访问
       initParameters.put("sr","192.168.11.123");
       bean.setInitParameters(initParameters); //设置初始化参数
       return bean;
  }

   //filter
   @Bean
   public FilterRegistrationBean webStatFilter(){
       FilterRegistrationBean bean = new FilterRegistrationBean();
       bean.setFilter(new WebStatFilter());
       //可以过滤那些请求呢?
       HashMap<String,String> initParameters = new HashMap<>();
       //这些东西不进行统计
       initParameters.put("exclusions","*.js,*.css,/druid/*");
       bean.setInitParameters(initParameters);
       return bean;
  }
}

 

整合Mybatis框架

整合包

mybatis-spring-boot-starter

在mapper层加核心注解@Mapper

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.5.3</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.sr</groupId>
   <artifactId>springboot-05-mybatis</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>springboot-05-mybatis</name>
   <description>Demo project for Spring Boot</description>
   <properties>
       <java.version>1.8</java.version>
   </properties>
   <dependencies>
       <!-- mybatis自己研发的-->
       <dependency>
           <groupId>org.mybatis.spring.boot</groupId>
           <artifactId>mybatis-spring-boot-starter</artifactId>
           <version>2.1.1</version>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
       </dependency>
       <!--下面的是springboot官方的-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-jdbc</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</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>

UserMapper 接口

//Mapper这个注解表示了这是一个mybatis 的 mapper 类:Dao
@Mapper
@Repository
public interface UserMapper {

   List<User> queryUserList();

   User queryUserById(int id);

   int addUser(User user);

   int updateUser(User user);

   int deleteUser(int id);
}

UserMapper.xml 放在resource包下

新建包 mybatis-->mapper-->UserMapper.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.sr.mapper.UserMapper">
   <select id="queryUserList" resultType="user">
      select * from mybatis.user
   </select>
</mapper>

application.yaml 整合mybatis

spring:
datasource:
  username: root
  password: root
  url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
  driver-class-name: com.mysql.cj.jdbc.Driver
#整合mybatis
mybatis:
type-aliases-package: com.sr.pojo
mapper-locations: classpath:mybatis/mapper/*.xml

UserController 运行Application测试

@RestController
public class UserController {
   @Autowired
   private UserMapper userMapper;
   @RequestMapping("/a")
   public List<User> queryUserList(){
       List<User> userList = userMapper.queryUserList();
       for (User user : userList) {
           System.out.println(user);
      }
       return userList;
  }
}

 

SpringSecurity(安全)

做网站:安全应该在 设计之初 考虑

知名的做安全的框架:shiro,SpringSecurity (两者很像,除了类不一样,名字不一样)

认证,授权

 

 

 

依赖包:

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

 

 

 

 

 

 

 

学习主要看 springsecurity 帮助文档

注销功能

 

 

 

前端命名空间

依赖

 

 

可能会出现版本不兼容,需要降级版本

 

开启记住我功能

 

 

 

Shiro(面试常常问)

 

Swagger

  • 号称世界上最流行的Api框架

  • RestFul Api文档在线自动生成工具=>Api文档与API定义同步更新

  • 直接运行,可以在线测试API接口;

  • 支持多种语言:(Java,Php....)

 

在项目使用Swagger 需要springbox;

  • swagger2

  • ui

 

SpringBoot继承Swagger

  1. 新建一个Springboot-web项目

  2. 导入相关依赖

    在maven搜索包 springfox-swag

    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
    <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger2</artifactId>
       <version>2.9.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
    <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger-ui</artifactId>
       <version>2.9.2</version>
    </dependency>
  3. 编写一个Hello工程

  4. 配置Swagger==> Config

    @Configuration
    @EnableSwagger2  //开启Swagger2
    public class SwaggerCongfig {
       
    }
  5. 测试运行

 

配置Swagger

Swagger的bean实例Docket;

@Configuration
@EnableSwagger2  //开启Swagger2
public class SwaggerCongfig {
   //配置Swagger的Docket的bean实例
   @Bean
   public Docket docket(){
       return new Docket(DocumentationType.SWAGGER_2)
              .apiInfo(apiInfo());
  }
   //配置Swagger信息=apiInfo
   private ApiInfo apiInfo(){
       //作者信息
       Contact contact = new Contact("宋瑞", "url", "2604335111@qq.com");
       return new ApiInfo(
               "宋瑞的SwaggerAPI文档",
               "作者的描述",
               "v1.0",
               "http://wangzhi",
               contact,
               "Apache 2.0",
               "http://www.apache.org/licenses/LICENSE-2.0",
               new ArrayList());
  }
}

 

Swagger配置扫描接口

Docket.select()

@Configuration
@EnableSwagger2  //开启Swagger2
public class SwaggerCongfig {
   //配置Swagger的Docket的bean实例
   @Bean
   public Docket docket(){
       return new Docket(DocumentationType.SWAGGER_2)
              .apiInfo(apiInfo())
              .select()
               //RequestHandlerSelectors,配置要扫描接口的方式
               //basePackage:指定扫描的包
               //any():扫描全部
               //none():不扫描
               //withClassAnnotation:扫描类上的注解 ,参数是一个注解的反射对象
               //withMethodAnnotation:扫描方法上的注解
              .apis(RequestHandlerSelectors.basePackage("com.sr.swagger.controller"))  
               //paths():过滤什么路径
              .paths(PathSelectors.ant("/sr/**"))
              .build();  
  }

配置是否启动swagger

.enable(true/false) //是否启动swagger

在.select()上面写

 

问题:只希望我的swagger在生产环境中使用,在发布的时候不使用?

  • 判断是不是生产环境 flag=false

  • 注入enable(flag)

 

 

任务

异步任务

@Async //告诉Spring这是一个异步的方法

在 TestApplication开启异步注解功能:

@EnableAysnc

 

邮件任务

导入包

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

配置

spring.mail.username=2604335111@qq.com
spring.mail.password=wnujyuessdlmeabe
spring.mail.host=smtp.qq.com
#开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true

 

定时任务

 

posted @   Sr淑女  阅读(127)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示