SpringBoot 开发总结思考(二)

简介: 模块装配:假设要注入MongoDB,那么就加上@Configuration注解,有可能一个配置类没办法解决某个方向的问题,往往是很多@Configuration的类组合在一起SpringBoot是使用Enable注解,然后再通过@import导入Selector,通过Selector读取 .factories 文件,最终加载的Configuration

SpringBoot 开发总结思考(二)


1、SpringBoot 自动配置(装配)


.原理是什么?

https://blog.csdn.net/u014745069/article/details/83820511


.为什么要有?


2、SpringBoot 是如何把一些库加入到IOC中的?


@Component、@Configuration 适用于自定义业务,而SpringBoot考虑的是如何把第三方以及自己的库加入到IOC中


@SpringBootApplication 就是一个超级大的配置类,其中包含的注解会分解小的配置类模块


3、@EnableAutoConfiguration :SpringBoot中最核心的注解


主要作用就是为了加载N多的Bean,然后将其放入IOC中


部分的属性是写在配置文件中的,允许从配置文件中更改配置的Bean的属性等


必须要能把Bean加入到IOC中


@Import(AutoConfigurationImportSlector.class)
AutoConfigurationImportSlector 中有一个非常重要的方法:selectImports


.核心方法,用于加载第三方配置类


要加载的所有的配置都在spring.factories中记录,SpringBoot 会读取该文件所有的Bean,然后再将这些Bean加入到IOC中


spring.factories 中的配置类与SpringBoot的自动加载机制是如何关联起来的?


.核心就是  .factories 配置文件


4、第三方的Bean也加了 @Configuration,为什么还要通过  @EnabledAutoConfiguration +  .factories 的机制加入到IOC中?


如果只是加了 @Configuration ,相当于直接把源码加入到了IOC中


第三方SDK也直接将源码加入到IOC中吗?显然不可能


5、以Enabled 开头的注解,被称之为模块装配


模块装配:假设要注入MongoDB,那么就加上@Configuration注解,有可能一个配置类没办法解决某个方向的问题,往往是很多@Configuration的类组合在一起


SpringBoot是使用Enable注解,然后再通过@import导入Selector,通过Selector读取  .factories 文件,最终加载的Configuration


6、@EnableAutoConfiguration 最终还是要加载@Configuration


比起自定义@Configuration ,还多了一步@Import的Selector



修改前面的 HeroConfiguration 类,并将所有的@Component去掉


@Configuration
public class HeroConfiguration {
    //@Bean
    public ISkill diana(){
        return new Diana("Diana", 1);
    }
    @Bean
    public ISkill irelia(){
        return new Irelia();
    }
}


但现在的结构仍然可以自动将HeroConfiguration 加载到IOC中,因为启动类的@SpringBootApplication包含了ComponentScan,当前包下的标注了@Component/@Configuration的都会被加入到IOC中


自定义一个 启动类 LOLApplication,并将启动类的@SpringBootApplication注解去掉


@ComponentScan
public class LolApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(LolApplication.class)
                .run(args);
        ISkill iSkill = (ISkill) context.getBean("irelia");
        iSkill.r();
    }
}


使用另一种@Import方式


.最简单的一种方式就是,将配置类传入到Import中


@Import(HeroConfiguration.class)


此时会报错,unable to start web service,为什么加@ComponentScan就可以?


在默认情况下,上下文会启动Web服务器,如果不主动关闭Web服务器的模式,它就会自动启动


之所以加@ComponentScan可以,是因为该注解会扫描和web服务器相关配置的


但注释之后使用@Import只是导入了一个配置类,所以很多SpringBoot内置的配置都是没有导入到IOC中


增加WebApplicationType.NONE  把服务器关闭


@Import(HeroConfiguration.class)
public class LolApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(LolApplication.class)
                .web(WebApplicationType.NONE)
                .run(args);
        ISkill iSkill = (ISkill) context.getBean("irelia");
        iSkill.r();
    }
}


@Import 第二个用法


  • 传入的参数增加一个Selector

新增一个Selector:LolConfigurationSelector


public class LolConfigurationSelector implements ImportSelector {
    /**
     * 该接口要求返回一个数组,这个数组是一个字符串类型
     * @param annotationMetadata
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        /**
         * 其实还是在返回元类的名字,一次可以导入多个配置类
         */
        return new String[] {HeroConfiguration.class.getName()};
    }
}


更改启动类 LolApplication


@Import(LolConfigurationSelector.class)
public class LolApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(LolApplication.class)
                .web(WebApplicationType.NONE)
                .run(args);
        ISkill iSkill = (ISkill) context.getBean("irelia");
        iSkill.r();
    }
}


7、SpringBoot自动装配的spring.factories文件


新建一个Enable  注解类:EnableLolConfiguration(相当于一个模块装配)


元注解需要标注一些注解


@Retention(RetentionPolicy.RUNTIME) :用来修饰注解,是注解的注解

@Target(ElementType.TYPE) : 被描述的注解可以用在什么地方

@Documented : 表明这个注释是由 javadoc记录的


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(LolConfigurationSelector.class)
public @interface EnableLolConfiguration {
}


修改  LolApplication


@EnableLolConfiguration
public class LolApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(LolApplication.class)
                .web(WebApplicationType.NONE)
                .run(args);
        ISkill iSkill = (ISkill) context.getBean("irelia");
        iSkill.r();
    }
}


