1. Spring面试基础

1.1 Spring框架概念及其相关组件

1.1.1 Spring是什么

Spring是一个开源框架,Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
轻量级:与EJB对比,依赖资源少,消耗的资源少。
分层: 一站式,每一个层都提供的解决方案

1.1.2 Spring相关组件:

  1. Spring Core: 核心类库,提供IOC服务;
  2. Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
  3. Spring AOP:AOP服务;
  4. Spring DAO:对JDBC的抽象,简化了数据访问异常的处理;
  5. Spring ORM:对现有的ORM框架的支持;
  6. Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传;
  7. Spring MVC:提供面向Web应用的Model-View-Controller实现。

1.2 什么是IOC和DI

1.2.1 IOC

IOC就是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到Spring容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。DI依赖注入,和控制反转是同一个概念的不同角度的描述,即 应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。

1.2.2 DI

DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

1.3 SpringBean的配置方式

  • 基于XML配置
  • 基于注解的配置(@Component、@Repository、@Controller @Service)
  • 基于Java类+配置注解的方式(@Configuration @Bean)

1.4 IOC容器Bean的常见属性

id标签是bean的唯一标识,IoC容器中bean的id标签不能重复,否则报错。

name是bean的别名,可以定义多个

class属性是bean常用属性,为bean的全限定类名,指向classpath下类定义所在位置

factory-method属性factory-method工厂方法属性,通过该属性,我们可以调用一个指定的静态工厂方法,创建bean实例。

scope属性 bean的作用范围(singleton — 单例, prototype — 多例)

init-method和destory-method属性 Bean的初始化和销毁时执行的方法

autowire属性 表示bean的自动装配方式 可选值: no:默认,不进行自动装配 .byName .byType

1.5 IOC容器Bean的作用域

singleton:表示整个IOC容器共享一个Bean,也就是说每次说每次通过getBean获取的bean都是同一个。

prototype:每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。

request:每次HTTP请求将会生成各自的bean实例

session:每次会话请求对应一个bean实例

global-session:全局作用域

* singletonprototype经常使用,其他的很少使用。

1.6 IOC依赖注入方式

  1. ● 构造器注入: <constructor-arg> 标签
  2. ● setter方法注入: <property name = "xxxx" value = "xxx"></property>
  3. ● 根据注解注入: @Autowired, @Resource

1.7 IOC容器中重要的类

IOC容器的顶级接口 BeanFactory , 仅提供了最基本的容器方法

ApplicationContext接口 则扩展了 BeanFactory ,提供了很多功能,使我们常用的容器

BeanFacotry的实现类 XmlBeanFactory

ApplicationContext的实现类:

  • ClassPathXmlApplicationContext:可以加载类路径下的配置文件,实现容器的实例化。
  • FileSystemXmlApplicationContext:可以加载磁盘任意路径下的配置文件,实现容器的实例化。(必须有访问权限)
  • AnnotationConfigApplicationContext :扫描配置注解,根据注解配置实现容器的实例化。

1.8 Spring常用注解

@ComponentScan 组件扫描, 会扫描指定包下的 @Component @Controller @Service @Repository
@Controller 标注当前类为容器的对象,代表控制组件
@Service 标注当前类为容器的对象,代表服务组件
@Repository 标注当前类为容器的对象,代表持久组件
@Component 标注当前类为容器的对象,代表组件
@Autowired 自动装配注解 默认按类型装配
@Transactional 事务注解
@Value 将配置文件中的值,注入到指定字段
@Bean 配置bean对象 标签作用一致
@Configuration 标注当前的java类是一个配置类

