首页 > 其他分享 >SpringBoot自动配置原理解析

SpringBoot自动配置原理解析

时间:2024-03-11 14:59:03浏览次数:11  
标签:SpringBoot 配置 自动 注解 原理 解析 class Starter

  一、什么是SpringBoot自动配置
  首先介绍一下什么是SpringBoot,SpringBoost是基于Spring框架开发出来的功能更强大的Java程序开发框架,其最主要的特点是:能使程序开发者快速搭建一套开发环境。SpringBoot 能将主流的开发框架(例如SpringMVC,Dubbo,Mybatis,Redis等),做到像Maven导入Jar包一样的简洁快速,做到开箱即用。其中最关键的技术就是 SpringBoot定制的各种Starter,通Maven引入Starter就能快速搭建开发环境。
  二、SpringBoot Starter自动装配案例
  在以前单独使用SpringMVC Web编程框架时,我们需要单独配置DispatcherServlet和Tomcat,使用SpringBoot之后,我们只需要引入SpringBoot-Starter-Web就能直接开始编写Controller等Web相关的代码,这就是SpringBoot为们提供的开箱即用的便捷能力,下面就以SpringBoot-Starter-Web 来说明SpringBoot自动配置的关键原理
  三、SpringBoot自动装配案例源码解析
  3.1 DispatcherServlet的自动配置原理
  首先我们定位到SpringBoot自动配置的Maven依赖
  <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-autoconfigure</artifactId>
  <version>${spring-boot.version}</version>
  </dependency>
  在依赖的Jar包中我们可以在META-INF/spring.factories中找到自动配置类:
  org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
  org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration.DispatcherServletConfiguration
  下图是这个配置类的主要源码和解析:
  下面将上图中关键的注解功能,分别进行功能说明
  3.1.1:@EnableConfigurationProperties ({WebMvcProperties.class}) 注解解析
  这个注解表示使WebMvcProperties.class类上的@ConfigurationProperties这个注解生效,同时@ConfigurationProperties这个注解是将application.xml中以 spring.mvc开头的配置参数自动注入到WebMvcProperties.class类的字段中
  3.1.2:@Conditional ({DefaultDispatcherServletCondition.class} 注解解析
  该注解的原理就是将满足特定条件情况下的Bean自动加载到Spring容器中,该注解对应的Spring接口就是 rg.springframework.context.annotation.Condition这个接口
  public interface Condition {
  boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
  }
  3.1.3:@ConditionOnClass注解解析
  @ConditionOnClass这个注解是在当程序代码环境classpath下存在xxx.class的情况下条件成立,同时最终也会调用到matches方法中,其中关键的源码如下:
  protected static Class<?> resolve(String className, ClassLoader classLoader) throws ClassNotFoundException {
  return classLoader != null ? Class.forName(className, false, classLoader) : Class.forName(className);
  }
  从上面可以看到,代码利用Class.forName方法加载classpath下的xxx.class类,如果加载成功条件就会成立。最后,在满足了所有@ConditionOnal注解条件后,SpringBoot就会自动为我们在Spring容器中注入DispatcherServlet了,无需单独配置了,直接引入pring-boot-starter-webr即可开始使用web相关功能。
  3.1.4:总结
  我们以DispatcherServlet是如何自动配置到容器中为例,探究了SpringBoot Starter的自动配置原理,其中涉及了几个关键的注解和步骤:
  第一步:涉及到了配置文件的读取和个性化配置,这里就涉及到了下面这两个注解
  @ConfigurationProperties
  @EnableConfigurationProperties
  第二步:设计到了在什么条件下才自动配置的注解
  @Conditional
  @ConditionalOnClass
  第三步:约定了自动配置类的加载路径
  /META-INF/spring-factories
  org.springframework.boot.autoconfigure.EnableAutoConfiguration=自动配置类全路径名称
  在我们了解到了SpringBoot自动配置的原理之后,我们就可以自定义一个SpringBoot Starter来快速搭建我们的开发环境了。
  四、自定义一个打印输入输出日志的Starter
  4.1 首先定义一个标记需要打印出入参日志的注解@PrintLog
  @Target(ElementType.METHOD)
  @Retention(RetentionPolicy.RUNTIME)
  public @interface PrintLog {
  }
  4.2 定义一个存放打印日志配置的实体类
  //自动注入application配置文件中已log.switch开头的配置参数
  @ConfigurationProperties("log.switch")
  public class LogProperties {
  //是否启用打印日志功能
  private Boolean enabled = false;
  //是否打印调用者ip
  private Boolean printIp = false;
  //是否打印调用者url
  private Boolean printUrl = false
  }
  4.3 定义一个@PrintLog注解的切面类
  @Aspect
  public class LogAspect {
  private static final Log LOGGER = LogFactory.getLog(LogAspect.class);
  private LogProperties logProperties;
  @Pointcut("@annotation(com.zl.annotation.PrintLog)")
  public void Log(){}
  @Around("Log()")
  public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
  ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  HttpServletRequest request = attributes.getRequest();
  MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  Method method = signature.getMethod();
  String methodName = method.getName();
  //打印调用url
  if (Boolean.TRUE.equals(logProperties.getPrintUrl())){
  LOGGER.info("URL:" + request.getRequestURL().toString());
  }
  //打印ip
  if (Boolean.TRUE.equals(logProperties.getPrintIp())) {
  LOGGER.info("IP :" + request.getRemoteAddr());
  }
  //打印方法
  LOGGER.info("method :" + methodName);
  //打印参数
  LOGGER.info("parameter :" + Arrays.toString(joinPoint.getArgs()));
  Object result = joinPoint.proceed();
  //打印返回结果
  LOGGER.info("return :" + JSON.toJSONString(result));
  return result;
  }
  }
  4.4 定义一个打印日志的自动配置类
  @Configuration
  @EnableConfigurationProperties({LogProperties.class})
  //表示在application配置文件中必须配置log.switch.enabled = true才启动自动配置
  @ConditionalOnProperty(prefix = "log.switch", value = "enabled", havingValue = "true")
  public class LogAutoConfigure {
  @Bean
  //Advice.class是aop切面中关键的切面方法类(@Before,@After等)
  //程序中有Advice.class类说明需要使用切面功能,这时才加载自定义的切面类
  @ConditionalOnClass(Advice.class)
  public LogAspect webLogAspect(LogProperties logProperties){
  return new LogAspect(logProperties);
  }
  }
  五、总结
  SpringBoot自动配置功能带给我们的是开箱即用,快速便捷的功能,自动配置为我们研发人员带来的优点,我主要总结为以下两点:
  提高研发效率 。我们可以快速构建开发环境,对于开发中使用到的开源组件和中间件,我们直接引入对应的Starter就可以直接开发了,例如Redis和Mybati等,可以直接引入对应的spring-boot-starter-data-redis就可以直接使用RedisTemplate来操作 Redis了,这样可以极大的提高研发的效率,无需再进行复杂的起步配置了和各种版本依赖管理了。
  标准模块复用。对于业务开发中的一些标准模块,例如常用的一些三方服务,我们可以利用Starter直接配置好,在需要使用的项目中直接引入这个starter就可以立即使用了,无需再去引入Jar包和编写配置文件等,同样的,对于一些标准非业务强耦合的功能,例如监控,鉴权等,也可以定义一个Starter,需要使用鉴权和监控功能的项目就可以直接复用了,无需再次开发。

