1.SpringBoot的概述
1.1什么是SpringBoot,为什么要SpringBoot,SpringBoot的特点是什么?
SpringBoot是spring的子项目,帮助程序员减少xml配置,做到迅速上手,让开发人员注重业务而不是配置;
减少复杂的配置和依赖管理,只需要使用java -jar 启动,就可以得到一个生产级别的web工程;
特点:
1.快速
2.直接嵌入应用服务器,如tomcat、jetty、undertow等;不需要去部署war包
3.提供固定的启动器依赖去简化组件配置;实现开箱即用(启动器starter-其实就是Spring Boot提供的一个jar包),通过自己设置参数(.properties或.yml的配置文件),即可快速使用。
4.自动配置spring和其他需要的第三方依赖
5.提供了一些大型项目中常见的非功能性特性,如内嵌服务器、安全、指标,健康检测、外部化配置等
6.绝对没有代码生成,也无需 XML 配置。
详情请看官网:https://spring.io/projects/spring-boot
2.快速入门
2.1.创建工程
2.1.1.创建maven项目
2.1.2.pom.xml 添加springBoot父依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
2.1.3.添加web启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.1.4.管理JDK版本
<properties>
<java.version>1.8</java.version>
</properties>
2.1.5.完整的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cheung</groupId>
<artifactId>itheima_springboot_test</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<!-- 添加父依赖-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--添加启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
2.2 创建启动类
2.2.1 启动类代码如下:
编写 itheima-springboot_test\src\main\java\com\cheung\Application.java 如下:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
2.2.2 创建controller类
编写 itheima-springboot_test\src\main\java\com\cheung\controller\HelloController.java 如下:
//@RestController注解相当于@ResponseBody + @Controller合在一起的作用。
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "HELLO SPRING!";
}
2.2.3 启动测试
上面端口被我改成了8081
3.java配置应用
3.1 传统的Java注解配置
java配置主要靠java类和一些注解,比较常用的注解有:
- @configuration:声明类作为配置类,代替xml文件
- @Bean :声明在方法上,将方法的返回值加入Bean容器,代替 标签
- @Value :属性注入
- @PropertySource:指定外部属性文件
以下是使用注解的方式连接Druid连接池:
pom.xml:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test
jdbc.username=root
jdbc.password=root
class类:JdbcConfig.java
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
@Value("${jdbc.url}")
String url;
@Value("${jdbc.driverClassName}")
String driverClassName;
@Value("${jdbc.username}")
String username;
@Value("${jdbc.password}")
String password;
/*
通过@Bean将 dataSource() 方法声明为一个注册Bean的方法,Spring会自动调用该方法,将该方法的返回值
*/
加入Spring容器中。
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
在controller中进行测试 修改代码如下:
//@RestController注解相当于@ResponseBody + @Controller合在一起的作用。
@RestController
public class HelloController {
@Autowired
private DataSource dataSource;
@GetMapping("/hello")
public String hello() {
System.out.println("dataSource = " + dataSource);
return "HELLO SPRING!";
}
结果就不贴图了,控制台打印DataSource地址
3.2 SpringBoot的属性注入(这个知道就行,springboot自动封装了hikari连接池直接配置好 @Autowirte就行)
属性文件的名称必须为application.properties 或者 application.yml
3.2.1 yml文件说明:
- 缩进两个空格 写key
- 冒号后面空一格再写值
jdbc:
driverClass: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://10.211.55.7/test
user: root
password: cheung
properties文件这样写:
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://10.211.55.7/test
jdbc.user==root
jdbc.password=cheung
当有多个yml配置文件时:命名规则和application中的引用
命名规则:application-**.xml命名;
1.创建application-abc.yml:
baidu:
url: https://www,baidu.com
2.创建application-def.yml;
itheima:
url: https://www.itheima.com
3.在application.yml中添加如下配置:
spring:
profiles:
active: abc ,def
3.2.2 更加优雅的配置
事实上,如果一段属性只有一个Bean需要使用,我们无需将其注入到一个类(JdbcProperties,将该类上的所有注
解去掉)中。而是直接在需要的地方声明即可;再次修改 JdbcConfig 类为如下代码:
@Configuration
public class JdbcConfig {
@Bean // 声明要注入的属性前缀,Spring Boot会自动把相关属性通过set方法注入到DataSource中 @ConfigurationProperties(prefix = "jdbc") //加载application.yml 中jdbc:下的数据
public DataSource dataSource() {
return new DruidDataSource();
}
}
我们直接把 @ConfigurationProperties(prefix = “jdbc”) 声明在需要使用的 @Bean 的方法上,然后SpringBoot就会自动调用这个Bean(此处是DataSource)的set方法,然后完成注入。使用的前提是:该类必须有对应属性的set方法!(最后key与设置的属性一样)
4.springBoot自动篇日志原理
- 注解:@SpringBootApplication
- run方法:SpringApplication.run()
源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
通过这段我们可以看出,在这个注解上面,又有一个 @Configuration 注解。通过上面的注释阅读我们知道:这个注解的作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了 @Configuration 的类,并且读取其中的配置信息。而 @SpringBootConfiguration 是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。
@EnableAutoConfiguration注解官方的一些说明
翻译如下:springboot根据你添加的依赖推测你要配置的spring
第二级的注解 @EnableAutoConfiguration ,告诉Spring Boot基于你所添加的依赖,去“猜测”你想要如何配
置Spring。比如我们引入了 spring-boot-starter-web ,而这个启动器中帮我们添加了 tomcat 、 SpringMVC
的依赖。此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!
@ComponentScan(通常启动类放与比较前的包目录中)
配置组件扫描的指令。提供了类似与 <context:component-scan> 标签的作用通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包
spring.factories文件中放置了许多默认配置类
找到spring.factories文件的源码:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
...
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
...
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return this.getSpringFactoriesInstances(type, new Class[0]);
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
...
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
...
return instances;
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
//最终通过loadSpringFactories找到spring.factories
//在spring-boot-autoconfigure-2.1.5.RELEASE.jar!/META-INF/spring.factories
spring.factories文件内容如下:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
....
可以发现以EnableAutoConfiguration接口为key的一系列配置,key所对应的值,就是所有的自动配置类,可以在当前的jar包中找到这些自动配置类:
非常多,几乎包含了主流的开源框架,例如:
- redis
- jms
- amqp
- jdbc
- jackson
- mongodb
- jpa
- solr
- elasticsearch
举个例子,查看静态资源路径位置
1.找到properties文件位置
路径如下:/spring-boot-autoconfigure-2.1.5.RELEASE.jar!/org/springframework/boot/autoconfigure/web/ResourceProperties.class
@ConfigurationProperties(
prefix = "spring.resources",
ignoreUnknownFields = false
)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
看可以看到静态文件位置在resource目录下这些:“classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, “classpath:/public/”;静态文件就创建文件夹放在以上几个目录中
修改默认位置的话可以在application.yml中设置:
spring:
resources:
CLASSPATH_RESOURCE_LOCATIONS: 路径
5.lombok
分析:
使用Spring Boot整合SSM工程;需要使用到数据库数据。
-
将数据库表数据导入到数据库中(springboot_test);
-
编写数据库表对应的实体类;一般情况下需要编写get/set/toString等这些方法会耗时并且会让实体类看起来比较臃肿。可以使用lombok插件对实体类进行简化。
lombok是一个插件工具类包;提供了一些注解@Data、@Getter等这些注解去简化实体类中的构造方法、get/set等方法的编写。
- 在IDEA中安装lombok插件;
- 添加lombok对应的依赖到项目pom.xml文件;
<dependency>
<!--添加lombok文件依赖-->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- 改造实体类使用lombok注解
小结:
在Bean上使用:
@Data :自动提供getter和setter、hashCode、equals、toString等方法
@Getter:自动提供getter方法
@Setter:自动提供setter方法
@Slf4j:自动在bean中提供log变量,其实用的是slf4j的日志功能。
例子:
@Data//自动提供getter和setter、hashCode、equals、toString等方法
@Slf4j //自动在bean中提供log变量,其实用的是slf4j的日志功能
@Table(name = "tb_user")
public class User {
@Id
@KeySql(useGeneratedKeys = true)//开启主键自动回填
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
// 性别 1男性 2女性
private Integer sex;
private Date birthday;
private String note;
private Date Created;
private Date updated;
}
6.Spring Boot整合-SpringMVC端口和静态资源
分析:
-
修改tomcat端口
查询**Properties,设置配置项(前缀+类变量名)到application配置文件中
-
访问项目中的静态资源
静态资源放置的位置;放置静态资源并访问这些资源
小结:
- 修改项目tomcat端口:
#tomcat端口
server:
port: 80
- 在spring boot项目中静态资源可以放置在如下目录:全部在resources目录下
7.Spring Boot整合-SpringMVC拦截器
目标:可以在Spring Boot项目中配置自定义SpringMVC拦截器
分析:
- 编写拦截器(实现HandlerInterceptor);
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("这是MyInterceptor中的preHandle方法");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.debug("这是MyInterceptor中的postHandle方法");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.debug("这是MyInterceptor中的afterCompletion方法");
}
}
- 编写配置类实现 WebMvcConfigurer,在该类中添加各种组件;
package com.itheima.config;
import com.itheima.interceptor.MyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
//注册拦截器
@Bean
public MyInterceptor myInterceptor(){
return new MyInterceptor();
}
//添加拦截器到spring mvc拦截器链
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor()).addPathPatterns("/*");
}
}
- 测试
10. Spring Boot整合-事务和连接池
目标:配置Spring Boot自带默认的hikari数据库连接池和使用@Transactional注解进行事务配置
分析:
-
事务配置
- 添加事务相关的启动器依赖,mysql相关依赖;
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <dependency> <!--springboot整合处理jdbc事务--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId>
-
数据库连接池hikari配置
只需要在application配置文件中指定数据库相关参数
小结:
- 事务配置;只需要添加jdbc启动器依赖
- 数据库连接池使用默认的hikari,在配置文件中配置如下:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/springboot_test
username: root
password: root
11. Spring Boot整合-Mybatis
目标:配置Mybatis在Spring Boot工程中的整合包,设置mybatis的实体类别名,输出执行sql语句配置项
分析:
- 添加启动器依赖;
- 配置Mybatis:实体类别名包,日志,映射文件等;
- 配置MapperScan
小结:
-
添加mybatis官方对于spring boot的一个启动器
<!--mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency>
-
配置mybatis
mybatis: # 实体类别名包路径 type-aliases-package: com.itheima.pojo # 映射文件路径 # mapper-locations: classpath:mappers/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-
设置启动器类中的mapper扫描
12. Spring Boot整合-通用Mapper
目标:配置通用Mapper组件到Spring Boot项目中并使用Mapper接口
分析:
通用Mapper:可以实现自动拼接sql语句;所有的mapper都不需要编写任何方法也就是不用编写sql语句。可以提高开发效率。
- 添加启动器依赖;
<dependency>
<!-- 通用mapper-->
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
- 改造UserMapper继承Mapper;
package com.cheung.mapper;
import com.cheung.pojo.User;
import tk.mybatis.mapper.common.Mapper;
//@Mapper // 可以不进行添加直接在springbootApplication上添加@MapperScan()注解
public interface UserMapper extends Mapper<User> {
}
- 修改启动引导类Application中的Mapper扫描注解;
package com.cheung.service;
import com.cheung.mapper.UserMapper;
import com.cheung.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id){
//根据id查询
return userMapper.selectByPrimaryKey(id);
}
public void saveUser(User user){
// 新增用户
System.out.println("新增用户...");
userMapper.insertSelective(user);
}
}
- 修改User实体类添加jpa注解;(import javax.persistence.**)
package com.cheung.pojo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Data//自动提供getter和setter、hashCode、equals、toString等方法
@Slf4j //自动在bean中提供log变量,其实用的是slf4j的日志功能
@Table(name = "tb_user")
public class User {
@Id
@KeySql(useGeneratedKeys = true)//开启主键自动回填
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
// 性别 1男性 2女性
private Integer sex;
private Date birthday;
private String note;
private Date Created;
private Date updated;
}
- 改造UserService实现业务功能;
小结:
在启动引导类上面的mapper扫描注解 一定要修改为 通用mapper的扫描注解
13. Spring Boot整合测试
目标:可以访问处理器对应路径将数据库中的数据根据id查询
分析:
- 改造HelloController,注入UserService利用其方法实现查询;
- 启动项目进行测试 http://localhost/user/用户id --> http://localhost/user/8
小结:
修改了HelloController:
@Autowired
private UserService userService;
/**
* 根据用户id查询用户
* @param id 用户id
* @return 用户
*/
@GetMapping("/user/{id}")
public User queryById(@PathVariable Long id){
return userService.queryById(id);
}
14. Spring Boot整合-Junit
目标:在Spring Boot项目中使用Junit进行单元测试UserService的方法
分析:
- 添加启动器依赖spring-boot-starter-test;
<!-- springboot进行单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
- 编写测试类
小结:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void queryById() {
User user = userService.queryById(8L);
System.out.println("user = " + user);
}
@Test
public void saveUser() {
User user = new User();
user.setUserName("test2");
user.setName("test2");
user.setAge(13);
user.setPassword("123456");
user.setSex(1);
user.setCreated(new Date());
userService.saveUser(user);
}
}
在Spring Boot项目中如果编写测试类则必须要在类上面添加@SpringBootTest
15. Spring Boot整合-redis
目标:在Spring Boot项目中使用Junit测试RedisTemplate的使用
分析:
- 添加启动器依赖;spring-boot-starter-data-redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置application.yml中修改redis的连接参数;(redis需要启动)
spring:
redis:
host: 10.211.55.*
port: 6379
- 编写测试类应用RedisTemplate操作redis中的5种数据类型(string/hash/list/set/sorted set)
小结:
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test(){
//string 字符串
//redisTemplate.opsForValue().set("str", "heima");
redisTemplate.boundValueOps("str").set("heima");
System.out.println("str = " + redisTemplate.opsForValue().get("str"));
//hash 散列
redisTemplate.boundHashOps("h_key").put("name", "heima");
redisTemplate.boundHashOps("h_key").put("age", 13);
//获取所有域
Set set = redisTemplate.boundHashOps("h_key").keys();
System.out.println(" hash散列的所有域:" + set);
//获取所有值
List list = redisTemplate.boundHashOps("h_key").values();
System.out.println(" hash散列的所有域的值:" + list);
//list 列表
redisTemplate.boundListOps("l_key").leftPush("c");
redisTemplate.boundListOps("l_key").leftPush("b");
redisTemplate.boundListOps("l_key").leftPush("a");
//获取全部元素
list = redisTemplate.boundListOps("l_key").range(0, -1);
System.out.println(" list列表中的所有元素:" + list);
// set 集合
redisTemplate.boundSetOps("s_key").add("a", "b", "c");
set = redisTemplate.boundSetOps("s_key").members();
System.out.println(" set集合中的所有元素:" + set);
// sorted set 有序集合
redisTemplate.boundZSetOps("z_key").add("a", 30);
redisTemplate.boundZSetOps("z_key").add("b", 20);
redisTemplate.boundZSetOps("z_key").add("c", 10);
set = redisTemplate.boundZSetOps("z_key").range(0, -1);
System.out.println(" zset有序集合中的所有元素:" + set);
}
}
16. Spring Boot项目部署
目标:将Spring Boot项目使用maven指令打成jar包并运行测试
分析:
- 需要添加打包组件将项目中的资源、配置、依赖包打到一个jar包中;可以使用maven的
package
; - 部署:java -jar 包名
小结:
-
添加打包组件
<build> <plugins> <!-- 打jar包时如果不配置该插件,打出来的jar包没有清单文件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
-
部署运行
java -jar 包名