1.9 Autowired和Resource注解区别

  1. @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。

  2. @Autowired默认按类型装配(这个注解是属于spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以搭配@Qualifier注解进行使用

  3. @Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

2. Spring面试重点

2.1 IOC容器初始化流程

  1. 创建配置
    (1) 基于xml 或 基于注解 配置Spring Bean
  2. 配置解析
    (1) 读取xml内容,并得到一个Document对象

(2) 解析Document对象,遍历bean标签的节点
(3) 将每一个Bean标签封装成一个BeanDefinition对象

  1. 注册bean定义到容器中
    (1) 将bean的定义对象 存储到容器中的map集合中

(2) map集合: 在容器的核心实现类 DefaultListableBeanFactory中, ConcurrentHashMap
(3) 以 bean标签中配置的id作为key
(4) 以 beanDefinition对象作为value存储到map集合中

  1. 初始化所有单例对象
    (1) 完成注册后,查看所有注册bean定义

(2) 如果是非抽象 、 并且不是懒加载的单例对象会被立刻创建
(3) 创建出来的单例对象会存储到singletonObjects map集合中 也是一个ConcurrentHashMap

2.2 IOC容器getBean流程

  1. 判断单例map集合中 是否已经创建该对象
    >有,返回
    >无,下一流程
  2. 判断是否存在父容器,且父容器是否包含该对象
    >包含,返回
    >不包含,下一流程
  3. 准备尝试创建对象,beanDefinitionMap中获取bean定义
    >无定义,抛出NoSuchBeanDefinition异常
    >有定义,下一流程
  4. 判断bean定义的scope属性
    >单例 (1) 调用createBean创建对象 (2) 加入单例map集合
    >多例 调用createBean创建对象
    >其他
  5. createBean创建对象
    (1) 获取要创建bean的class
    (2) 判断是否使用工厂方法创建对象
    是 —-> 调用工厂方法创建对象
    否 —-> 使用构造器创建
    (1) 根据构造器参数的个数、类型

    (2) 确定到底使用哪个构造器创建
    (3) 使用JDK反射方法创建对象

  6. 依赖注入 —-> 调用populateBean方法进行依赖注入

2.3 SpringBean的循环依赖和覆盖问题

2.3.1 循环依赖

多例 : 对象都是多例对象,会报循环依赖异常

单例:

  • 如果是构造器依赖的属性,会报循环依赖异常
  • 如果是通过属性依赖产生的循环依赖,默认允许循环依赖 (通过Spring的三级缓存解决)
  • 设置allowCircularReferences为false会报循环依赖异常

2.4 Spring管理Bean的生命周期

  1. bean对象的实例化
  2. 封装属性,也就是设置properties中的属性值
  3. 如果bean实现了BeanNameAware,则执行setBeanName方法,也就是bean中的id值
  4. 如果实现BeanFactoryAware或者ApplicationContextAware ,需要设置setBeanFactory或者上下文对象setApplicationContext
  5. 如果存在类实现BeanPostProcessor后处理bean,执行postProcessBeforeInitialization,可以在初始化之前执行一些方法
  6. 如果bean实现了InitializingBean,则执行afterPropertiesSet,执行属性设置之后的操作
  7. 调用执行指定的初始化方法
  8. 如果存在类实现BeanPostProcessor则执行postProcessAfterInitialization,执行初始化之后的操作
  9. 执行自身的业务方法
  10. 如果bean实现了DisposableBean,则执行spring的的销毁方法
  11. 调用执行自定义的销毁方法。

    2.5 SpringAOP面试点

    2.5.1 谈谈你对AOP的理解

  • Aspect Orieted Programming ,中文叫“面向切面编程”或“面向方面编程”

  • 是一种编程模式,将分布在多个类中的功能封装到一个类中,这些功能称为cross-cutting concerns(横切关注点),如日志、事务、缓存权限、安全等

  • 不是替代OOP,而是对其的补充

    2.5.2 项目中AOP的实际应用场景

  • 事务

  • 权限
  • 异常
  • 用户行为日志
  • 性能监控
  • 缓存等

    2.5.3 AOP的具体使用方式

  1. 定义切面类 我们使用注解的方式 @Aspect @Component
  2. 定义切入点表达式 可以通过 扫描包的方式 也 可以通过指定注解的方式
  3. 定义通知: 通知分5种 前置、后置、异常、最终、环绕通知

    2.5.4 例: 以用户行为日志举例AOP的使用

  4. 日志效果
    image.png

  5. 定义日志注解,在需要记录日志的方法中加上注解
    ~MRMWA49YX]I6@X0E%{L_OH.png
    VHN)8$O)EU3I]BO0CX{BB}N.png
  6. 引入AOP依赖
    5PZK4
  7. 定义切面及切入点
    EO}5R]66XKKZLON8URYTC]D.png
  8. 定义环绕通知,记录日志内容
    ![)G(TFZDF81OBAG[TN~~}[B.png](https://cdn.nlark.com/yuque/0/2022/png/26104240/1644409139139-031da636-3447-4fb6-a964-8a5778040290.png#clientId=u596893f3-152f-4&crop=0&crop=0&crop=1&crop=1&from=ui&height=363&id=u35a9a95f&margin=%5Bobject%20Object%5D&name=%29G%28TFZDF81OBAG%5BTN~~%7D%5BB.png&originHeight=685&originWidth=1182&originalType=binary&ratio=1&rotation=0&showTitle=false&size=95000&status=done&style=none&taskId=u4fcdf188-5180-4588-aefd-cebfd03f8b5&title=&width=627)

—-> ThreadLocal获取当前登录用户信息
—-> 将日志行为信息保存数据库

2.5.5 例: 基于AOP实现读写分离数据源动态处理

  1. 配置读写两个数据源
    WKY5XI2PS}LRQHI%A9GWETW.png

  2. 使用AOP根据方法名,动态选择数据源
    QK98N]H}]HL{4HLB90Q)@31.png

    2.5.6 AOP的工作原理

  • AOP的底层的工作原理 就是使用动态代理对目标业务进行增强
  • 而动态代理主要有JDK 和 CGLIB两种动态代理实现
  • JDK是自带的的动态代理实现,要求被代理的类必须实现接口
  • CGLIB是开源的动态代理实现,需要引入依赖,要求被代理的类必须可以被继承

