SpringBoot 基础入门


Spring Boot简介

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的创建、运行、调试、部署等。使用Spring Boot可以做到专注于Spring应用的开发,而无需过多关注XML的配置。Spring Boot遵循“习惯优于配置”的理念,简单来说,它提供了一堆依赖打包,并已经按照使用习惯解决了依赖问题。使用Spring Boot可以不用或者只需要很少的Spring配置就可以让企业项目快速运行起来。

Spring Boot特点:

  1. 创建独立的Spring应用程序

  2. 嵌入的Tomcat,无需部署WAR文件

  3. 简化Maven配置

  4. 自动配置Spring

  5. 提供生产就绪型功能,如指标,健康检查和外部配置

  6. 绝对没有代码生成以及对XML没有要求配置


如果使用的IntelliJ IDEA,则无需下载插件,如果是使用Eclipse开发,没有SpringBoot插件的话,还是需要下载(这里可跳过…):


接受后,点击Finish,然后等待下载完毕,最后重启。

新建一个Spring Boot工程:

自动生成的目录结构如下:


在com.wu.application下再次新建一个controller包,并新建一个MyController类:

package com.wu.application.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
@RequestMapping("/boot")
public class MyController {@ResponseBody@RequestMapping("/sayhello")public String sayHello() {return "Hello,Spring Boot 2!";}
}

以上简单的几行语句就相当于SSM整合的几十甚至上百行代码,因为SSM整合需要编写许多配置文件,极其繁琐。


在application.properties中修改端口号和默认访问路径:

# 配置服务器的端口号
server.port=8888
# 配置服务器的默认访问路径
server.servlet.context-path=/app


Spring Boot不但能创建传统的war包应用,还能创建独立的不依赖于任何外部容器(比如Tomcat)的独立应用。

首先检查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.4.2</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wu</groupId><artifactId>springboot-1</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>springboot-1</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-web</artifactId></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>

如果要打jar包,就修改为<packaging>jar</packaging>,如果要打成war包,就修改为<packaging>war</packaging>

右击项目,点击Run As,选择Maven Clean,清除编译后的目录,默认是target目录:

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------< com.wu:springboot-1 >-------------------------
[INFO] Building springboot-1 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ springboot-1 ---
[INFO] Deleting E:\javaworkspace\springboot-1\target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.820 s
[INFO] Finished at: 2021-01-29T10:12:40+08:00
[INFO] ------------------------------------------------------------------------
[WARNING] The requested profile "pom.xml" could not be activated because it does not exist.

然后再次点击Run As,选择Maven Build,对Goals框输入内容 package:

可以发现,在项目目录下的target文件下出现了已经打好了的jar包:


文件路径搜索框搜索cmd,并输入java -jar springboot-1-0.0.1-SNAPSHOT.jar 命令:


对浏览器输入http://localhost:8888/app/boot/sayhello:

总结:约定优于配置,简洁胜于复杂,当学习完了SSH或SSM感触深刻,因为那就是配置的地狱。


@Configuration注解

创建两个pojo类:

package com.wu.application.pojo;public class Student {private String name;private Long id;private Integer age;private Book book;public Student(String name,Long id,Integer age,Book book) {this.name = name;this.id = id;this.age = age;this.book = book;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Book getBook() {return book;}public void setBook(Book book) {this.book = book;}@Overridepublic String toString() {return "Student [name=" + name + ", id=" + id + ", age=" + age + ", book=" + book + "]";}
}
package com.wu.application.pojo;public class Book {private String bookName;private Long bookId;public Book(String bookName,Long bookId) {this.bookName = bookName;this.bookId = bookId;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public Long getBookId() {return bookId;}public void setBookId(Long bookId) {this.bookId = bookId;}@Overridepublic String toString() {return "Book [bookName=" + bookName + ", bookId=" + bookId + "]";}
}

创建配置类:

将实例对象交给spring容器来统一管理

package com.wu.application.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import com.wu.application.pojo.Book;
import com.wu.application.pojo.Student;@Configuration(proxyBeanMethods = true) // 默认情况下的配置类(等价于配置文件)为单例模式 : 使用代理模式得到强化
public class MyConfig {@Bean("student")public Student getStudentBean() {return new Student("张三",20210129L,20,getBookBean());}@Bean("book")public Book getBookBean() {return new Book("一本书",0001L);}
}

应用入口类:

package com.wu.application;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;import com.wu.application.pojo.Book;
import com.wu.application.pojo.Student;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(MyApplication.class, args);Student student = context.getBean("student",Student.class);Book book = context.getBean("book",Book.class);System.out.println("Spring容器中的bean为单例模式:"+(student.getBook() == book));    }
}

