您的位置:首页 > 编程语言 > Java开发

Spring Boot 笔记之SpringApplication

2019-05-26 23:33 267 查看

SpringApplication是Spring Boot驱动应用上下文的引导类。

1.Spring Boot项目的启动类有2种写法:

写法一:

写法2:

如果把写法2改成用写法1的方式,显示如下:

随机端口一般是单元测试用的。

 

2.SpringApplication与SpringBootApplication的区别;

@SpringBootApplication 标注当前一些功能

SpringApplication :Spring Boot应用的引导

 

先看一下SpringBootApplication的注解:

这个注解我们重点关注3个地方,第一个:@ComponentScan,它是Spring Framework 3.1开始引入的,是扫描的作用。

第二个:@EnableAutoConfiguration,激活自动装配,@Enable模式,都是@Enable开头的,比如说:

  • @EnableWebMvc

  • @EnableTransactionManagement

  • @EnableAspectJAutoProxy

  • @EnableAsync

第三个:@SpringBootApplication等价于@Configuration->configuration class注解

说他等价的原因在此:

举个例子(Spring注解驱动示例):

注解驱动上下文AnnotationConfigApplicationContext:Spring Framework 3.0开始引入的

 

 

3.@Component的“派生性”

  • @Component

    @Service

  • @Repository

  • @Controller

  • @Configuration

 

@Service、@Repository、@Controller、@Configuration里面都是@Component,这个叫做Spring的模式注解

具体的依据可以去这儿看:https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model

Spring的模式注解:Srereotype Annotations

元注解:标注元注解的注解。也就是说@Component是@Service、@Repository、@Controller、@Configuration的元注解,@Document是所有注解的元注解。

模式注解包括@Component,@Service,@Repository,@Controller,@RestController,@configuration等。(@Contrlloer、@Service、@Repository只是逻辑上的区分,对Spring而言,都是bean。物理上都是一样的,都是bean defination)

 

这个派生性只有在@Component里面生效。因为@Componnent和@ComponentScan的成队性,@ComponentScan去扫描@Component。它的“子”注解都会被扫进去。即凡是被@Component标注的都会被扫描进去。

为什么@Component的会被扫描进去呢?

即处理类:ConfigurationClassParser

扫描类:

ClassPathBeanDefinitionScanner

  •  ClassPathScanningCandidateComponentProvider

扫描之后用parse方法进行解析,

如果使用默认过滤器,Component、Repository、Service、Controller都会被扫进来。

继续这个方法往下跟:

这个方法的第一行,表明了只过滤component。

这就是为什么他只扫描ComponentScan。

可以类比一下dubbo的@Service->2.5.7版本->new AnnotationTypeFilter(Service.class);

 

@SpringBootApplication等同于@SpringBootConfiguration,等同于@Configuration,等同于@Component,所以他是一个bean,但是由于注解是不能继承的,所以叫“派生性”。

所谓@Component的“派生性”等同于注解的“继承”。

 

知道了什么是Spring模式注解和@Component的“派生性”之后,再回到注解驱动的例子:

先看SpringBoot的启动示例:

 

再看下String的:

对比可以看出输出的结果是一样的。所以其实,Spring Boot是驱动Spring的一个容器,只不过是谁来驱动的问题。

为了进一步证明这个观点,把上面的例子调整为非web程序:

 

打印出来的当前Spring应用上下文的类正是等于它:

现象出来之后,我们看一下这个的本质:

  • WebApplicationType.NONE:非web类型

     Servlet不存在

  • Spring Web应用上下文ConfigurableWebApplicationContext不存在

     spring-boot-starter-web不存在

  • spring-boot-starter-webflux不存在

  • WebApplicationType.REACTIVE:Spring WebFlux

       DespatcherHandler

       spring-boot-starter-webflux存在

  •  Servlet不存在

       spring-boot-starter-web不存在

  • WebApplicationType.SERVLET:Spring MVC

       spring-boot-starter-web存在

    如果2个包都加入,代码是有优先级的,判断之后,会选择Spring MVC

     

    当不加以设置web类型时,它采用推断:

    SpringApplication()->deduceWebApplicationType()第一次推断为WebApplicationType.SERVLET

    设置webApplicationType属性为WebApplicationType.NONE

    当设置为非web类型,他的server容器也不会启动了,程序就挂掉了。说明web类型会影响上下文。

    设置之后,看看那个方法读调用了他:

    所以说Spring Boot只是一层壳,核心还是Spring Framework。

    SpringApplication是Spring Boot驱动应用上下文的引导类。调用run方法的时候,

    看到这,再回到一开始spring的那个例子:

    和这个例子中的refresh()对应的。所以说,SpringApplication是Spring Boot驱动应用上下文的引导类。

    最后看一下官方文档关于SpringApplicaiton的说明:

  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签:  Spring Spring Boot