2.6 Spring事务面试点

2.6.1 Spring事务的配置方式

  1. 注解配置
  2. 基于AOP的tx标签配置

    2.6.2 Spring事务的隔离级别

  • Spring 默认使用数据库的隔离级别
  • ISOLATION_READ_UNCOMMITTED:读未提交
  • ISOLATION_READ_COMMITTED:读已提交
  • ISOLATION_REPEATABLE_READ:可重复读
  • ISOLATION_SERIALIZABLE:串行化

    2.6.3 Spring事务的失效场景

  1. 数据库引擎不支持事务(innoDB )
  2. 没有被Spring管理
  3. * 方法不是public的
  4. * 自身调用问题
  5. 数据源未配置事务管理
  6. 传播行为中设置了不支持事务
  7. * 异常被捕获掉
  8. * 异常类型错误, 默认捕获RuntimeException异常

    2.6.4 Spring事务的传播行为

    PROPAGATION_REQUIRED 表示当前方法必须在一个具有事务的 上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。( 如果被调用端发生异常,那 么调用端和被调用端事务都将回滚)

PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

PROPAGATION_SUPPORTS 表示当前方法不必需要具有一个事务 上下文,但是如果有一个事务的话,它也可以在这个事务中运行

PROPAGATION_MANDATORY 表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常

PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。

PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常

PROPAGATION_NESTED 表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中 ,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation. required的一样

2.7 Spring使用的设计模式

工厂模式: Spring中的FactoryBean就是典型的工厂方法模式。使用工厂模式创建对象的实例

单例模式:在Spring配置文件中定义的Bean默认为单例模式

模板方法:用来解决代码重复的问题,比如我们常使用的RestTemplate、JmsTemplate、JpaTemplate都是基于模板方法

代理模式: AOP的底层实现就是基于JDK动态代理 及 CGLIB动态代理

观察者模式: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 spring中Observer模式常用的地方是listener的实现。如ApplicationListener

适配器模式:AOP的方法拦截器中

策略模式:Spring中在实例化对象的时候用到Strategy模式

3. SpringMVC面试题

3.1 SpringMVC常用注解

@RequestMapping 指定请求资源路径
[
@ResponseBody ](/ResponseBody ) 注解表示将该方法的返回值 直接返回到客户端,一般我们返回的都是 json
[
@RequestBody ](/RequestBody ) 接收前台 json参数
[
@RequestParam ](/RequestParam ) 接收前台表单参数 key = value 形式参数 ? a=1 & b=2
[
@PathVariable ](/PathVariable ) 获取路径参数的 http:ip:port/user/{id}
@RestController 相当于 @ResponseBody @Controller 的合体
@ControllerAdvice controller的增强注解,用于统一处理功能:如统一异常处理
@ExceptionHandler 异常处理
@CookieValue 指定cookie中的参数
@RequestHeader 指定请求消息头中的参数

