SpringBoot技术概述

一、起源

为了应对越来越复杂的企业级应用开发,Spring应运而生,通过依赖注入和面向切面的技术,为企业级Java开发提供了相对简单的开发方法。

但是Spring的诞生也摆脱不了两大痛点问题:

  • 配置管理繁杂
  • 依赖管理繁琐

虽然Spring的组件是轻量的,但是其相关配置却是重量级的,一开始Spring使用繁杂的XML进行配置,在复杂的对象场景下,XML配置的工作量相对繁琐。

后来Spring 2.5引入了基于注解的组件扫描,消除了大量的XML显式配置;Spring 3.0引入了基于Java的配置,这种配置方式以类型安全的特点可以较好的替代XML配置方式。

尽管上述的演进帮助我们减轻配置的负担,但是配置工作还是必不可少的,比如使用三方库时,需要进行显示配置;进行事务管理和SpringMVC,也需要使用XML或Java方式进行显示配置。组件扫描减少了配置量,Java配置看起来更加清爽,但是Spring的配置工作还是不少的,需要投入很大的时间精力与完成。

另外,项目的依赖管理也较为繁琐,要梳理出应用所需的相关依赖信息,还要解决依赖之间彼此的冲突。而依赖版本所产生的兼容性问题也不容小觑。

基于上述痛点问题,SpringBoot应运而生。

二、SpringBoot核心要点概览

SpringBoot带来了Java开发的变革,最重要的是以下四个核心:

  • 自动配置:针对很多Spring应用程序常见的应用功能,Spring Boot能自动提供相关配置
  • 起步依赖:告诉Spring Boot需要什么功能,它就能引入需要的库
  • Actuator:让你能够深入运行中的Spring Boot应用程序,一探究竟
  • 命令行界面:这是Spring Boot的可选特性,借此你只需写代码就能完成完整的应用程序,无需传统项目构建
1、自动配置

在传统Spring的项目中,显示配置比比皆是,例如JDBC访问数据库的代码配置片段:

        @Bean
        public JdbcTemplate jdbcTemplate(DataSource dataSource) {
          return new JdbcTemplate(dataSource);
        }

这段非常简单的Bean声明创建了一个JdbcTemplate的实例,注入了一个DataSource依赖。

        @Bean
        public DataSource dataSource() {
          return new EmbeddedDatabaseBuilder()
                  .setType(EmbeddedDatabaseType.H2)
                  .addScripts('schema.sql', 'data.sql')
                  .build();
        }

这些配置并不复杂,但是很多Spring应用中都有类似大量相同的配置片段,这种大量的**样板配置 **依托SpingBoot的自动配置就可以帮我们完成。

以上述场景为例,如果Spring Boot在应用程序的Classpath里发现H2数据库的库,那么它就自动配置一个嵌入式H2数据库。

如果在Classpath里发现JdbcTemplate,那么它还会为你配置一个JdbcTemplate的Bean。你无需操心那些Bean的配置,Spring Boot会做好准备,随时都能将其注入到你的Bean里。类似于这样的方式,可以大幅减轻开发者的配置负担。

2、起步依赖

SpringBoot通过起步依赖为项目的依赖管理提供帮助,起步依赖针对Maven\Gradle通过依赖传递的方式,把特定功能相关的依赖库聚合到一起,组成了针对特定功能的定制依赖集。

这样开发者从繁杂的依赖配置中解脱出来,在开发时只需要结合要实现的功能,把相关的起步依赖引入进来即可,不需要关心引入哪些依赖、这些依赖的版本选取哪个等问题,方便快捷。
在这里插入图片描述

这样做有两大好处:

  • 减少依赖数量:只需要引入起步依赖即可
  • 安全可靠:不用关心版本,起步依赖都是经过测试的,不会出现兼容性问题

如果想知道真正引入了哪些依赖,可以通过构建工具的依赖树进行查看,也可以使用Maven的dependency插件命令查看:

mvn dependency:tree

如果想对个别组件引入指定版本,可以在起步依赖中排除相关传递依赖,之后在POM.xml中显式直接引入。

3、Actuator

Actuator提供了运行时检视应用程序内部运行情况的能力,主要包括如下细节:

  • Spring应用程序上下文里配置的Bean
  • Spring Boot的自动配置做的决策
  • 应用程序取到的环境变量、系统属性、配置属性和命令行参数
  • 应用程序里线程的当前状态
  • 应用程序最近处理过的HTTP请求的追踪情况
  • 各种和内存用量、垃圾回收、Web请求以及数据源用量相关的指标

可以通过相关界面发送指令,查看具体的情况信息。

三、自动配置技术

1、配置启动引导类

首先,需要有配置启动引导类,这是主要的Spring配置类。虽然Spring Boot的自动配置免除了很多Spring配置,但还需要进行少量配置来启用自动配置:

@SpringBootApplication  // 开启组件扫描和应用配置
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);  // 负责启动引导应用程序
	}
}

@SpringBootApplication开启了Spring的组件扫描和Spring Boot的自动配置功能。

实际上,@SpringBootApplication将三个有用的注解组合在了一起。

  • @Configuration:标明该类使用Spring基于Java的配置。虽然本书不会写太多配置,但我们会更倾向于使用基于Java而不是XML的配置。
  • @ComponentScan:启用组件扫描,这样你写的Web控制器类和其他组件才能被自动发现并注册为Spring应用程序上下文里的Bean。比如Spring MVC控制器,使用@Controller进行注解,这样组件扫描才能找到它。
  • @EnableAutoConfiguration :就是这一行配置开启了Spring Boot自动配置的魔力,让你不用再写成篇的配置了。

main方法里向SpringApplication.run()传递了一个DemoApplication类的引用,还有命令行参数,通过这些东西启动应用程序。

2、条件配置

原文

当我们使用SpringBoot时,可以在依赖库中看到有个spring-boot-autoconfigure的JAR文件,里面有很多配置类,这些配置类都会在应用程序的ClassPath中,根据触发条件,为应用程序的自动配置提供便利:
在这里插入图片描述

这些配置类可以根据条件灵活加载,其原因在于它们使用了Spring的条件化配置(Spring 4.0引入的新特性)。

条件化配置允许配置存在于应用程序中,但在满足某些特定条件之前都忽略这个配置。另外,在Spring里可以很方便地编写你自己的条件,你所要做的就是实现Condition接口,覆盖它的matches()方法。举例来说,下面这个简单的条件类只有在Classpath里存在JdbcTemplate时才会生效:

# 代码示例源自《SpringBoot实战》
public class JdbcTemplateCondition implements Condition {
  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    try {
       context.getClassLoader().loadClass("org.springframework.jdbc.core.JdbcTemplate");
       return true;
    } catch (Exception e) {
       return false;
    }
   }
}

当你用Java来声明Bean的时候,可以使用这个自定义条件类:

@Conditional(JdbcTemplateCondition.class)
public MyService myService() {
      ...
}

在这个例子里,只有当JdbcTemplateCondition类的条件成立时才会创建MyService这个Bean。也就是说MyService Bean创建的条件是Classpath里有JdbcTemplate。否则,这个Bean的声明就会被忽略掉。

更多的条件化注解如下:
在这里插入图片描述

3、自定义配置
  • 使用显示配置进行覆盖

    案例来自《SpringBoot实战》

在这里插入图片描述

当我们显示编写了SpringSecurity的配置时,Spring Boot会降低自动配置的优先级,以显式配置为准。

其原因在于@ConditionalOnMissingBean注解是覆盖自动配置的关键。我们可以在相关自动配置中看到如下源码:

        @Configuration
        @EnableConfigurationProperties
        @ConditionalOnClass({ EnableWebSecurity.class })
        @ConditionalOnMissingBean(WebSecurityConfiguration.class)
        @ConditionalOnWebApplication
        public class SpringBootWebSecurityConfiguration {

        ...

        }

@ConditionalOnMissingBean注解要求当下没有WebSecurityConfiguration类型的Bean。虽然在显式配置中我们并没有显式创建这个Bean,但通过在SecurityConfig上添加@EnableWeb-Security注解,实际上间接创建了一个WebSecurityConfiguration Bean。

所以在自动配置时,这个Bean就已经存在了,@ConditionalOnMissingBean条件不成立,SpringBoot-WebSecurityConfiguration提供的配置就被跳过了。

  • 使用属性进行精细化配置

    我们在application.properties的文件中进行相关属性精细化配置,也可以创建名为application.yml的YAML文件进行属性配置。

            spring.main.show-banner=false
    

    yaml示例如下:

            logging:
              level:
                root: INFO
    
            ---
    
            spring:
              profiles: development
    
            logging:
              level:
                root: DEBUG
    
            ---
    
            spring:
              profiles: production
    
            logging:
              path: /tmp/
              file: BookWorm.log
              level:
                root: WARN
    

    这个application.yml文件分为三个部分,使用一组三个连字符(—)作为分隔符。第二段和第三段分别为不同spring.profiles下的相关配置,不同部分的配置将在对应的profiles下激活。

    Profile是应对不同的应用配置面对不同的部署环境而产生的,这是一种条件化配置,基于运行时激活的Profile,会使用或者忽略不同的Bean或配置类。

            @Profile("production")
            @Configuration
            @EnableWebSecurity
            public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
            ...
    
            }
    

    如上所示,可以为配置类指定profile环境,当profile为production时才激活上述配置类,否则将忽略。

参考资料:《SpringBoot实战》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值