从Spring进化为SpringBoot

目录

零.@SpringBootApplication

一.起步依赖

二.自动配置

三.自动配置的原理

1.装配常见方案

【1】方案1:@ComponentScan 组件扫描

【2】方案2:@Import 导入

【3】使用第三方依赖提供的 @EnableXxxxx注解

2.自动装配原理

3.实现starter

四.内置Tomcat


SpringBoot相比于Spring简化了开发,得益于它两个非常重要的功能:一个是起步依赖,一个是自动配置。

通过SpringBoot所提供的起步依赖,就可以大大的简化pom文件当中依赖的配置。

通过自动配置的功能就可以大大的简化在使用时Bean的配置类书写。
这样我们只需要引入程序开发时所需要的起步依赖,我们就可以直接使用其中的Bean了。

零.@SpringBootApplication

这个注解是Spring Boot项目的基石,创建SpringBoot项目之后会默认在主类加上。

@SpringBootApplication
public class SpringSecurityJwtGuideApplication {
      public static void main(java.lang.String[] args) {
        SpringApplication.run(SpringSecurityJwtGuideApplication.class, args);
    }
}

我们可以把 @SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。

package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
   ......
}

package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

根据 SpringBoot 官网,这三个注解的作用分别是:
(1)@EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
(2)@ComponentScan:扫描被@Component (@Repository,@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。
(3)@Configuration:声明这个类是配置类。
并允许在 Spring 上下文中注册额外的 bean 或导入其他配置类。

这个注解是自动装配的核心,后面会讲到。

一.起步依赖

简单说就是我们只要引入一个starter依赖,与之相关的依赖jar包都会被引入。

注:starter是SpringBoot中常见项目名称,定义了很多该依赖所使用的其他依赖坐标,以达到简化配置的目的。

原理就是Maven的依赖传递。

例:

比如springboot-starter-web,这是web开发的起步依赖,在web开发的起步依赖当 中,就集成了web开发中常见的依赖:json、web、webmvc、tomcat等。我们只需要引入 这一个起步依赖,其他的依赖都会自动的通过Maven的依赖传递进来。

二.自动配置

概念:SpringBoot的自动配置就是当Spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器 中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

解释:先回顾一下之前的spring注解开发的步骤

具体流程:定义Bean【第三方或自定义】->扫描进容器管理【扫描包或配置类】->依赖自动注入或按名称注入【普通类型可以通过配置文件注入】

简单说自动配置就是省略中间那一步。也就是我们自己扫描包(也就是配置)的过程,而采用自动配置。
 

之前要用@Component注册Bean,并且使用@ComponentScan之类的注解在配置类上对Bean进行扫描。
现在使用SpringBoot的@SpringBootApplication就实现了在启动时通过自动配置。将自定义Bean和第三方starter中的Bean自动装配到容器。

现在自定义的Bean的话只需要@Component和@Configuration注册Bean就可以了,后续不用管它。第三方starter的话只需要引入就可以通过@Autowired或@Resource注入Bean直接用。

附:在SpringBoot中@Configuration作用和@Component一样。

@Configuration一般用来声明配置类,可以使用@Component注解替代,不过使用注解@Configuration声明配置类更加语义化。

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }
}

一般@Configuration用来配置第三方Bean,而@Component用来自定义Bean。

三.自动配置的原理

1.装配常见方案

我们可以试试自定义第三方Bean并引入依赖,会发现引入进来的第三方依赖当中的bean以及配置类为什么没有生效。

案例:创建flyingpig-utils工程,里面有个子类。

@Component
public class TokenParser {
    public void parse(){
        System.out.println("TokenParser ... parse ...");
    }
}

通过坐标引入依赖:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>flyingpig-utils</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

我们进行Bean的注入,发现没有com.example.TokenParse类型的Bean。

原因在我们之前讲解IOC的时候有提到过,在类上添加@Component注解来声明bean对象时,还需 要保证@ComponentScan注解能被Spring的组件扫描到。

SpringBoot项目中的@SpringBootApplication注解,具有包扫描的作用,但是它只会扫描启动类所在的当前包以及子包。
当前包:com.flyingpig, 第三方依赖中提供的包扫描不到。

那么如何解决以上问题的呢,那就是扫描我们第三方依赖的包。那怎么扫描呢,主要有三种方法。

【1】方案1:@ComponentScan 组件扫描

@SpringBootApplication
@ComponentScan({"com.flyingpig","com.example"}) //指定要扫描的包
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class,args);
    }
}

缺点: 1. 使用繁琐 2. 性能低

【2】方案2:@Import 导入