3.2 SpringMVC运行流程

  1. 用户发送请求至前端控制器DispatcherServlet;
  2. DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
  4. DispatcherServlet 调用 HandlerAdapter处理器适配器;
  5. HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
  6. Handler执行完成返回ModelAndView;
  7. HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
  8. DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
  9. ViewResolver解析后返回具体View;
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
  11. DispatcherServlet响应用户。

    3.3 Filter、Interceptor、Aop实现与区别

  • AOP使用的主要是动态代理 ,
  • 过滤器使用的主要是函数回调;
  • 拦截器使用是反射机制 。

  • 一个请求过来 ,先进行过滤器处理,看程序是否受理该请求 。 过滤器放过后 程序中的拦截器进行处理 ,处理完后进入 被 AOP动态代理重新编译过的主要业务类进行处理 。

  • Filter:和框架无关,可以控制最初的http请求,但是更细一点的类和方法控制不了。

  • Interceptor:可以控制请求的控制器和方法,但控制不了请求方法里的参数(用于处理页面提交的请求响应并进行处理,例如做国际化,做主题更换,过滤等)。

  • Aspect : 可以自定义切入的点,有方法的参数,但是拿不到http请求,可以通过其他方式如RequestContextHolder获得。

  • 都可以实现权限检查,日志记录。不同的是使用的范围不同,规范不同,深度不同。

    3.4 SpringMVC如何上传图片

  1. 依赖两个jar包 commons-io.jar 及 commons-fileupload.jar
  2. 首先在spring mvc的配置文件中配置 Mutipart解析器
  3. 然后前端上传图片的时候需要在form 表单上加上enctype=mutilpart-data
  4. 后台controller的接收方法中 使用spring的 MutilpartFile接收文件对象

    4. Mybatis面试题

    4.1 #{}和${}的区别是什么

  • {}是预编译处理,${}是字符串替换。

  • Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
  • Mybatis在处理${}时,就是把${}替换成变量的值。
  • 使用#{}可以有效的防止SQL注入,提高系统安全性。
  • 使用建议
  • 能用 #{} 的地方就用 #{},不用或少用 ${}

  • 表名作参数时,必须用 ${}。如:select * from ${tableName}

  • order by 时,必须用 ${}。如:select * from t_user order by ${columnName}

  • 使用 ${} 时,要注意何时加或不加单引号,即 ${} 和 ‘${}’

    4.2 实体类中的属性名和表中的字段名不一样,怎么办

    写sql语句时起别名 ,别名和属性相对应

在MyBatis的全局配置文件中开启驼峰命名规则 ,mybatis会将数据库中 下划线的字段自动转为驼峰格式的属性

在Mapper映射文件中使用resultMap来自定义映射规则