8、@EnableAutoConfiguration 为什么要从 .factories 文件读取?


一个模块具体要加载哪些配置类,是一个变化的过程。


既然是变化,那么就应该被隔离到配置文件中


但不是所有在  .factories  文件中的配置都会被导入,所以这些配置文件中的类被称为   候选配置类


满足一定条件之后,配置类才会被导入到IOC中


AutoConfigurationImportSelector中有一个很重要的方法就是:getCandidateConfigurations(获取所有的候选配置类名)


9、Java SPI 机制解析


SpringBoot自动装配机制其实是SPI机制/思想的应用


SPI 机制/思想:


. Service Provider Interface (服务发现机制)


SPI 就是应对变化,一个系统中往往会依赖很多模块,这些模块又是有各种各样不同实现方案的,有时候需要灵活的替换实现方案


首先有调用方,再有标准服务接口,服务接口下可能会有很多不同的实现(方案A、方案B),不同的方案遵循标准的服务接口,就可以被调用方调用;换句话说就是在Java中SPI,等同于基于接口编程。不基于Interface接口编程,无法提供标准服务接口,也无法将众多方案的具体隐藏在抽象之后


SpringBoot自动加载机制就是SPI机制/思想的衍生


对于一个方案来说,完全可以通过修改 .factories文件去切换不同的配置类,切换不同配置类的实质就是在切换众多的方案之一


10、再谈如何解决变化?


既然有了@Primary、条件注解之后,为什么还要有SPI机制/思想?


首先肯定的是,无论是SPI 还是@Primary、条件注解机制,都是为了解决变化而生


但是两者关注模块的细粒度是不一样的


.@Primary、条件注解  关注的是类/对象层面的变化,关注的具体/粒度非常小


.SPI 关注的点非常抽象,是整体解决方案的切换;有时候通过简单的类替换是没办法解决问题的

举个栗子


.装修的时候将1木质地板换成大理石地板(@Primary、条件注解)


.房子的整体装修风格发生了变化(SPI)


两者应对变化没有明显的界限


11、SpringBoot自动装配到底做了一件什么事情?


SpringBoot 较其他框架多出了一个IOC容器,SpringBoot自动装配真正解决了如何发现这些Bean并把这些配置的Bean要能够加入到IOC容器中,如果没有IOC,则需要手动在XML指定

目录
相关文章
|
5天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
47 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
11天前
|
Java 数据库连接 数据库
Springboot整合mybatisPlus开发
MyBatis-Plus是一个MyBatis的增强工具,旨在简化开发和提高效率。它在不修改原有MyBatis的基础上提供额外功能。要将MyBatis-Plus集成到SpringBoot项目中,首先通过Maven添加mybatis-plus-boot-starter和相应数据库驱动依赖,然后配置application.yml中的数据库连接信息,并指定Mapper类的扫描路径。Mapper接口可继承BaseMapper实现基本的CRUD操作。
|
11天前
|
前端开发 JavaScript Java
Springboot框架整合jsp开发【干货满满】
该文介绍了如何在Spring Boot中集成JSP,需包含`spring-boot-starter-web`、`tomcat-embed-jasper`和`jstl`三个依赖。配置Spring Boot寻找JSP的位置,设置`spring.mvc.view.prefix`为`/WEB-INF/jsp/`,`spring.mvc.view.suffix`为`.jsp`。JSP文件应放在`src/main/webapp/WEB-INF/jsp/`下。
|
13天前
|
Web App开发 前端开发 Java
SpringBoot配置HTTPS及开发调试
在实际开发过程中,如果后端需要启用https访问,通常项目启动后配置nginx代理再配置https,前端调用时高版本的chrome还会因为证书未信任导致调用失败,通过摸索整理一套开发调试下的https方案,特此分享
20 0
SpringBoot配置HTTPS及开发调试
|
13天前
|
IDE Java 开发工具
Spring Boot DevTools:加速开发的热部署工具
【4月更文挑战第28天】在Spring Boot的开发过程中,快速反馈和效率至关重要。Spring Boot DevTools是一个为开发者设计的模块,支持热部署(hot swapping),能够实现应用的快速重启和自动重载,极大地提高了开发效率。本篇博客将介绍Spring Boot DevTools的核心概念,并通过具体的实战示例展示如何在开发过程中利用这一工具。
23 0
|
18天前
|
Java Maven Kotlin
[AIGC] 请你写一遍博客介绍 “使用idea+kotinlin+springboot+maven 结合开发一个简单的接口“,输出markdown格式,用中文回答,请尽可能详细
[AIGC] 请你写一遍博客介绍 “使用idea+kotinlin+springboot+maven 结合开发一个简单的接口“,输出markdown格式,用中文回答,请尽可能详细
|
24天前
|
人工智能 前端开发 Java
Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
智慧导诊解决盲目就诊问题,减轻分诊工作压力。降低挂错号比例,优化就诊流程,有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位,了解对应病症信息和推荐就医科室。
187 10
|
24天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
34 0
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
1月前
|
开发框架 Java 测试技术
XwFast,我开发了一个基于SpringBoot和MyBatisPlus的敏捷开发框架!
XwFast,我开发了一个基于SpringBoot和MyBatisPlus的敏捷开发框架!
33 1
|
2月前
|
XML Java 开发者
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging
41 1