使用@Import导入的类会被Spring加载到IOC容器中

(1)引入类

@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
@SpringBootApplication
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class,args);
     }
}

(2)导入配置类

@Configuration
public class HeaderConfig {
    @Bean
    public HeaderParser headerParser(){
        return new HeaderParser();
    }
    @Bean
    public HeaderGenerator headerGenerator(){
        return new HeaderGenerator();
    }
}
@Import(HeaderConfig.class) //导入配置类
@SpringBootApplication
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class,args);
    }
}

(3)导入ImportSelector接口实现类

public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //返回值字符串数组(数组中封装了全限定名称的类)
        return new String[]{"com.example.HeaderConfig"};
    }
}
@Import(MyImportSelector.class) //导入ImportSelector接口实现类
@SpringBootApplication
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class,args);
    }
}

上面两种方法对程序员比较很繁琐,不友好。

那我们如何我们不用自己指定要导入哪些bean对象和配置类了,让第三方依赖它自己来指定。

【3】使用第三方依赖提供的 @EnableXxxxx注解

在使用时只需在启动类上加上@EnableXxxxx注解即可

@EnableHeaderConfig //使用第三方依赖提供的Enable开头的注解
@SpringBootApplication
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class,args);
    }
}

2.自动装配原理

在前面讲到的@SpringBootApplication注解中包含了:
【1】元注解(不再解释)
【2】@SpringBootConfiguration--底层是@Configuration注解,表明SpringBoot启动类就是一个配置类。
【3】@ComponentScan--用来进行组件扫描的,这里扫描启动类所在的包及其子包下所有Bean。
也就是说这个注解实现了自定义Bean的自动装配。

【4】@EnableAutoConfiguration--核心注解,实现第三方Bean自动装配。

底层封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)
在实现类重写的selectImports()方法,读取当前项目下所有依赖jar包中META-INF/spring.factories、META-INF/spring/org.springframework.boot.autoconfigure.AutoConfigurat ion.imports两个文件里面定义的配置类(配置类中定义了@Bean注解标识的方法)。

当SpringBoot程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息(类的全限定名)封装到String类型的数组中,最终通过@Import注解将这些配置类全部加载到Spring的IOC容器 中,交给IOC容器管理。

简单说就是第三方依赖定义配置类,然后通过底层的@Import注解调用接口实现类读取配置文件中的配置类,再读取其中的Bean进行配置。
而不用在代码中自己定义扫描了。

这些所有的自动配置类当中,所有的 bean都会加载到 spring 的 IOC 容器当中吗?

并不会。在声明 bean 的时候,通常会加上这么一类@Conditional 开头的注解。这个注解就是进行条件装配。所以SpringBoot非常的智能,它会根据 @Conditional 注解来进行条件装配。只有条件成立,它才会声明这 个bean,才会将这个 bean 交给 IOC 容器管理。

3.实现starter

在自定义一个起步依赖starter的时候,按照规范需要定义两个模块,一个用来实现起步依赖,一个用来实现自动配置
1. starter模块(进行依赖管理[把程序开发所需要的依赖都定义在starter起步依赖中])
2. autoconfigure模块(自动配置) 将来在项目当中进行相关功能开发时,只需要引入一个起步依赖就可以了,因为它会将 autoconfigure自动配置的依赖给传递下来。

注:

SpringBoot官方starter命名: spring-boot-starter-xxxx
第三组织提供的starter命名: xxxx-spring-boot-starter

需求明确了,接下来我们再来分析一下具体的实现步骤:
第1步:创建自定义starter模块(进行依赖管理)
第2步:创建autoconfigure模块 在starter中引入autoconfigure (我们使用时只需要引入starter起步依赖即可)
第3步:在autoconfigure中完成自动配置
1. 定义一个自动配置类,在自动配置类中将所要配置的bean都提前配置好
2. 定义配置文件,把自动配置类的全类名定义在配置文件中

也可以直接定义一个starter模块,里面定义类,配置类以及配置文件。

四.内置Tomcat

为什么我们之前书写的SpringBoot入门程序中,并没有把程序部署到Tomcat的webapps目录 下,也可以运行呢?

原因呢,是因为在我们的SpringBoot中,引入了web运行环境(也就是引入spring-boot-starter-web起步依赖),其内部已经集成了内置的Tomcat服务器。

我们可以通过IDEA开发工具右侧的maven面板中,就可以看到当前工程引入的依赖。其中已经将 Tomcat的相关依赖传递下来了,也就是说在SpringBoot中可以直接使用Tomcat服务器。

  • 13
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值