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指定

目录
相关文章
|
7天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
25 0
|
1月前
|
前端开发 Java
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
文章通过一个表白墙/留言墙的初级SpringBoot项目实例,详细讲解了如何进行前后端开发,包括定义前后端交互接口、创建SpringBoot项目、编写前端页面、后端代码逻辑及实体类封装的全过程。
74 3
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
1月前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
172 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
2月前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的医院门诊预约挂号系统
基于Java+Springboot+Vue开发的医院门诊预约挂号系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的门诊预约挂号管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
136 2
基于Java+Springboot+Vue开发的医院门诊预约挂号系统
|
1月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
27 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
18天前
|
JavaScript 前端开发 Java
SpringBoot_web开发-webjars&静态资源映射规则
https://www.91chuli.com/ 举例:jquery前端框架
15 0
|
1月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
42 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
1月前
|
开发框架 Java API
「SpringBrick快速入门指南」:一款基于Spring Boot的高级插件化开发框架
「SpringBrick快速入门指南」:一款基于Spring Boot的高级插件化开发框架
52 0
|
1月前
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。
|
1月前
|
JavaScript 前端开发 数据可视化
【SpringBoot+Vue项目实战开发】2020实时更新。。。。。。
【SpringBoot+Vue项目实战开发】2020实时更新。。。。。。
47 0