02_高级/源码分析

1.原理分析

1.1.自动配置

1.1.1Condition概述
image.png
  • spring帮我们创建bean
  • 之前只要配置,spring会帮我们创建bean,现在可以加一些条件,满足条件,再帮我创建bean
  • 举例:导入spring-boot-starter-data-redis起步依赖,springboot就帮我们创建了redisTemplate,如果没有导入这个起步依赖,会不会帮我创建redisTemplate,而且springboot如何知道到底有没有导这个起步依赖呢
  • 代码演示,直接在引导类获取spring的ioc容器,通过名称获取redisTemplate,没有导入redis起步依赖,会报错,导入了依赖就可以成功获取
    image.png
1.1.2Condition案例一
image.png
image.png
image.png
image.png
image.png
image.png
  • user这个bean两种写法,一种是直接在类上加注解@Component,另外一种是写一个UserConfig类(这种方法实际上是注解引入第三方类的写法,第三方类无法在源码上加@Component)
  • @Conditional注解,需要写一个Condition的实现类,该实现类就一个matches方法,返回值为true,表示满足条件,加载bean。
    image.png
    image.png
1.1.3.Condition案例二

动态指定某个类存在,就加载User
image.png
image.png
image.png
image.png
image.png
  • 自定义注解,注解上面加上@Conditional以及@Conditional所有的元注解,定义一个字符串数组的属性,用于动态接收某个类的全路径。
  • Condition的自定义实现类通过matches注解元对象参数,获取自定义注解指定的属性
1.1.4.Condition在SpringBoot官方提供的jar中
image.png
image.png
  • 是否有对应的字节码文件
  • ioc容器是否有bean
  • 配置文件是否有指定的属性
  • redis自动配置
    image.png

    有字节码文件,并且ioc容器中没有bean(没有自定义redisTemplate)才帮你创建

1.1.5.配置文件有某个配置,就创建bean
image.png
image.png
image.png
1.1.6.Condition小结
image.png
1.1.7.切换内置web服务器
image.png
  • 不引入web起步依赖,直接启动引导类,启动之后就结束了
    image.png
  • 引入web起步依赖
    image.png
  • springboot提供内置服务器的种类如何查看
    image.png
    image.png

    embedded:嵌入式
    image.png
  • @ConditionalOnWebApplication当web环境下才会加载下列所有的bean
  • Tomcat工厂初始化需要两个字节码文件,这两个class必须导入tomcat坐标才会有
  • 所以,导入不同web服务器的坐标就可以实现服务器的动态切换
  • starter-web内部就依赖了tomcat的坐标
    image.png
    image.png
  • 现在想用jetty,首先要把tomcat排除掉
    image.png
    image.png
    image.png
    image.png
  • 内部还是使用的condition
1.1.8.@Enable*注解
image.png
  • 点击引导类的@SpringBootApplication注解,可以发现上面一堆注解,其中点击@SpringBootConfiguration,发现上面有@Configuration,所以引导类是一个配置类,里面可以定义bean的
  • @EnableAutoConfiguration是自动配置的核心,点击进入发现也是组合注解
    image.png
    image.png
  • 答案是不可以。为啥redisTemplate是jar包定义的bean,我们引入了redis起步依赖之后就直接可以获取到呢?
  • 演示不能获取第三方jar包中定义的bean:新建一个模块,定义User类和UserConfig类
    image.png
    image.png
    image.png

    再新建一个模块,依赖刚才的模块,直接在引导类通过ioc容器获取user报错
    image.png
    image.png
  • 解决
    image.png
    image.png
  • 不用Enable注解,获取不到这个bean,就无法开启功能
  • Enable的实质是import
1.1.9.@Import注解
image.png
image.png
image.png
image.png
image.png
image.png
  • selector返回值是一个数组,一次可以导入很多类,registar导入bean的同时可以指定对象名称
  • @SpringBootApplication--@EnableAutoConfiguration--@Import(AutoConfigurationImportSelector.class)第三种方式--AutoConfigurationImportSelector implements DeferredImportSelector--public interface DeferredImportSelector extends ImportSelector
  • AutoConfigurationImportSelector里面具体完成了什么事情
1.1.10.@EnableAutoConfiguration注解
image.png

返回的数组就是需要加载的类
image.png
image.png

定位AutoConfigurationImportSelector所在的jar包,找到spring.factories
image.png
image.png
满足条件会把这些类全部自动加载
  • 自动配置的核心
    image.png
1.1.11.自动配置案例
  • 导入Mybatis坐标,参考命名规则,spring自己的叫spring-boot-starter-xx,第三方定义的叫xx-spring-boot-starter
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
  • 查看mybatis-starter里面的坐标,包含自动配置的坐标
    image.png
  • 查看源码
    image.png

    配置文件spring.factories配置了MybatisAutoConfiguration,springboot通过import注解加载配置文件中配置的类,从而把MybatisAutoConfigurationl里面的bean全部加载
    image.png
  • 思路分析
    image.png
  • 实操redis-spring-boot-autoconfigure:
    image.png
    image.png
    image.png

    读取配置文件中redis的连接信息,如果没有配置,默认给值
    image.png
    image.png
  • 实操redis-spring-boot-starter:
    image.png
    image.png
  • 实操测试
    image.png
    image.png