结果:

.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v2.4.2)2021-01-29 17:42:33.822  INFO 1452 --- [           main] com.wu.application.MyApplication         : Starting MyApplication using Java 14.0.2 on PC-20200901HLGR with PID 1452 (E:\javaworkspace\springboot-1\target\classes started by Administrator in E:\javaworkspace\springboot-1)
2021-01-29 17:42:33.826  INFO 1452 --- [           main] com.wu.application.MyApplication         : No active profile set, falling back to default profiles: default
2021-01-29 17:42:35.089  INFO 1452 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8888 (http)
2021-01-29 17:42:35.102  INFO 1452 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-01-29 17:42:35.102  INFO 1452 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-01-29 17:42:35.213  INFO 1452 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/app]    : Initializing Spring embedded WebApplicationContext
2021-01-29 17:42:35.213  INFO 1452 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1315 ms
2021-01-29 17:42:35.453  INFO 1452 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-01-29 17:42:35.737  INFO 1452 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8888 (http) with context path '/app'
2021-01-29 17:42:35.752  INFO 1452 --- [           main] com.wu.application.MyApplication         : Started MyApplication in 2.388 seconds (JVM running for 3.517)
Spring容器中的bean为单例模式:true

如果将@Configuration中的proxyBeanMethods设置为false,则上面的结果就会变为false,所以如果组件之间形成依赖关系,则使用默认的单例模式,如果没有依赖关系的话,最好使用多例模式,因为这样的模式速度会变得更快。

@Import注解

@Import注解可以用于导入第三方包 ,虽然@Bean注解也可以,但是@Import注解快速导入的方式会显得更加便捷

package com.wu.application;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Import;import com.wu.application.pojo.Book;
import com.wu.application.pojo.Student;@Import({com.wu.application.pojo.Student.class,com.wu.application.pojo.Book.class})
@SpringBootApplication
public class MyApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(MyApplication.class, args);Student student = context.getBean(Student.class);Book book = context.getBean(Book.class);System.out.println("学生:"+student);System.out.println("书籍:"+book);}
}

结果:

.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v2.4.2)2021-01-29 18:14:12.375  INFO 2428 --- [           main] com.wu.application.MyApplication         : Starting MyApplication using Java 14.0.2 on PC-20200901HLGR with PID 2428 (E:\javaworkspace\springboot-1\target\classes started by Administrator in E:\javaworkspace\springboot-1)
2021-01-29 18:14:12.379  INFO 2428 --- [           main] com.wu.application.MyApplication         : No active profile set, falling back to default profiles: default
2021-01-29 18:14:13.456  INFO 2428 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8888 (http)
2021-01-29 18:14:13.469  INFO 2428 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-01-29 18:14:13.470  INFO 2428 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-01-29 18:14:13.577  INFO 2428 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/app]    : Initializing Spring embedded WebApplicationContext
2021-01-29 18:14:13.577  INFO 2428 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1132 ms
2021-01-29 18:14:13.776  INFO 2428 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-01-29 18:14:14.024  INFO 2428 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8888 (http) with context path '/app'
2021-01-29 18:14:14.036  INFO 2428 --- [           main] com.wu.application.MyApplication         : Started MyApplication in 2.133 seconds (JVM running for 3.041)
学生:Student [name=null, id=null, age=null, book=null]
书籍:Book [bookName=null, bookId=null]

@Conditional注解

