SpringBoot原理

本文深入探讨了SpringBoot的配置优先级,包括不同格式配置文件的优先级,以及系统属性和命令行参数的优先级。接着,讨论了SpringBoot的Bean管理,包括获取Bean、Bean作用域和第三方Bean的配置。特别强调了Bean默认的单例模式以及如何设置为非单例。最后,介绍了SpringBoot的自动配置机制,包括起步依赖、自动配置的概念以及自动配置的实现原理,如@Conditional注解的作用。文章旨在理解SpringBoot底层工作方式,对面试和项目开发有所帮助。
摘要由CSDN通过智能技术生成

目录

1. 配置优先级

application.properties

2.Bean管理

2.1 获取Bean

2.2 Bean作用域

2.3 第三方Bean

3. SpringBoot原理

3.1 起步依赖

3.2 自动配置

3.2.1 概述

3.2.2 常见方案

3.2.2.1 概述

3.2.2.2 方案一

3.2.2.3 方案二

3.2.3 原理分析

3.2.3.1 源码跟踪

3.2.3.2 @Conditional


SpringBoot原理 主要偏向底层原理

主要记录以下三部分

1.首先就是配置优先级  SpringBoot中常见的配置方式以及配置当中的优先级

2.Bean管理

3.SpringBoot底层原理  面试加工资必备

1. 配置优先级

SpringBoot项目当中支持的三类配置文件:

  • application.properties

  • application.yml

  • application.yaml

启动SpringBoot程序,测试下三个配置文件中哪个Tomcat端口号生效:

  • properties、yaml、yml三种配置文件同时存在

properties、yaml、yml三种配置文件,优先级最高的是properties

  • yaml、yml两种配置文件同时存在

配置文件优先级排名(从高到低):

  1. properties配置文件

  2. yml配置文件

  3. yaml配置文件

注意事项:虽然springboot支持多种格式配置文件,但是在项目开发时,推荐统一使用一种格式的配置。(yml是主流)

在SpringBoot项目当中除了以上3种配置文件外,SpringBoot为了增强程序的扩展性,除了支持配置文件的配置方式以外,还支持另外两种常见的配置方式:

  1. Java系统属性配置 (格式: -Dkey=value)

-Dserver.port=9000

  1. 命令行参数 (格式:--key=value)

--server.port=10010

删除命令行参数配置,重启SpringBoot服务:

所以

优先级: 命令行参数 > 系统属性参数 > properties参数 > yml参数 > yaml参数

如果项目已经打包上线了,这个时候我们来设置Java系统属性和命令行参数

运行jar程序:

  • 同时设置Java系统属性和命令行参数

  • 仅设置Java系统属性

注意事项:

  • Springboot项目进行打包时,需要引入插件 spring-boot-maven-plugin (基于官网骨架创建项目,会自动添加该插件)

在SpringBoot项目当中,常见的属性配置方式有5种, 3种配置文件,加上2种外部属性的配置(Java系统属性、命令行参数)。通过以上的测试,我们也得出了优先级(从低到高):

  • application.yaml(忽略)基本遇不见  赶紧忘掉

  • application.yml

  • application.properties

  • java系统属性(-Dxxx=xxx)

  • 命令行参数(--xxx=xxx)

2.Bean管理

可以通过Spring当中提供的注解@Component以及它的三个衍生注解(@Controller、@Service、@Repository)来声明IOC容器中的bean对象,同时我们为应用程序注入运行时所需要依赖的bean对象,也就是依赖注入DI。

  1. 从IOC容器中手动的获取到bean对象

  2. bean的作用域配置

  3. 管理第三方的bean对象

接第一方面,从IOC容器中获取bean对象。

2.1 获取Bean

默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对象,就直接进行依赖注入就可以了。

而在Spring容器中提供了一些方法,可以主动从IOC容器中获取到bean对象,下面介绍3种常用方式:

  1. 根据name获取bean

Object getBean(String name)

  1. 根据类型获取bean

<T> T getBean(Class<T> requiredType)

  1. 根据name获取bean(带类型转换)

<T> T getBean(String name, Class<T> requiredType)

  • 想获取到IOC容器,直接将IOC容器对象注入进来就可以了

控制器:DeptController

@RestController
@RequestMapping("/depts")
public class DeptController {

    @Autowired
    private DeptService deptService;

    public DeptController(){
        System.out.println("DeptController constructor ....");
    }

    @GetMapping
    public Result list(){
        List<Dept> deptList = deptService.list();
        return Result.success(deptList);
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id)  {
        deptService.delete(id);
        return Result.success();
    }

    @PostMapping
    public Result save(@RequestBody Dept dept){
        deptService.save(dept);
        return Result.success();
    }
}

业务实现类:DeptServiceImpl

@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<Dept> list() {
        List<Dept> deptList = deptMapper.list();
        return deptList;
    }

    @Override
    public void delete(Integer id) {
        deptMapper.delete(id);
    }

    @Override
    public void save(Dept dept) {
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());
        deptMapper.save(dept);
    }
}

Mapper接口:

@Mapper
public interface DeptMapper {
    //查询全部部门数据
    @Select("select * from dept")
    List<Dept> list();

    //删除部门
    @Delete("delete from dept where id = #{id}")
    void delete(Integer id);

    //新增部门
    @Insert("insert into dept(name, create_time, update_time) values (#{name},#{createTime},#{updateTime})")
    void save(Dept dept);
}

测试类

@SpringBootTest
class SpringbootWebConfig2ApplicationTests {

    @Autowired
    private ApplicationContext applicationContext; //IOC容器对象

    //获取bean对象
    @Test
    public void testGetBean(){
        //根据bean的名称获取
        DeptController bean1 = (DeptController) applicationContext.getBean("deptController");
        System.out.println(bean1);

        //根据bean的类型获取
        DeptController bean2 = applicationContext.getBean(DeptController.class);
        System.out.println(bean2);

        //根据bean的名称 及 类型获取
        DeptController bean3 = applicationContext.getBean("deptController", DeptController.class);
        System.out.println(bean3);
    }
}

看 !!程序运行后控制台日

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值