1.1.12.自动配置案例升级
  • 本地启动redis服务端和客户端
    image.png
  • jedis获取到之后进行set get操作,客户端也get
    image.png
  • 配置一个错误的redis端口号6666,哪个地方用jedis,就在哪配
    image.png
  • 引导类中 jedis存储会失败 说明配置的端口生效了
  • 加两个条件,如果Jedis在,加载这个Bean,如果用户自己定义了jedis的bean,就不提供
    image.png
    image.png
  • redis官方源码
    image.png
    image.png

1.2.监听机制

js中定义一个按钮,按钮绑定一个单击事件,一点击就会触发一个函数。js里面的监听机制。按钮是一个事件源,事件发生的地方,点击的动作是事件,点击事件后执行的逻辑代码操作就是监听器。按钮绑定或者注册某个监听器之后,用户操作就会进行监听器代码的回调。一个事件源可以注册多个监听器。
image.png
image.png
  • 编写四个实现类,分别实现四个监听器接口,分别加上@Component,交给spring容器管理。启动项目发现只有ApplicationRunner和CommandLineRunner两个接口的实现类自动运行了。另外两个监听器想要运行需要配置
    image.png
  • 可以获取run方法的参数,就是运行时配置的参数
    image.png
  • 配置SpringApplicationRunListener启动项目报错
    image.png

    没有构造方法,查看框架为我们提供的SpringApplicationRunListener的实现类,里面有构造方法。写了构造方法要把Component去掉,否则报错。因为这两个监听器必须要配置才能调用,所以加不加Component也无所谓
    image.png
    image.png
  • SpringApplication是项目启动的事件源
  • 源码
    image.png

1.3.启动流程分析

1.3.1.初始化
image.png
image.png
image.png
image.png
  • primarySources引导类可以是多个
  • this.webApplicationType = WebApplicationType.deduceFromClasspath();判断是否是web环境,判断有没有Servlet对应的class
  • setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));设置初始化的东西,包含自定义的Initializers,来源SpringFactories配置文件
  • setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));设置监听器,不包含自定义监听器,因为我们定义的SpringRunListener和ApplicationListener(原生)不一样,是对他的的封装,来源SpringFactories配置文件
  • 只是获取配置文件中初始化类和监听器类的名字,放在集合中
1.3.2.run
image.png
  • StopWatch stopWatch = new StopWatch();时间控制,监控整个启动耗时
  • ConfigurableApplicationContext context = null;ioc容器声明
  • SpringApplicationRunListeners listeners = getRunListeners(args);带s相当于是容器,包含了很多个SpringApplicationRunListener,其中就包含我们自定义的MySpringApplicationRunListener
  • listeners.starting(bootstrapContext, this.mainApplicationClass);调用所有的Listener的starting方法,内部就是做了循环,我们自己定义的MySpringApplicationRunListener的starting方法就执行了
  • ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);准备环境,内部又是循环listeners.environmentPrepared(bootstrapContext, environment);我们自己定义的MySpringApplicationRunListener的environmentPrepared方法就执行了。开始准备环境的时候,信息还是比较少的
    image.png
  • configureIgnoreBeanInfo(environment);加载环境信息
  • Banner printedBanner = printBanner(environment);图标存放的位置信息
    image.png

    替换
    image.png
  • context = createApplicationContext();创建ioc容器
  • prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);准备context,导致MyApplicationContextInitializer的initialize方法执行、MySpringApplicationRunListener的contextPrepared和contextLoaded方法执行。此时ioc容器已经创建好了,但是bean还没有完全加载进来
    image.png
  • refreshContext(context);真正去配置里面找bean然后创建,过程稍慢
    image.png

    web工程可能要加载100多个bean

  • listeners.started(context);循环调用,包含我们自定义的MySpringApplicationRunListener的started方法
  • callRunners(context, applicationArguments);会使我们自定义的两个Runner执行
  • listeners.running(context);循环调用,包含我们自定义的MySpringApplicationRunListener的running方法
  • 监听
    image.png

    观察者模式有观察者和被观察者,被观察者是事件和事件源,观察者是监听器。

  • 自动配置
    image.png

2.监控

image.png
image.png

2.1.基本使用

image.png
image.png
  • 访问http://localhost:8084/actuator得到json字符串
    image.png
  • json.cn格式化字符串
    image.png
  • http://localhost:8084/actuator/info返回一个空的json字符串,获取配置文件中以info开头的属性信息
    image.png
    image.png
  • http://localhost:8084/actuator/health
    image.png
    up表示好,down表示失败。想要看更完整的信息需要配置开启
    image.png
    image.png
    磁盘空间、状态。还可以检查引入第三方组件,比如引入redis,但是及本地不启动redis服务端,查看到报错信息
    image.png
    image.png
    启动了redis服务端,再次刷新健康检查信息
    image.png

2.2.完整使用

默认是只能看info和health,其他的想看需要配置
image.png
image.png

2.3.springboot admin

image.png
  • 客户端就是想被监控的springboot项目
  • 服务端是admin的ui界面的提供
  • 客户端需要把数据信息(通过actuator获取)发送给服务端,服务端只需要提供ui界面把数据解析展示到界面上


    image.png
  • 新建server模块
    image.png
    image.png
    image.png
    image.png
  • 新建client模块
    image.png
  • 分别启动server、client
    image.png
  • 访问http://localhost:9000/
    image.png
  • client添加controller
    image.png

    可以在admin页面中查看uri被访问的次数
    image.png
  • idea简单看一下
    image.png

3.项目部署

image.png

3.1.jar包

image.png
image.png

3.2.war包

image.png

<finalName>springboot</finalName>表示最终打的war包名字
image.png
  • 配置文件中server.port=8888不再生效,因为这个配置是针对于内置tomcat
    image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容