package com.wu.application.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import com.wu.application.pojo.Book;
import com.wu.application.pojo.Student;@Configuration(proxyBeanMethods = true) // 默认情况下的配置类(等价于配置文件)为单例模式 : 使用代理模式得到强化
public class MyConfig {@Bean("student")public Student getStudentBean() {return new Student("张三",20210129L,20,getBookBean());}
//  注意这里没有使用@Bean("book")标签public Book getBookBean() {return new Book("一本书",0001L);}
}
package com.wu.application;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(MyApplication.class, args);boolean existStudent = context.containsBean("student");boolean existBook = context.containsBean("book");System.out.println("学生存在容器中:"+existStudent);System.out.println("书籍存在容器中:"+existBook);}
}

结果:

学生存在容器中:true
书籍存在容器中:false

如果使用@ConditionalOnBean:

@Configuration(proxyBeanMethods = true) // 默认情况下的配置类(等价于配置文件)为单例模式 : 使用代理模式得到强化
public class MyConfig {@ConditionalOnBean(name = "book")@Bean("student")public Student getStudentBean() {return new Student("张三",20210129L,20,getBookBean());}@Bean("book")public Book getBookBean() {return new Book("一本书",0001L);}
}

结果:

学生存在容器中:false
书籍存在容器中:false

之所以为以上结果,是因为使用了条件注解,只有当spring容器中已经事先存在具有name为"book"的组件,才能使得以下的组件注册成功。

相应的,还有许多其它的类似的条件注解,我们只需按照字面的英语意思理解使用即可。

@ImportResource

通过导入资源文件来将组件注册进入spring容器中进行统一管理。

在resource文件夹下建立bean文件夹,在其下建立spring-bean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id = "student" class = "com.wu.application.pojo.Student"><property name="name" value = "张三"/><property name="id" value = "20210129"/><property name="age" value = "20"/><property name="book" ref = "book" /></bean><bean id = "book" class = "com.wu.application.pojo.Book"><property name="bookName" value = "一本书"/><property name="bookId" value = "10001"/></bean>
</beans>

配置类:

package com.wu.application.config;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@ImportResource(value = "classpath:/bean/spring-bean.xml")
@Configuration // 默认情况下的配置类(等价于配置文件)为单例模式 : 使用代理模式得到强化
public class MyConfig {}
}

MyApplication.java:

package com.wu.application;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;import com.wu.application.pojo.Book;
import com.wu.application.pojo.Student;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(MyApplication.class, args);Student student = context.getBean("student",Student.class);Book book = context.getBean("book",Book.class);System.out.println(student);System.out.println(book);}
}

结果:

Student [name=张三, id=20210129, age=20, book=Book [bookName=一本书, bookId=10001]]
Book [bookName=一本书, bookId=10001]

@ConfigurationProperties注解

第一种:@ConfigurationProperties+@Component

配置绑定

首先在pom.xml文件中添加如下内容:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

对application.properties进行修改:

# 自定义配置
mybook.bookName=一本书
mybook.bookId=999

pojo类:

package com.wu.application.pojo;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component(value = "book")
@ConfigurationProperties(prefix = "mybook")
public class Book {private String bookName;private Long bookId;public Book() {}public Book(String bookName,Long bookId) {this.bookName = bookName;this.bookId = bookId;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public Long getBookId() {return bookId;}public void setBookId(Long bookId) {this.bookId = bookId;}@Overridepublic String toString() {return "Book [bookName=" + bookName + ", bookId=" + bookId + "]";}
}

应用入口类:

package com.wu.application;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;import com.wu.application.pojo.Book;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(MyApplication.class, args);Book book = context.getBean("book",Book.class);System.out.println(book);}
}

结果:

Book [bookName=张三, bookId=999]

第二种:@EnableConfigurationProperties+@ConfigurationProperties

pojo类:

