目录
3.springboot自动装配读取的文件是哪个?原理是什么?
1.什么是SpringBoot?
本质是通过“约定大于配置”对spring进一步的封装。
2.如何快速创建一个SpringBoot的web项目?
在创建springboot项目时勾选“Spring Web”,即可快速创建springboot的web项目。
如果前期未在这里勾选,也可以在pom文件中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
然后新建一个类,输入如下代码:
@RestController
public class HelloWorld {
@GetMapping("/sayHello")
public String sayHello(){
return "你好,世界";
}
}
启动项目,我们能从启动日志上看到,我们的项目端口是8080,没有上下文路径,所以我们直接访问:http://localhost:8080/sayHello
能看到页面是直接返回,即成功。
这里我们看到默认启动端口是8080,怎么修改端口号呢,可以在application.properties里面修改端口号,添加
server.port=8088
即可修改项目的端口号,这就是“约定大于配置”的思想,不需要再写繁杂的xml配置文件,只要约定好在哪里需要写上什么就可以轻松修改。
3.springboot自动装配读取的文件是哪个?原理是什么?
自动装配读取的是META-INF包下的spring.factories文件里的内容,本质是结合是否存在类的注解,最后获取到类的全路径,然后再通过反射去创建对象。
4.yml的书写注意点以及配置优先级
配置文件可以写成yml或者yaml结尾得文件,使用的时候需要注意空格。如下是一个简单的例子:
如果项目中同时写了application.properties和application.yml,则application.properties中的同名属性会生效,也就是说application.properties的优先级更高。
5.springboot中的赋值操作
可以使用@ConfigurationProperties(prefix = "xxx")的注解实现,以下是一个自动赋值student对象的例子:
首先定义两个类,Dog和Student
@Data
public class Dog {
private String name;
private Integer age;
}
@Component
@ConfigurationProperties(prefix = "student")
@Data
public class Student {
private String name;
private Integer age;
private Map<String, Object> maps;
private List<Object> list;
private Dog dog;
}
在application.yml文件中编写好对应的值
student:
name: duolaimi
age: 20
maps: {k1: v1, k2: v2}
list:
- code
- music
dog:
name: 旺财
age: 3
最关键的是定义的类上加上了@ConfigurationProperties(prefix = "xxx")注解,并且prefix与yml定义的前面的值相同,如果都为student,即对应上了。
运行test文件,发现能自动赋值。
总结:需要配置多个值时,可以使用yml配置加上@ConfigurationProperties注解的方式,一次性赋值。
如果只是单个值赋值或者少量值赋值,则可以用@Value加上spel,如下所示
@Component
@Data
public class Dog {
@Value("${dogname}")
private String name;
@Value("${dogage}")
private Integer age;
}
这样也能正常赋值。
还能使用Environment接口,能将配置文件中的所有属性赋值到一个对象中,使用时加@Autowired,类似map,直接调用getProperty()方法传入要查的key即可。
6.JSR303的使用
什么是JSR303?简单来说,它是一个通过注解就能约束数据的工具
使用的话,只需在类上加上@Validated注解,然后在对应的属性上添加校验规则即可。比如:
@Component
@ConfigurationProperties(prefix = "student")
@Validated
@Data
public class Student {
@NotNull(message = "学生姓名不能为空")
private String name;
private Integer age;
private Map<String, Object> maps;
private List<Object> list;
private Dog dog;
}
注意:如果是通过@ConfigurationProperties赋值的对象,必须是从yml文件中才能正常获取,如果是读取的application.properties文件中的值,则无法进行校验。
7.SpringBoot配置文件的存放目录
我们可以查看官方文档知道,存放目录可以有四个:
经测试,同名配置的加载优先级是:
file:./config/
file:./
classpath:/config/
classpath:/
也就是官方文档中的顺序
8.环境配置隔离
如果我们使用的是properties文件,我们可以定义如下格式的文件:
然后在application.properties文件中通过spring.profiles.active=xxx(-后面的值)来指定生效的环境
如果我们使用的是yml文件,可以在一个文件中就做好环境配置隔离
如下代码所示:
spring:
profiles:
active: dev
---
server:
port: 8081
spring:
profiles: dev
---
server:
port: 8082
spring:
profiles: test
只需通过三个-即可分割环境,其中spring: profiles指定环境名称,上面的spring: profiles: active指定生效的环境
9.通过pom坐标导入静态资源方式
比如我们可以在webjars找到静态资源坐标:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
重启项目,即可正常访问静态资源
原理是什么呢?
我们查看WebMvcAutoConfiguration源码发现,它是把webjar下的目录放入到资源路径了
10.静态资源存放路径
查看源码可知,默认的静态资源存放路径是这四个,并且加载的优先级也是按照此顺序加载。
11.如何自定义webmvc的配置类
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public ViewResolver myViewResolver(){
return new MyViewResolver();
}
// 自己定义了一个视图解析器
public static class MyViewResolver implements ViewResolver{
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
}
新建一个配置类,加上@Configuration声明这是一个配置类,新建一个类实现ViewResolver,将改实现类返回并注册到bean中去。注意,@EnableWebMvc这个注解不能加,加上后会导致springboot的自动装配失效。
这里为什么加上@EnableWebMvc这个注解就会失效自动装配呢,因为webmvc自动装配的类上写着@ConditionalOnMissingBean(WebMvcConfigurationSupport.class),也就是说只有不存在WebMvcConfigurationSupport这个类才会进行自动装配,然而@EnableWebMvc简介导入了WebMvcConfigurationSupport这个类,所以会导致自动装配失效。
12.引导类解析
引导类中默认返回的对象就是spring容器:
@SpringBootApplication
public class SpringbootQuickstartApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootQuickstartApplication.class, args);
BookController bean = context.getBean(BookController.class);
System.out.println(bean);
}
}
我们可以使用该容器对象获取bean。
查看@SpringBootApplication注解源码发现,其实最终也是一个@Configuration配置类,就相当于spring核心配置类,或是以前的xml。
13.配置文件未被识别时应该怎么加回去
点击项目结构,选中Facets,选择自己的项目,点击右上角绿叶标志,在弹出的框中添加未被识别的配置文件即可。
14.yaml文件中变量的引用
使用${属性名}的方式引用变量。
15.SpringBoot整合MyBatis
添加mabatis整合springboot坐标和mysql坐标,在配置文件中添加数据库信息,在dao接口上添加@Mapper,通过注解方式进行增删改查即可
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/duolaimi
username: root
password: root
mybatis:
configuration:
map-underscore-to-camel-case: true
@Mapper
public interface CarDao {
@Select("select * from t_car where id = #{id}")
Car getById(Long id);
}
16.SpringBoot整合MyBatisPlus
先引入mp的坐标:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
dao接口继承BaseMapper<>,并传入实体泛型即可,BaseMapper里默认已经实现了基本方法。
@Mapper
public interface CarDao extends BaseMapper<Car> {
}
mp的相关配置:除了数据库连接信息,还需要指定表前缀
mybatis-plus:
global-config:
db-config:
table-prefix: t_
mp中的主键策略是雪花算法assign_id,如果需要设置为自增策略则id_type改为auto。
开启日志:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
分页操作:
需要开启mp的拦截器进行分页操作,默认没有开启。(注意:不同版本的MP的分页不一样)
高版本:
@Configuration
public class MPConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
低版本:
@Configuration
public class MyBatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
开启后传入Page对象即可:
@Test
void testPage(){
IPage page = new Page(1,5);
IPage page1 = carDao.selectPage(page, null);
System.out.println(page1);
}
如何使用mp提供的service?
自己定义接口继承IService,并指定泛型,然后创建该接口的实现类,继承ServiceImpl类,并指定泛型,第一个泛型为Dao的接口,第二个泛型为实体类。
public interface ICarService extends IService<Car> {
}
@Service
public class CarServiceImpl extends ServiceImpl<CarDao, Car> implements ICarService {
}
17.SpringBoot整合Druid
先要添加druid的starter坐标:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.20</version>
</dependency>
在配置文件中指定druid数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/duolaimi
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
或者
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/duolaimi
username: root
password: root
建议使用下面的方式
18.自定义全局异常拦截器
使用@RestControllerAdvice或者@ControllerAdvice配合@ExceptionHandler注解声明这是一个全局异常处理类,拦截所有的异常信息。(注意,这里需要打印异常信息)
@RestControllerAdvice
public class ProjectExceptionAdvice {
// 拦截所有的异常信息
@ExceptionHandler
public R doException(Exception e){
e.printStackTrace();
return new R(false, null, "服务器故障,请稍后再试!");
}
}
19.maven打包插件
pom文件中需要引入这个依赖,打包出来的jar包才是正常的,后面使用java -jar命令才会正常,否则就会出现问题。不使用这个插件的话,打出来的文件结构和目录会不同。
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
20.命令行启动常见问题及解决方案
1.Windows端口被占用
21.Linux环境后台启动jar包
在原先的java -jar Xxx.jar命令前面加上nohup命令,表示后台启动,后面需要指定日志输出的位置
完整的后面还需要加上2>&1 &
22.启动时设置临时属性
在项目启动命令后可以添加--server.port=8080之类的。需要修改多个临时属性时,中间使用空格分割。
23.多环境分组管理
在配置文件中可以使用include将不同的配置文件加载进来
或者使用group属性:
24.maven与SpringBoot多环境兼容
在pom文件中设置profiles-profile->等,具体如下:
然后在配置文件中通过两个@来引用配置值,如:
25.设置日志文件
可以指定日志文件的名称,格式,以及到达多少大小后再生成一个。
26.原理篇
1.自动配置原理
设计思想:
1.收集Spring开发者的编程习惯,整合开发过程使用的常用技术列表-->(技术集A)
2.收集常用技术(技术集A)的使用参数,整理开发过程中每个技术的常用设置列表-->(设置集B)
3.初始化SpringBoot基础环境,加载用户自定义的bean和导入其他坐标,形成初始化环境
4.将技术集A包含的所有技术都定义出来,在Spring/SpringBoor启动时默认全部加载
5.将技术集A中具有使用条件的技术约定出来,设置成按条件加载,由开发者决定是否使用该技术(与初始化环境比对)
6.将设置集B作为默认配置加载(约定大于配置),减少开发者配置工作量
7.开放设置集B的配置覆盖接口,由开发者根据自身需要决定是否覆盖默认配置。