Spring Boot 笔记之SpringApplication

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

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

写法一:

image2019-5-25%2015%3A3%3A31.png?version=1&modificationDate=1558884495000&api=v2

写法2:

image2019-5-25%2015%3A4%3A24.png?version=1&modificationDate=1558884495000&api=v2

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

image2019-5-25%2015%3A5%3A24.png?version=1&modificationDate=1558884495000&api=v2

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

 

2.SpringApplication与SpringBootApplication的区别;

@SpringBootApplication 标注当前一些功能

SpringApplication :Spring Boot应用的引导

 

先看一下SpringBootApplication的注解:

image2019-5-25%2016%3A27%3A57.png?version=1&modificationDate=1558884495000&api=v2

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

image2019-5-25%2016%3A51%3A20.png?version=1&modificationDate=1558884495000&api=v2

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

  • @EnableWebMvc

  • @EnableTransactionManagement

  • @EnableAspectJAutoProxy

  • @EnableAsync

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

说他等价的原因在此:

image2019-5-25%2017%3A3%3A50.png?version=1&modificationDate=1558884495000&api=v2

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

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

 

image2019-5-25%2017%3A16%3A19.png?version=1&modificationDate=1558884495000&api=v2

 

3.@Component的“派生性”

  • @Component

    • @Service

    image2019-5-25%2017%3A23%3A15.png?version=1&modificationDate=1558884495000&api=v2

    • @Repository

      image2019-5-25%2017%3A23%3A57.png?version=1&modificationDate=1558884495000&api=v2

    • @Controller

    image2019-5-25%2017%3A24%3A34.png?version=1&modificationDate=1558884495000&api=v2

    • @Configuration

image2019-5-25%2017%3A25%3A8.png?version=1&modificationDate=1558884495000&api=v2

 

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

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

Spring的模式注解:Srereotype Annotations

image2019-5-25%2017%3A33%3A50.png?version=1&modificationDate=1558884495000&api=v2

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

image2019-5-25%2017%3A31%3A39.png?version=1&modificationDate=1558884495000&api=v2

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

 

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

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

image2019-5-25%2017%3A55%3A46.png?version=1&modificationDate=1558884495000&api=v2

即处理类:ConfigurationClassParser

扫描类:

ClassPathBeanDefinitionScanner

  •  ClassPathScanningCandidateComponentProvider
    image2019-5-25%2018%3A5%3A54.png?version=1&modificationDate=1558884495000&api=v2

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

image2019-5-25%2018%3A6%3A59.png?version=1&modificationDate=1558884495000&api=v2

image2019-5-25%2018%3A7%3A41.png?version=1&modificationDate=1558884495000&api=v2

image2019-5-25%2018%3A10%3A56.png?version=1&modificationDate=1558884495000&api=v2

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

继续这个方法往下跟:

image2019-5-25%2018%3A13%3A59.png?version=1&modificationDate=1558884495000&api=v2

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

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

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

 

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

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

 

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

先看SpringBoot的启动示例:

 

image2019-5-26%2022%3A18%3A52.png?version=1&modificationDate=1558884495000&api=v2

再看下String的:

image2019-5-25%2017%3A16%3A19.png?version=1&modificationDate=1558775775000&api=v2

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

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

image2019-5-26%2022%3A31%3A30.png?version=1&modificationDate=1558884495000&api=v2

 

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

image2019-5-26%2022%3A37%3A16.png?version=1&modificationDate=1558884495000&api=v2

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

image2019-5-26%2022%3A38%3A30.png?version=1&modificationDate=1558884495000&api=v2

image2019-5-26%2022%3A39%3A8.png?version=1&modificationDate=1558884495000&api=v2

  • 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类型会影响上下文。

image2019-5-26%2022%3A47%3A49.png?version=1&modificationDate=1558884496000&api=v2

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

image2019-5-26%2022%3A49%3A38.png?version=1&modificationDate=1558884496000&api=v2

image2019-5-26%2022%3A50%3A33.png?version=1&modificationDate=1558884496000&api=v2

image2019-5-26%2022%3A51%3A13.png?version=1&modificationDate=1558884496000&api=v2

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

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

image2019-5-26%2023%3A12%3A38.png?version=1&modificationDate=1558884496000&api=v2

image2019-5-26%2023%3A12%3A57.png?version=1&modificationDate=1558884496000&api=v2

image2019-5-26%2023%3A13%3A23.png?version=1&modificationDate=1558884496000&api=v2

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

image2019-5-26%2022%3A37%3A16.png?version=1&modificationDate=1558884495000&api=v2

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

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

image2019-5-26%2023%3A27%3A13.png?version=1&modificationDate=1558884496000&api=v2

转载于:https://my.oschina.net/u/3944601/blog/3054308

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值