4.3 常见的mybatis的动态标签

  • 4.4 标签的作用及如何使用

    (TE`I~%$%NK5UU}5T`~{6)A.png

  • collection 集合名称

  • item 每个元素名称
  • separator 分隔符

    4.5 Mapper接口里的方法,参数不同时,方法能重载吗

    不可以,不论是注解配置的mybatis 还是xml配置的mybatis,被解析后每个方法都会封装成一个MappedStatement 存储到一个map集合中,集合的key使用的是mapper接口的全限类名+方法名,value就是MappedStatement对象。
    如:
    我想写个重载方法 findUser 一个带ID参数 返回值User 一个不带参数 返回值为List 但是这个方法在map中寻找时都是以 xxx.UserMapper.findUser作为key ,会发生冲突 实际上这个时候mybatis也会报错。

    4.6 如何获取自动生成的(主)键值

  1. 可以通过查询最后一条的sql语句

SELECT LAST_INSERT_ID()
  1. 也可以通过mybatis的标签属性

useGeneratedKeys

4.7 在Mapper中如何传递多个参数

通过实体类传参
通过map传参
通过定义多个@Param注解传参

4.8 MyBatis如何执行批量插入

  • 通过mybatis的动态标签
  • 利用 MyBatis 批处理特性,批量提交(ExecutorType.BATCH)

    * SimpleExecutor 简单执行器
    * ReuseExecutor 可复用的执行器
    * BatchExecutor 批量

    4.9 介绍一下MyBatis的二级缓存

    一级缓存: 一级缓存:默认开启 一级缓存的范围是同一个SqlSession对象,当我们使用SqlSession对象进行查询时mybatis会帮我们把查询的数据存入到内存中,当我们在这个SqlSession中再一次执行同样的查询操作时,我们就可以直接去缓存中获取数据

二级缓存: 二级缓存:默认关闭 二级缓存是mapper级别的缓存,多个SqlSession共享,其作用域是mapper的同一个namespace,不同的SqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。

顺序: 二级缓存 —-> 一级缓存 —-> 数据库

4.10 一对一、一对多的关联查询

一对一: 在xml中定义映射关系, 使用association代表关联一个实体类, property映射的属性名,javaType该属性的实体类类型,fetchType是否延迟加载,column用于执行select方法所传递的参数,select需要执行的mapper方法的全限定名称


一对多: 在xml中定义映射关系,因为是一个集合 所以使用collection标签,ofType代表集合中实体类的类型,其他属性和上面对一的情况一致

4.11 MyBatis是如何进行分页的

通过pageHelper插件进行分页:

PageHelper.startPage(1,1); // 在代码中执行startPage方法 第一个参数第几页,第二个是几条数据 PageHelper分页的实现在我们执行SQL语句之前动态的将SQL语句拼接了分页的语句,从而实现了从数据库中分页获取数据的过程。

4.12 MyBatis与Hibernate有哪些不同

(1)Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。
(2)Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。
(3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。

4.13 Mybatis中使用到了哪些设计模式

  1. Builder模式,例如SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder;
  2. 工厂模式,例如SqlSessionFactory、ObjectFactory、MapperProxyFactory;
  3. 单例模式,例如ErrorContext和LogFactory;
  4. 代理模式,Mybatis实现的核心,比如MapperProxy、ConnectionLogger,用的jdk的动态代理;还有executor.loader包使用了cglib或者javassist达到延迟加载的效果;
  5. 装饰者模式,例如Cache包中的cache.decorators子包中等各个装饰者的实现;
  6. 组合模式,例如SqlNode和各个子类ChooseSqlNode等;
  7. 模板方法模式,例如BaseExecutor和SimpleExecutor,还有BaseTypeHandler和所有的子类例如IntegerTypeHandler;
  8. 适配器模式,例如Log的Mybatis接口和它对jdbc、log4j等各种日志框架的适配实现;
  9. 迭代器模式,例如迭代器模式PropertyTokenizer;

    5. SpringBoot

    5.1 Spring 和 SpringBoot的区别

    5.1.1 SpringBoot介绍

    SpringBoot 是Spring旗下的一款开发框架,他可以让我们创建基于Spring的应用变得更加的方便, SpringBoot 整合了常用的Spring和第三方的类库,整合后提供带Starter的pom,整合后的项目采用自动配置,如果配置不满足需要,SpringBoot也提供了配置文件 只需简单的修改便可以。 SpringBoot内置了 servlet容器(tomcat,jboss)使得我们的项目启动部署更加的方便 (java -jar xx.jar) Springboot 提供了企业级应用的健康检测方案

5.1.2 SpringBoot优点

  1. 快速搭建项目,
  2. 与主流框架集成无需配置集成.
  3. 内嵌服务容器.
  4. 具有应用监控.
  5. 开发部署方便

    5.2 SpringBoot中常见的starter

    参考: Spring官方文档

    5.3 SpringBoot的配置文件

    springboot启动后 会默认的去指定文件夹加载 名称为 application的文件,后缀为
    .properties 或 .yml .yaml
    application.properties/yml
    bootstrap.properties/yml
    如果在同一目录下出现多个配置文件: springboot会都加载
    application.properties > .yml > .yaml
    属性名相同: 优先级高的生效
    属性名不同: 都生效
    项目目录:
    config:
    application.yml
    项目目录:
    application.yml
    项目目录:
    resources:
    config
    application.yml
    项目目录:
    resources:
    application.yml

    5.4 yml配置文件语法

    配置普通数据:
    语法: key: value
    如:
    1. name: xiaoming
    注意: : 和 value间一定要有空格

配置对象或map数据:
语法: key:
key1: value1
key2: value2
或: key: {key1: value1,key2: value2}
如:

  1. person:
  2. name: xiaoming
  3. first: 1
  4. age: 3

注意: 相同缩进代表同一级别. name和age同一级别都是person的属性
如果属性有了值就不能在有下级属性

配置集合数组:
语法: key:
- value1
- value2
或: key: [value1,value2]
注意: -符号 一定要在同一级别,并且和属性间要有空格

配置对象集合
语法: key:
- key1: value
key2: value
- key1: value
key2: value
或: key: [{key1: value1,key2: value2},{key1: value1,key2: value2}]
注意: -符号 一定要在同一级别,并且和属性间要有空格

5.5 如何读取自定义的配置

  • @Value ```java @Value(“${name}”)

    String name;

  1. @Value("${person.name}")
  2. String personName;
  3. @Value("${city[0]}")
  4. String cityFirst;
  1. - @ConfigurationProperties(prefix = "xxl.job")
  2. ```java
  3. @Data
  4. @Component
  5. @ConfigurationProperties(prefix = "config-attributes")
  6. public class ConfigModel {
  7. private String val;
  8. private int[] valArr;
  9. private List<String> cityList;
  10. private Map valMap;
  11. private List<Map> valMapList;
  12. }

5.6 如何定义多环境配置

如果所有环境配置都写到一个配置文件中,不好维护
可以定义多个环境配置文件的方式来实现:
如:
application-{环境名称}.yml
application-dev.yml
application-test.yml
application-prod.yml

  1. spring:
  2. profiles:
  3. active: prod 激活生产环境的配置

5.7 SpringBoot自动配置的原理

SSM面试热点 - 图9