标签:SpringBoot,配置,自动,注解,原理,解析,class,Starter
From: https://www.cnblogs.com/emmaty/p/18066060

相关文章

  • MySQL实现事务隔离的原理
    一、readview四个字段create_trx_id:创建该readview的事务的事务idm_ids:创建readview时,当前数据库中的活跃事务(指启动但还没提交的事务)min_trx_id:m_ids的最小值max_trx_id:创建readview后,下一个事务的id二、聚簇索引的隐藏列trx_id:最近一次改动该聚簇索引记录的事务idrol......
  • springboot初始化时执行方法
    参考:http://www.360doc.com/content/23/0303/15/81790262_1070284511.shtml监听容器刷新完成扩展点ApplicationListener<ContextRefreshedEvent>ApplicationContext事件机制是观察者设计模式实现的,通过ApplicationEvent和ApplicationListener这两个接口实现ApplicationContext......
  • 基于vue+springboot高校宿舍管理系统
    本项目是一款基于springBoot的高校宿舍管理系统。本系统主要功能包含:(1)基本信息管理基本信息分为学生信息和宿舍信息两部分,其功能是负责维护这些信息,对它们进行增删查改等操作。宿舍分配管理(2)根据给定的宿舍信息与学生信息,按照一定的规则自动地给还未分配宿舍的学生分配宿舍,......
  • 隐私计算-原理和实践
    主页个人微信公众号:密码应用技术实战个人博客园首页:https://www.cnblogs.com/informatics/引言很长一段时间没有更新博客和公众号了,最近做了一个基于区块链的隐私计算项目,主要关于数据安全流通和计算,在一定程度上解决了数据确权、授权使用、数据隐私等问题,保证了数据的可用......
  • [基础] VAE原理
    名称VAE原文TL;DR这篇文章介绍了一种名为Auto-EncodingVariationalBayes(AEVB)的算法。AEVB算法通过引入随机变分推断和学习算法,解决了在大数据集和不可解后验分布情况下的推断和学习问题。文章的主要贡献有两个:首先,提出了一个可以直接使用标准随机梯度方法优化的下界估计器......
  • SpringBoot3.x使用Druid
    SpringBoot3.x使用DruidBiliBili视频官网:druid/druid-spring-boot-starteratmaster·alibaba/druid参考文章SpringBoot3集成Druid连接池详解起步安装最新版本查询:https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-3-starter注意:Druid配......
  • java springboot拦截器的实现及用法
     1.前景,有时候我们在不同的地方需要使用用户的信息,我们可以使用threadLocal存储信息,这样我们在在这个线程随时使用用户信息了,不用自己在写一段冗余代码了,这时候使用拦截器就很不错 2.实现1.实现HandlerInterceptor2.重写实现方法  preHandle:在业务处理器处理请......
  • Tomcat解析Request对象
    当Tomcat创建一个HttpServletRequest对象并将其传递给Servlet的service方法时,这个对象并不完全包含请求体的数据。这是因为请求体的解析是延迟进行的,通常是在Servlet需要访问这些数据时(比如通过调用request.getParameter("name"))才进行的。这种设计是为了优化性能。HTTP请求体可......
  • H265 NALU类型详细解析
    1.H265NALU类型解析F:禁止位,必须为0,表示有效;为1的话表示无效。Type:6-bitsNALType确定NAL的类型,其中VCLNAL和non-VCLNAL各有32类。0-31是vclnal单元;32-63,是非vclnal单元。VCL是指携带编码数据的数据流,而non-VCL则是控制数据流。vclnal单元的类型(0-31)如下表: no......
  • springboot3开发文档
    版本号jdk17springboot3mysql8.0mavenidea自带springboot依赖注入pom.xml命名规范:官方提供的场景:命名为:spring-boot-starter-*第三方提供场景:命名为:*-spring-boot-starter父工程坐标对各种常用依赖的版本进行了管理,我们的项目需要以这个项目为父工程,这样我们就......