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

目录
相关文章
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
153 0
|
7月前
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
508 7
|
7月前
|
人工智能 Java 数据库
飞算 JavaAI:革新电商订单系统 Spring Boot 微服务开发
在电商订单系统开发中,传统方式耗时约30天,需应对复杂代码、调试与测试。飞算JavaAI作为一款AI代码生成工具,专注于简化Spring Boot微服务开发。它能根据业务需求自动生成RESTful API、数据库交互及事务管理代码,将开发时间缩短至1小时,效率提升80%。通过减少样板代码编写,提供规范且准确的代码,飞算JavaAI显著降低了开发成本,为软件开发带来革新动力。
|
8月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
768 79
|
6月前
|
供应链 JavaScript BI
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发
这是一款专为小微企业打造的 SaaS ERP 管理系统,基于 SpringBoot+Vue+ElementUI+UniAPP 技术栈开发,帮助企业轻松上云。系统覆盖进销存、采购、销售、生产、财务、品质、OA 办公及 CRM 等核心功能,业务流程清晰且操作简便。支持二次开发与商用,提供自定义界面、审批流配置及灵活报表设计,助力企业高效管理与数字化转型。
613 2
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发
|
5月前
|
Java API 微服务
Java 21 与 Spring Boot 3.2 微服务开发从入门到精通实操指南
《Java 21与Spring Boot 3.2微服务开发实践》摘要: 本文基于Java 21和Spring Boot 3.2最新特性,通过完整代码示例展示了微服务开发全流程。主要内容包括:1) 使用Spring Initializr初始化项目,集成Web、JPA、H2等组件;2) 配置虚拟线程支持高并发;3) 采用记录类优化DTO设计;4) 实现JPA Repository与Stream API数据访问;5) 服务层整合虚拟线程异步处理和结构化并发;6) 构建RESTful API并使用Springdoc生成文档。文中特别演示了虚拟线程配置(@Async)和StructuredTaskSco
670 0
|
8月前
|
人工智能 自然语言处理 前端开发
20分钟上手DeepSeek开发:SpringBoot + Vue2快速构建AI对话系统
本文介绍如何使用Spring Boot3与Vue2快速构建基于DeepSeek的AI对话系统。系统具备实时流式交互、Markdown内容渲染、前端安全防护等功能,采用响应式架构提升性能。后端以Spring Boot为核心,结合WebFlux和Lombok开发;前端使用Vue2配合WebSocket实现双向通信,并通过DOMPurify保障安全性。项目支持中文语义优化,API延迟低,成本可控,适合个人及企业应用。跟随教程,轻松开启AI应用开发之旅!
|
10月前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
416 6
|
10月前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
259 5
|
10月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
467 2