package com.wu.application.pojo;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "mybook")
public class Book {private String bookName;private Long bookId;public Book() {}public Book(String bookName,Long bookId) {this.bookName = bookName;this.bookId = bookId;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public Long getBookId() {return bookId;}public void setBookId(Long bookId) {this.bookId = bookId;}@Overridepublic String toString() {return "Book [bookName=" + bookName + ", bookId=" + bookId + "]";}
}

配置类:

package com.wu.application.config;import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;import com.wu.application.pojo.Book;
@Configuration // 默认情况下的配置类(等价于配置文件)为单例模式 : 使用代理模式得到强化
@EnableConfigurationProperties(Book.class) // 1.开启属性配置功能 2.使得该组件自动注册到spring容器中
public class MyConfig {
}

应用入口类:

package com.wu.application;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;import com.wu.application.pojo.Book;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(MyApplication.class, args);Book book = context.getBean("mybook-com.wu.application.pojo.Book",Book.class);System.out.println(book);}
}

结果:

Book [bookName=张三, bookId=999]

通过Value注解获取自定义配置

首先在application.yml中添加自定义属性语句:

student:name: 张三age: 20id: 2021

MyController.java:

package com.wu.springboot.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
@RequestMapping("/home")
public class MyController {@Value("${student.name}")String studentName;@Value("${student.age}")int studentAge;@Value("${student.id}")long studentId;@RequestMapping(value = "/info")@ResponseBodypublic String studentInfo(){return "学生姓名:"+studentName+",学生年龄:"+studentAge+",学生学号:"+studentId;}
}

结果:

事务处理

SpringBoot&Mybatis-Plus实现转账事务为例

事务实现是通过在启动类上添加注解@EnableTransactionManagement以及在相应类或者相应方法上添加@Transactional注解

