SpringBoot自动加载配置原理讲解

目录

一、前言

二、起步依赖

三、自动配置


 

一、前言

SpringBoot将很多魔法带入Spring应用,其中最重要包含以下四个核心。

  1. 自动配置:针对很多Spring应用程序常见的应用功能,SpringBoot能自动提供相关的配置!《今天主要解析内容》
  2. 起步依赖:告诉SpringBoot需要什么功能,它就能引入需要的库。

二、起步依赖

向项目中添加依赖时间富有挑战的事。你需要什么库?他的Group和Artifact是什么?你需要哪个版本?哪个版本不会和项目中的其他依赖发生冲突?SpringBoot通过起步依赖为项目的依赖管理提供帮助,起步依赖其实就是特殊的Maven依赖,利用依赖传递解析,把常用库聚合在一起,组成了几个为特定功能而定制的依赖!

举个例子,假设你正在用Spring MVC构建一个RESR API,并将JSON作为资源表述。此外,你还想运用遵循JSR-303规范的声明式校验,并使用嵌入式的Tomcat服务器提供服务,实现以上目标,你在Maven中至少要依赖以下依赖:

  • spring-core
  • spring-web
  • spring-webmvc
  • jackson-databind等等

不过、如果打算利用SpringBoot的起步依赖,你只需要添加SpringBoot的WEB起步依赖(spring-boot-starter-web),仅此一个,它会根据依赖传递把其他所以需要的依赖传递到项目里,我们就不需要考虑细节依赖了!

比起减少依赖数量,起步依赖还引入了一些微妙的变化、项目中添加了web起步依赖,实际上指定了应用程序所需的一类功能,因为应用是个WEB应用程序,所有加入WEB的起步依赖,与之类似,如果应用程序要用到JPA持久化,那么就可以加入JPA起步依赖。如果需要安全功能,那就加入security起步依赖。简而言之,你不再需要考虑支持某种功能需要什么库了,引入相关的起步依赖就行。


此外,SpringBoot的起步依赖还把你从“需要哪些库、哪些版本”这个问题里解放出来,起步依赖引入的库和版本都是经过测试,因此你可以完全放心,他们之间不会存在不兼容的问题!
springboot的starters列表

三、自动配置

自动装配,SpringBoot的自动装配是一个运行时(更准确地说,是应用程序启动时)的过程。考虑了众多因素,才决定Spring配置应该用哪个,不加载哪个类的Bean!
举几个例子:

  1. Spring的JdbcTemplate是不是在Classpath里,如果是,并且有DataSource的bean,符合这俩条件则自动配置一个JdbcTemplate的bean
  2. Thymeleaf是不是在Clasapath里,如果是,则配置Thymeleaf的模版解析器、试图解析器以及模版引擎。

每当应用程序启动的时候,SpringBoot的自动装配都要做将近200次这样的决定,覆盖安全集成、持久化、Web开发等诸多方面。所有这些自动配置就是为了尽量不让开发者自己写配置~
他到底是如何做到自动加载配置呢?我们来解析以下,解读之前,我们需要了解Spring4条件加载特性!

1.Spring4条件化配置

SpringBoot之所以能够自动加载配置,Spring4更新的条件化配置决定性因素,我们先回顾下这个技术点再深入理解SpringBoot自动配置的实现原理!
在Spring4更新的条件化配置,可以让你通过判断条件,去决定是否加载和初始化一个类!

我们要自定义条件其实很简单!

步骤1:实现Condition接口,覆盖它的matches()方法,matches()方法中自己编写条件控制返回boolean决定是否加载!

步骤2:声明类的时候使用对注解指向条件即可!(@Conditional(Condition实现类.class))

条件类代码:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * projectName: JVM
 *
 * @author: 赵伟风
 * time: 2021-02-04 00:51
 * description:userservice加载条件类
 */
public class UserServiceConditional implements Condition {

       
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

        try {
            //判断是否有user类,决定返回值!
            Class.forName("com.zwf.boot_auto_configure.bean.User");
            return true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return  false;
        }
    }
}

业务类代码:

import com.zwf.boot_auto_configure.conditional.UserServiceConditional;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Service;

/**
 * projectName: JVM
 *
 * @author: 赵伟风
 * time: 2021-02-04 00:49
 * description:
 */

@Service
@Conditional(UserServiceConditional.class) //加载判断条件,需要条件类matches返回值决定是否加载
public class UserService {

    public String retMsg(){

        return "service msg";
    }
}

controller测试类代码:

import com.zwf.boot_auto_configure.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * projectName: JVM
 *
 * @author: 赵伟风
 * time: 2021-02-04 00:49
 * description: 测试获取业务类实体
 */

@RestController
public class UserController {

    /**
     * 自己创建和删除实体类,测试是否装配此实体,理解条件化加载!
     */
    @Autowired
    private UserService userService;


    @GetMapping("/retmsg")
    public String retMsg(){

        return  userService.retMsg();
    }
}

 

通过控制UserServiceConditional判断条件返回值,可以动态控制是否配置UserService类!

其他条件化注解注解:

条件化注解
条件化注解条件化注解
@ConditionalOnBean 当存在某个类Bean生效
@ConditionalOnMissingBean当不存在某个类的Bean生效
@ConditionalOnClass当Classpath里有指定的类生效
@ConditionalOnMissingClass 当Classpath里没有指定的类生效
@ConditionalOnMissingClass 当指定java版本生效
@ConditionalOnProperty当指定配置属性要有一个明确的值
@ConditionalOnReource当指有某个配置资源的时候生效
@ConditionalOnWebApplication当是一个web应用的时候生效
@ConditionalOnNotWebApplication@ConditionalOnNotWebApplication

 

 

 

 

 

 

 

 

 

 

 

2、Springboot自动配置

自动配置就基于条件化配置,其实你可能理解了,springboot只不过是预先写好了配置类,在配置类加上各种条件,

例如需要jpa的bean,需要有数据库链接池才会加载!

只要倒入了对应的依赖,触发条件就会自动加载配置类!

在springboot中会依赖名为spring-boot-autoconfigure的jar,这里面有很多的配置类,每个配置类都在classpath里,只要符合条件就会自动加载!

举个例子:

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnBean({DataSource.class})
@ConditionalOnClass({JpaRepository.class})
@ConditionalOnMissingBean({JpaRepositoryFactoryBean.class, JpaRepositoryConfigExtension.class})
@ConditionalOnProperty(
    prefix = "spring.data.jpa.repositories",
    name = {"enabled"},
    havingValue = "true",
    matchIfMissing = true
)
@Import({JpaRepositoriesRegistrar.class})
@AutoConfigureAfter({HibernateJpaAutoConfiguration.class, TaskExecutionAutoConfiguration.class})
public class JpaRepositoriesAutoConfiguration {
    //省略
}

我们随便找了其中一个配置类,他的加载,就有很多条件,

@ConditionalOnBean({DataSource.class})配置jpa就必须先要包含datasource连接池的Bean

@ConditionalOnClass({JpaRepository.class})必须存在这个JpaRepository.类!也就是说必须导入Jpa的依赖包等!

说到这里,你对自动配置有个初步了解了么?

欢迎在评论互动讨论,我在接下来的文章中分析,如何触发自动加载和加载的springboot配置读取过程!


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值