1、spring boot 扫描不到自定义Controller
详见:spring boot 扫描不到自定义Controller - hanggle - 博客园
2、SpringBoot解决什么?
Spring应用开发时的两个痛点:
-
复杂的配置
项目各种配置其实是开发时的损耗, 因为在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,所以写配置挤占了写应用程序逻辑的时间。
-
一个混乱的依赖管理
项目的依赖管理也是件吃力不讨好的事情。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这难题实在太棘手。并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题毫无疑问会是生产力杀手。
而SpringBoot让这一切成为过去!Spring Boot 简化了基于Spring的应用开发,只需要“run”就能创建一个独立的、生产级别的Spring应用。Spring Boot为Spring平台及第三方库提供开箱即用的设置(提供默认设置,存放默认配置的包就是启动器starter),这样我们就可以简单的开始。多数Spring Boot应用只需要很少的Spring配置。
我们可以使用SpringBoot创建java应用,并使用java –jar 启动它,就能得到一个生产级别的web工程。
3、SpringBoot的特点
-
创建独立的Spring应用。
-
直接嵌入Web服务器,如tomcat、jetty、undertow等;不需要部署的war包。
-
提供固定的启动器依赖去简化组件配置;实现开箱即用(启动器starter其实就是Spring Boot提供的一个jar包),通过自己设置参数(.properties或.yml的配置文件),即可快速使用。
-
自动地配置Spring和其它有需要的第三方依赖。
-
提供了一些大型项目中常见的非功能性特性,如内嵌服务器、安全、指标,健康检测、外部化配置等。
-
绝对没有代码生成,也无需 XML 配置。
4、SpringBoot 的项目需要继承哪个parent?
spring-boot-starter-parent
5、spring-boot-starter-parent 的作用是?
maven的spring-boot-starter-parent的作用_码上敲享录
6、 SpringBoot应用启动类上必须加什么注解?
@SpringBootApplication
7、SpringBoot应用启动后,内嵌tomcat的端口号默认是多少?
8080
8、为什么我们的 Controller 不需要配置包扫描?
@SpringBootApplication已经有默认的包扫描【默认为启动类的包名】,这样同级或下级都可扫描。
9、热部署的作用
改了代码自动重启。
10、Spring Boot启动器的作用
-
配置一个启动器它会把整合这个框架或模块的依赖全部导入。
-
每一个启动器都有一个自动配置类,实现自动整合Spring。
-
每一个启动器都有一个配置属性类,提供了默认整合的属性配置。
11、Spring Boot启动器
Spring Boot应用启动器 - 别动我的猫 - 博客园
12、@SpringBootConfiguration注解
声明当前类是 SpringBoot应用的配置类,项目中只能有一个。
13、@EnableAutoConfiguration注解
启用自动配置 ,注解@EnableAutoConfiguration
,告诉SpringBoot基于你所添加的依赖,去“猜测”你想要如何配置Spring。比如我们引入了spring-boot-starter-web
,而这个启动器中帮我们添加了tomcat
、SpringMVC
的依赖。此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!
-
Spring Boot提供了很多启动器,都进行了默认配置,这些配置是否生效,取决于我们是否导入了对应的启动器依赖,如果有那么默认配置就会生效。
-
所以,我们使用SpringBoot构建一个项目,只需要导入启动器依赖,配置就可以交给Spring Boot自动处理。除非你不希望使用Spring Boot的默认配置,它也提供了自定义配置的入口。
14、@ComponentScan注解
配置组件扫描的指令。提供了类似与<context:component-scan>
标签的作用
通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包
我们的@SpringBootApplication注解是加在启动类上,因此扫描的包是该类所在包及其子包。因此,一般启动类会放在最外层包目录中。
15、@ConfigurationProperties
@ConfigurationProperties 注解使用姿势,这一篇就够了 - 纪莫 - 博客园
16、Spring Boot自动配置原理
-
SpringApplication会寻找 META-INF/spring.factories 文件,读取其中以EnableAutoConfiguration 为key的所有类的名称, 这些类就是提前写好的自动配置类。
-
这些类都声明了@Configuration注解,并且通过@Bean注解提前配置了我们所需要的一切实例,完成自动配置。
-
这些配置类不一定全部生效,因为有@ConditionalOn注解,满足一定条件才会生效。(类存在条件)
-
相关的类要存在,我们只需要导入了相关依赖(启动器),依赖有了条件成立,自动配置生效。
-
如果我们自己配置了相关Bean,那么会覆盖默认的自动配置的Bean。
-
我们可以通过配置application.yml或application.properties文件,来覆盖自动配置中的属性。
17、Spring Boot开发两个重点
-
找Spring Boot提供的starter启动器。
-
配置属性覆盖starter启动器中自动配置类的默认属性。
18、properties配置
# 设置tomcat端口号
server.port=9001
# 设置项目的访问路径
server.servlet.context-path=/
19、Spring Boot访问配置文件的三种方式
第一种:注入属性@ConfigurationProperties(prefix = "my") 尽量指定前缀,避免冲突。 所有需要注入的属性,都必须提供setter方法
第二种:@Value注解的属性,不需要提供setter方法,@Value只能注入: 基本数据类型与String
@Value("${my.host}")
private String host;
第三种:将需要注入的属性定义成一个属性类,可以重复使用。(@ConfigurationProperties实现注入属性),当需要用的时候,需要创建该属性类的对象。(@EnableConfigurationProperties实现bean创建)
@RestController
@EnableConfigurationProperties(UserProperties.class)
public class PropController3 {
@Autowired(required = false)
private UserProperties userProperties;
@GetMapping("/test3")
public String test3(){
System.out.println("======test3======");
System.out.println(userProperties.getHost());
System.out.println(userProperties.getPort());
System.out.println(userProperties.getUser());
System.out.println(userProperties.getAddress());
System.out.println(userProperties.getUsers());
return "test3方法,访问成功!";
}
}
19、Spring boot整合lombok
第一步: 在idea中安装lombok插件(已安装跳过此步)
-
第二步: 引入lombok依赖
<!-- 引入lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency>
-
第三步: lombok注解介绍
-
@Data: 自动生成getter、setter、hashCode、equals、toString方法
-
@AllArgsConstructor: 自动生成全参构建器
-
@NoArgsConstructor: 自动生成无参构建器
-
@Setter: 自动生成setter方法
-
@Getter: 自动生成getter方法
-
@EqualsAndHashCode: 自动生成equals、hashCode方法
-
@ToString: 自动生成toString方法
-
@Slf4j: 自动在bean中提供log变量,其实用的是slf4j的日志功能。
-
@NonNull: 这个注解可以用在成员方法或者构造方法的参数前面,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常。
-
-
第四步: 在实体类上加注解
package cn.itcast.pojo; import lombok.*; @ToString // toString @Data // getter、setter、toString、equals、hashCode @AllArgsConstructor // 全参构造器 @NoArgsConstructor // 无参构造器 public class User { private String name; private int age; private String sex; }
20、SpringBoot:整合SpringMVC
20.1 日志控制
# 配置日志 logging: level: cn.itcast: debug org.springframework: debug
说明:
-
logging.level: 是固定写法,说明下面是日志级别配置,日志相关其它配置也可以使用。
-
cn.itcast、org.springframework: 是指定包名,后面的配置仅对这个包有效。
-
debug: 日志的级别
控制器中加入日志:
package cn.itcast.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j // 日志注解
public class LogController {
@GetMapping("/log")
public String log(){
log.debug("====debug====");
log.info("====info====");
log.warn("====warn====");
log.error("====error====");
return "log....";
}
}
20.2 拦截器、跨域WebMvcConfigurerAdapter详解
SpringBoot——》WebMvcConfigurerAdapter详解_小仙。的博客-CSDN博客_webmvcconfigureradapter
21、配置连接池
application.yml文件中配置连接池
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot_db
username: root
password: root
22、SpringBoot:整合Mybatis
-
引入mybatis启动器依赖
<!-- 配置mybatis启动器 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency>
-
配置mybatis相关属性
mybatis:
# 配置类型别名包扫描
type-aliases-package: cn.itcast.springboot.pojo
# sql语句映射文件路径
mapper-locations:
- classpath:mappers/*.xml
# 驼峰映射
configuration:
map-underscore-to-camel-case: true
# 配置日志
logging:
level:
cn.itcast: debug
用户实体(User)
package cn.itcast.springboot.pojo;
import lombok.Data;
import java.util.Date;
@Data
public class User{
// 用户id
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
// 性别 1: 男 2: 女
private Short sex;
// 出生日期
private Date birthday;
// 备注
private String note;
// 创建时间
private Date created;
// 修改时间
private Date updated;
}
数据访问接口(UserMapper)
方式一 (@Mapper注解)
package cn.itcast.springboot.mapper;
import cn.itcast.springboot.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper // 声明数据访问接口,产生代理对象
public interface UserMapper {
// 查询全部用户
List<User> findAll();
}
方式二 (@MapperScan注解)【推荐】
package cn.itcast.springboot.mapper;
import cn.itcast.springboot.pojo.User;
import java.util.List;
public interface UserMapper {
// 查询全部用户
List<User> findAll();
}
在启动类上添加数据访问接口包扫描:
package cn.itcast.springboot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/** 启动类 */
@SpringBootApplication
// 数据访问接口包扫描
@MapperScan(basePackages = {"cn.itcast.springboot.mapper"})
public class HighApplication {
public static void main(String[] args){
// 运行spring应用
SpringApplication.run(HighApplication.class, args);
}
}
说明: 这种方式的好处是,不用给每一个Mapper都添加注解。采用@MapperScan包扫描方式只需要添加一次注解。
定义SQL语句(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="cn.itcast.springboot.mapper.UserMapper">
<select id="findAll" resultType="User">
SELECT * FROM tb_user
</select>
</mapper>
业务层 (UserService)
package cn.itcast.springboot.service;
import cn.itcast.springboot.mapper.UserMapper;
import cn.itcast.springboot.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class UserService {
@Autowired(required = false)
private UserMapper userMapper;
// 查询全部用户
public List<User> findAll(){
return userMapper.findAll();
}
}
控制器 (UserController)
package cn.itcast.springboot.controller;
import cn.itcast.springboot.pojo.User;
import cn.itcast.springboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
private UserService userService;
// 查询全部用户
@GetMapping("/findAll")
public List<User> findAll(){
return userService.findAll();
}
}
22、SpringBoot:整合通用mapper
通用Mapper简化了表的CRUD,对于单表CRUD,不用写SQL语句,完全面向对象方式操作数据库,通用Mapper的作者也为自己的插件编写了Spring Boot启动器。
引入通用Mapper启动器依赖
<!-- 配置通用Mapper启动器 --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.5</version> </dependency>
注意: 引入了通用Mapper的启动器,它已包含了Mybatis官方启动器的功能,因此需要删除对官方Mybatis启动器的依赖。
在实体类上加JPA注解 (User)
package cn.itcast.springboot.pojo;
import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Data
@Table(name = "tb_user")
public class User{
// 用户id
@Id // 主键
@KeySql(useGeneratedKeys = true) // 开启自增主键返回功能
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
// 性别 1: 男 2: 女
private Short sex;
// 出生日期
private Date birthday;
// 备注
private String note;
// 创建时间
private Date created;
// 修改时间
private Date updated;
}
数据访问接口需要继承Mapper接口 (UserMapper)
package cn.itcast.springboot.mapper;
import cn.itcast.springboot.pojo.User;
import tk.mybatis.mapper.common.Mapper;
//@Mapper // 声明数据访问接口,产生代理对象
public interface UserMapper extends Mapper<User> {
}
修改业务层 (UserService)
@Service @Transactional public class UserService { @Autowired(required = false) private UserMapper userMapper; // 查询全部用户 public List<User> findAll(){ return userMapper.selectAll(); } }
修改启动类(@MapperScan注解修改为通用Mapper中的)
package cn.itcast.springboot;
import tk.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/** 启动类 */
@SpringBootApplication
// 数据访问接口包扫描
@MapperScan(basePackages = {"cn.itcast.springboot.mapper"})
public class HighApplication {
public static void main(String[] args){
// 运行spring应用
SpringApplication.run(HighApplication.class, args);
}
}
23、SpringBoot:整合Junit
引入test启动器依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
编写测试类 (UserServiceTest)
package cn.itcast.springboot;
import cn.itcast.springboot.pojo.User;
import cn.itcast.springboot.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
// 运行主类
@RunWith(SpringRunner.class)
// 如果测试类在启动类的同级目录或者子目录下可以省略指定启动类
//@SpringBootTest(classes = {HighApplication.class})
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void findAll(){
List<User> users = userService.findAll();
System.out.println(users);
}
}
-
引入spring-boot-starter-test启动器
-
测试类需要到的两个注解:
-
@RunWith(SpringRunner.class) // 运行主类
-
@SpringBootTest // 指定启动类
-
24、SpringBoot:整合Redis
引入Redis启动器依赖
<!-- 配置redis启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置Redis连接属性
-
# 配置Redis spring: redis: host: localhost # 主机 port: 6379 # 端口
-
注入RedisTemplate操作Redis
package cn.itcast.springboot;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void redisTest(){
// 设置值
redisTemplate.opsForValue().set("name", "admin");
// 获取值
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name = " + name);
// 删除值
redisTemplate.delete("name");
}
}
-
引入spring-boot-starter-data-redis启动器
-
配置属性: spring.redis.host 与 spring.redis.port
-
注入RedisTemplate操作Redis数据库
25、SpringBoot:项目打包部署
25.1 打成Jar包
第一步: 引入Spring Boot打包插件
<build>
<plugins>
<!-- 配置spring-boot的maven插件
1. 用它可以运行spring-boot项目
2. 需要用它构建打jar、war资料
-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
第二步: 执行命令
# 清理、打包
mvn clean package
# 清理、打包 跳过测试
mvn clean package -Dmaven.test.skip=true
第三步: 运行
java -jar xxx.jar
第四步: 浏览器访问 http://localhost:8080/findAll
25.2 达成war包
第一步: 修改pom.xml
<!-- 打包方式(默认为jar) -->
<packaging>war</packaging>
第二步: 排除springboot自带的tomcat
<!-- 配置Web启动器(集成SpringMVC、内嵌tomcat、Jackson) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--
配置tomcat启动器,就会排除spring-boot-starter-web中依赖过来的tomcat启动器
指定scope为provided: 代表打war包时,不需要它的依赖jar包(我们有自己的tomcat)
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
注意: spring-boot-starter-tomcat 是原来被传递过来的依赖,默认会打到包里,所以我们需要配置tomcat启动器,这样就会排除spring-boot-starter-web中依赖过来的tomcat启动器,并指定依赖范围为provided,这样tomcat相关的jar就不会打包到war里了。
目的: 我们用自己tomcat,不用它内嵌的tomcat,这样内嵌的tomcat相关jar包就不需要。
第三步: 自定义Web应用入口类继承SpringBootServletInitializer(相当于web.xml)
package cn.itcast.springboot;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/** web应用入口 */
public class WebServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 设置启动类
builder.sources(HighApplication.class);
// 返回spring应用构建对象
return builder;
}
}
第四步: 在pom.xml修改工程的名称为ROOT
<build>
<!-- 指定最终打成war的项目名称 -->
<finalName>ROOT</finalName>
</build>
说明: ROOT是tomcat的默认工程名,也是唯一一个不需要加工程访问的目录,所以我们打包的时候用finalName指定的名字打包就直接生成的WAR包就是ROOT.war
第五步: 部署项目ROOT.war
-
安装JDK1.8环境
-
安装Tomcat 把 ROOT.war部署到webapps下即可
-
启动Tomcat,
bin/startup.bat
即可,会自动解压ROOT.war