package org.wu.project.controlle;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.wu.project.mapper.AccountMapper;
import org.wu.project.service.AccountService;@RestController
public class AccountController {private AccountService accountService;@Autowired@Qualifier("accountServiceBean")public void setAccountService(AccountService accountService) {this.accountService = accountService;}@RequestMapping("/transfer")public boolean transfer(String senderId,String receiverId,Integer money){try {accountService.transfer(senderId, receiverId, money);return true;}catch(Exception e){e.printStackTrace();}return false;}
}
package org.wu.project.entity;import lombok.Data;@Data
public class Account {private String id;private String userName;private int money;
}
package org.wu.project.mapper;import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;@Repository("accountMapperBean")
public interface AccountMapper {void increaseMoney(@Param("id") String id,@Param("money") Integer money);void reduceMoney(@Param("id") String id,@Param("money") Integer money);
}
package org.wu.project.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wu.project.mapper.AccountMapper;@Service("accountServiceBean")
public class AccountService {private AccountMapper accountMapper;@Autowired@Qualifier("accountMapperBean")public void setAccountMapper(AccountMapper accountMapper) {this.accountMapper = accountMapper;}@Transactionalpublic void transfer(String senderId,String receiverId,Integer money){accountMapper.increaseMoney(receiverId,money);accountMapper.reduceMoney(senderId,money);}
}
package org.wu.project;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;@SpringBootApplication
@EnableTransactionManagement
@MapperScan("org.wu.project.mapper")
public class ProjectApplication {public static void main(String[] args) {SpringApplication.run(ProjectApplication.class, args);}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "org.wu.project.mapper.AccountMapper"><update id="increaseMoney">update account set money = #{money} + moneywhere id = #{id}</update><update id="reduceMoney">update account set money = money - #{money}where id = #{id}</update>
</mapper>
# 应用名称
spring.application.name=project
# 应用服务 WEB 访问端口
server.port=8888
#下面这些内容是为了让MyBatis-Plus映射
#指定Mybatis-Plus的Mapper文件
mybatis-plus.mapper-locations=classpath:mappers/*.xml
#指定Mybatis-Plus的实体目录
mybatis-plus.type-aliases-package=org.wu.project.entity
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=root

转账事务处理之前:

转账事务处理之后(本地局域网主机输入网址http://localhost:8888/transfer?senderId=001&receiverId=002&money=200):

然后模拟一个异常来使得该事务发生中断,重新输入url:

结果为保持以上的money:

进一步扩展事务有关的细节:

@Transactional相关的属性

参数名称

功能描述

readOnly

该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)

rollbackFor

该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:

指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName

该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:

指定单一异常类名称:@Transactional(rollbackForClassName="RuntimeException")

指定多个异常类名称:@Transactional(rollbackForClassName={"RuntimeException","Exception"})

noRollbackFor

该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:

指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName

该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:

指定单一异常类名称:@Transactional(noRollbackForClassName="RuntimeException")

指定多个异常类名称:

@Transactional(noRollbackForClassName={"RuntimeException","Exception"})

propagation

该属性用于设置事务的传播行为,具体取值可参考表6-7。

例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

isolation

该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置

timeout

该属性用于设置事务的超时秒数,默认值为-1表示永不超时

  • 脏读:并发事务A读到了并发事务B还未提交的数据
  • 不可重复读: 在一个并发事务里面读取了两次某个数据,读出来数据不一致
  • 幻读: 在一个并发事务里面的操作中实现了不符合预期的数据(另一个并发事务改变了数据数量… ),幻读出现的前提是并发的事务中发生了插入、删除操作

SpringBoot工程多环境配置

一个产品从开发到用户使用一般会涉及到以下四个环境:
  • 开发环境
  • 测试环境
  • 准生产环境
  • 生产环境

建立四个以application-作为前缀的配置文件

在主配置文件application.yml中添加如下语句作为环境的选择:

#以下选择为开发环境
spring.profiles.active=dev

配置文件YAML类型

简介

YAML(读音:呀们) 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。 YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲。YAML 的配置文件后缀为 .yml.yaml

基本语法
  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#'表示注释
用法
  • 字面量意思
key: value
  • 对象
# 写法一:行内写法
key: {key1:value1,key2:value2}
# 写法二:缩进写法
key:key1: value1key2: value2
  • 数组
# 写法一:行内写法
key: [value1,value2]
# 写法二:缩进写法
key:- value1- value2

这里需要注意的地方为:单引号会将字符串中的转义字符原封不动地输出,而双引号则会解析转义字符

自定义类绑定的配置提示

在main文件夹下建立webapp文件夹,并将其设置为资源文件夹:

pom.xml中加入依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

打包排除:

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></excludes></configuration></plugin></plugins>
</build>

配置复杂属性

application.yml:

others:users:- name: 张三address: 中国contact:- QQ- 微信- name: 李四address: 日本contact:- 邮箱- 电话

Users.java:

package com.wu.springboot.pojo;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.List;@Component
@ConfigurationProperties(prefix = "others")
public class Users {private List<User> users;public List<User> getUsers(){return users;}public void setUsers(List<User> users){this.users = users;}@Overridepublic String toString() {return "Users{" +"users=" + users +'}';}
}
class User{private String name;private String address;private List<String> contact;public String getName() {return name;}public String getAddress(){return address;}public List<String> getContact(){return contact;}public void setName(String name){this.name = name;}public void setAddress(String address){this.address = address;}public void setContact(List<String> contact){this.contact = contact;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", address='" + address + '\'' +", contact=" + contact +'}';}
}

MyController:

package com.wu.springboot.cotroller;import com.wu.springboot.pojo.Book;import com.wu.springboot.pojo.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/")
public class MyController {@AutowiredUsers users;@GetMapping("/others")public String others(){return users.toString();}
}

结果:

SpringBoot集成传统jsp页面

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.4.2</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wu.springboot</groupId><artifactId>springboot-01</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-01</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-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- springboot内嵌Tomcat对jsp的解析依赖 --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId></dependency></dependencies><build><!-- 指定jsp文件编译的路径META-INF/resources --><resources><resource><!-- 指定源文件路径 --><directory>src/main/webapp</directory><!-- 指定编译路径 --><targetPath>META-INF/resources</targetPath><includes><include>*.*</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource></resources><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.2</version></plugin></plugins></build></project>

application.yml:

spring:mvc:view:suffix: .jspprefix: /

MyController.java:

package com.wu.springboot.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("/home")
public class MyController {@RequestMapping(value = "/info")public String index(Model model){model.addAttribute("info","Hello World!");return "index";}
}

index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><h1>${info}</h1>
</body>
</html>

SpringBoot集成Thymeleaf

Thymeleaf是新一代Java模板引擎,支持HTML原型,既可以让前端工程师在浏览器中直接打开查看样式,也可以让后端工程师结合真实数据查看显示效果。使用其余的模板技术时,整合方式同Thymeleaf类似,比如FreeMarker大致也是如此,如果读者使用的是目前流行的前后端分离技术(比如Vue,React),那么在开发过程中不需要整合视图层技术,后端提供接口即可。

添加依赖:

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

application.yml:

server:port: 8888
# Thymeleaf选项自定义配置
spring:thymeleaf:cache: false # 缓存关闭,一般生产环境中需要关闭check-template: true # 检查模板是否存在check-template-location: true # 检查模板位置是否存在encoding: UTF-8 # 模板文件编码为UTF-8prefix: classpath:/templates/ # 模板文件位置suffix: .html # 模板文件后缀servlet:content-type: text/html # Content-type类型配置

Book.java:

package com.wu.springboot.pojo;public class Book {private String name;private String author;private Float price;public String getName() {return name;}public String getAuthor() {return author;}public Float getPrice(){return price;}public void setName(String name){this.name = name;}public void setAuthor(String author){this.author = author;}public void setPrice(Float price){this.price = price;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +", price=" + price +'}';}
}

MyController.java:

package com.wu.springboot.cotroller;import com.wu.springboot.pojo.Book;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;import java.util.ArrayList;
import java.util.List;@Controller
@RequestMapping("/")
public class MyController {@GetMapping("/books")public ModelAndView books(){List<Book> books = new ArrayList<Book>();Book book1 = new Book();book1.setAuthor("张三");book1.setName("张三传");book1.setPrice(new Float(100.5));Book book2 = new Book();book2.setAuthor("李四");book2.setName("李四记");book2.setPrice(new Float(150.0));books.add(book1);books.add(book2);ModelAndView mv = new ModelAndView();mv.addObject("books",books);mv.setViewName("books");return mv;}
}

books.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>书籍信息</title>
</head>
<body><div align="center"><table border="1"><tr><td>书籍名称</td><td>书籍作者</td><td>书籍价格</td></tr><tr th:each="book:${books}"><td th:text="${book.name}"></td><td th:text="${book.author}"></td><td th:text="${book.price}"></td></tr></table></div>
</body>
</html>

结果:


SpringBoot整合log4j2日志

日志级别
机制:当一条日志信息的级别大于等于配置文件的级别,就生成日志记录。

  • trace:追踪,就是程序推进一下,可以写个trace输出,最不常用
  • debug:调试级别,一般作为最低级别
  • info:输出重要的信息,较常用
  • warn:警告级别
  • error:错误级别
  • fatal:致命级别

输出源

  • CONSOLE(输出到控制台)
  • FILE(输出到文件)

输出格式

  • SimpleLayout:以简单的格式显示
  • HTMLLayout:以HTML表格格式显示
  • PatternLayout:自定义格式显示

PatternLayout自定义日志格式
%d{yyyy-MM-dd HH:mm:ss} : 日志生成时间格式
%-5level : 日志输出级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%c : 日志输出logger的名称(%logger)
%t : 日志输出当前线程名称
%p : 日志输出格式
%m : 日志内容,即 logger.info(“message”)
%n : 日志换行符
%C : 日志输出Java类名(%F)
%L : 日志输出行号
%M : 日志输出方法名
%l : 日志输出语句所在的行数, 包括类名、方法名、文件名、行数
hostName : 日志输出本地机器名
hostAddress : 日志输出本地IP地址

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 排除springboot默认日志配置 --><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId><version>2.5.1</version>
</dependency>

log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO"><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{yyyy年MM月dd日 HH时mm分ss秒} [线程:%t 方法:%M] %-5level %logger{36} - %msg%n" /></Console></Appenders><Loggers><Root level="info"><AppenderRef ref="Console" /></Root></Loggers>
</Configuration>
package org.wu.project.controlle;import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class AccountController {Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);@RequestMapping("/test")public void test(){logger.info("测试信息打印");}

控制台输出日志信息:

2021-10-31 14:56:43,442 main INFO Log4j appears to be running in a Servlet environment, but there's no log4j-web module available. If you want better web container support, please add the log4j-web JAR to your web archive or server lib directory.__     _____     __ __   ___              _____ _\ \   / (_) \   / / \ \ / (_)            / ____| |\ \_/ / _ \ \_/ /__ \ V / _ _ __   __ _| |    | |__   ___ _ __\   / | | \   / _ \ > < | | '_ \ / _` | |    | '_ \ / _ \ '_ \| |  | |  | |  __// . \| | | | | (_| | |____| | | |  __/ | | ||_|  |_|  |_|\___/_/ \_\_|_| |_|\__, |\_____|_| |_|\___|_| |_|__/ ||___/
2021年10月31日 14时56分43秒 [线程:main 方法:logStarting] INFO  org.wu.project.ProjectApplication - Starting ProjectApplication on yiyexingchen with PID 7616 (E:\onedrive\OneDrive - laosaonan2\桌面\Java\spring-demo01\target\classes started by Localhost in E:\onedrive\OneDrive - laosaonan2\桌面\Java\spring-demo01)
2021年10月31日 14时56分43秒 [线程:main 方法:logStartupProfileInfo] INFO  org.wu.project.ProjectApplication - No active profile set, falling back to default profiles: default
2021年10月31日 14时56分44秒 [线程:main 方法:initialize] INFO  org.springframework.boot.web.embedded.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8888 (http)
2021年10月31日 14时56分44秒 [线程:main 方法:log] INFO  org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8888"]
2021年10月31日 14时56分44秒 [线程:main 方法:log] INFO  org.apache.catalina.core.StandardService - Starting service [Tomcat]
2021年10月31日 14时56分44秒 [线程:main 方法:log] INFO  org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.41]
2021年10月31日 14时56分44秒 [线程:main 方法:log] INFO  org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2021年10月31日 14时56分44秒 [线程:main 方法:prepareWebApplicationContext] INFO  org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1203 ms_ _   |_  _ _|_. ___ _ |    _
| | |\/|_)(_| | |_\  |_)||_|_\ /               |         3.4.2
2021年10月31日 14时56分46秒 [线程:main 方法:initialize] INFO  org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
2021年10月31日 14时56分46秒 [线程:main 方法:log] INFO  org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8888"]
2021年10月31日 14时56分46秒 [线程:main 方法:start] INFO  org.springframework.boot.web.embedded.tomcat.TomcatWebServer - Tomcat started on port(s): 8888 (http) with context path ''
2021年10月31日 14时56分46秒 [线程:main 方法:logStarted] INFO  org.wu.project.ProjectApplication - Started ProjectApplication in 3.26 seconds (JVM running for 4.83)
2021年10月31日 14时59分33秒 [线程:http-nio-8888-exec-1 方法:log] INFO  org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2021年10月31日 14时59分33秒 [线程:http-nio-8888-exec-1 方法:initServletBean] INFO  org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2021年10月31日 14时59分33秒 [线程:http-nio-8888-exec-1 方法:initServletBean] INFO  org.springframework.web.servlet.DispatcherServlet - Completed initialization in 8 ms
2021年10月31日 14时59分33秒 [线程:http-nio-8888-exec-1 方法:test] INFO   - 测试信息打印

自定义类绑定的配置提示依赖实例:

<dependency><!-- Bean配置文件提示 --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency><configuration><excludes><!-- 打包排除 --><exclude><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></exclude></excludes>
</configuration>
package org.wu.project.entity;import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@ConfigurationProperties(prefix = "test-object")
@Component
@Data
@ToString
public class TestObject {String testName;String testAge;
}

SpringBoot 基础入门相关推荐

  1. SpringBoot基础入门 01

    一.SpringBoot基础 1.1 原有Spring优缺点分析 1.1.1 Spring的优点分析 Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE ...

  2. SpringBoot基础入门篇

    SpringBoot是什么 为什么我们要使用SpringBoot? Spring Boot makes it easy to create stand-alone, production-grade ...

  3. SpringBoot基础入门

    1.SpringBoot核心相关内容 1.1入口类 SpringBoot通常有一个入口类*Application,内部有一个main方法,是启动SpringBoot的入口.使用@SpringBootA ...

  4. 2022年最新最全的Java零基础入门,零基础入门springboot,MySQL的学习

    今天就来开始带领大家零基础入门Java开发 写在前面 为什么学习Java Java用途很广泛,如下图所示,Java可以做很多工作 JAVA语言发展史 2019年3月,JDK12版本发布. 2019年9 ...

  5. 经典再现,看到就是赚到。尚硅谷雷神 - SpringBoot 2.x 学习笔记 - 基础入门篇

    SpringBoot 2.x 时代 – 基础入门篇 视频学习地址:https://www.bilibili.com/video/BV1Et411Y7tQ?p=112&spm_id_from=p ...

  6. SpringBoot@Schedule入门基础

    SpringBoot@Schedule入门基础 前言 Schedule是一个任务调度器,SpringBoot中可定时触发执行定时任务. 一.基本概念 在SpringBoot中,使用 @Schedule ...

  7. SpringBoot2.x(3)---基础入门

    SpringBoot2.x(3)---基础入门 一.概述 Spring Boot设计目的是用来简化新Spring应用的初始搭建以及开发过程.Spring Boot并不是对Spring功能上的增强,而是 ...

  8. SpringBoot基础知识

    SpringBoot基础知识 SpringBoot课程笔记 前言 ​ 很荣幸有机会能以这样的形式和互联网上的各位小伙伴一起学习交流技术课程,这次给大家带来的是Spring家族中比较重要的一门技术课程- ...

  9. 8. SpringBoot基础学习笔记

    SpringBoot基础学习笔记 课程前置知识说明 1 SpringBoot基础篇 1.1 快速上手SpringBoot SpringBoot入门程序制作 1.2 SpringBoot简介 1.2.1 ...

最新文章

  1. HDU2255 奔小康赚大钱(km模板题)
  2. iterm2 mac链接linux工具 桌面程序Transmit
  3. Ubuntu 常见报错处理
  4. Linux锁定和解锁用户
  5. 【leetcode】Permutations
  6. windows封装/备份恢复/双系统安装
  7. 启动ubuntu无反应_奔驰E200轿车启动无反应检修
  8. MySQL报错The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents .....
  9. vim 编辑二进制文件
  10. MVVM模式基于开源VLC解码器WPF万能视频播放器
  11. Linux合入patch命令,Linux下Patch命令用来打补丁和卸载补丁
  12. 4G和4G LTE之间的区别是什么?
  13. html图片与文字的排版6,前端开发学习笔记(六)- Css 文字排版
  14. discuz 模板php代码,自定义HTML模板DIY支持PHP代码解析
  15. moments音标_moment的意思在线翻译,解释moment中文英文含义,短语词组,音标读音,例句,词源,同义词【澳典网ODict.Net】...
  16. JAVA经典兔子问题
  17. 华为 Mate8 Emui 5.0 安卓 7.0 root 记录
  18. PPT图片怎么排列?
  19. Visual Studio Code插件-前端工程师开发必备
  20. R语言 牛顿-拉夫森迭代法求方程组

热门文章

  1. android美图秀秀--基础
  2. 大工18秋《计算机文化基础》在线作业2,东北财经大学作业2017秋学期《大学英语2》期末考核作业答案100分...
  3. 张飞硬件班笔记之电容
  4. 开工大吉,重温下架构设计六大原则
  5. 震惊!这家70个人的小公司让马云坐不住了!
  6. 高中数学一轮复习函数:指数与指数函数_习题含解析
  7. 四川大学生计算机一级考试内容,四川省大学生计算机一级考试全真模拟试题
  8. 无线lan连接服务器,无线 LAN 控制器和轻量接入点基本配置示例
  9. excel中VLOOKUP跨文件的调用
  10. ubuntu 安装微信(wechat)