SpringBoot SpringBoot 原理篇 1 自动配置 1.10 bean 的加载方式【八】

news2025/3/1 0:58:10

SpringBoot

【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】

SpringBoot 原理篇

文章目录

      • SpringBoot
      • SpringBoot 原理篇
      • 1 自动配置
        • 1.10 bean 的加载方式【八】
          • 1.10.1 BeanDefinitionRegistryPostProcessor
          • 1.10.2 小结

1 自动配置

1.10 bean 的加载方式【八】

1.10.1 BeanDefinitionRegistryPostProcessor

之前我们又使用 ImportBeanDefinitionRegistrar 接口来实现了bean 的加载

在这里插入图片描述

比ImportSelector 接口更高端了些,【还有吗?】【还有第八种】

来个新的类

package com.dingjiaxiong.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

/**
 * ClassName: MyPostProcessor
 * date: 2022/10/24 16:41
 *
 * @author DingJiaxiong
 */


public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        //后处理bean 定义注册,参数和第七种那个注册一样
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
        beanDefinitionRegistry.registerBeanDefinition("yellow",beanDefinition);

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

可以看到,它和第七种特别像,直接把第七种贴过来都能用了,问题就有了, 为啥叫什么后处理?

一点一点来

先来一个配置类

package com.dingjiaxiong.config;

import com.dingjiaxiong.bean.MyRegistrar;
import com.dingjiaxiong.service.impl.BookServiceImpl1;
import org.springframework.context.annotation.Import;

/**
 * ClassName: SpringConfig8
 * date: 2022/10/24 14:52
 *
 * @author DingJiaxiong
 */

@Import(BookServiceImpl1.class)
public class SpringConfig8 {
}

这个图书实现类,已经是好久之前的了,笔者这里再贴一下

package com.dingjiaxiong.service.impl;

import com.dingjiaxiong.service.BookService;

/**
 * ClassName: BookServiceImpl1
 * date: 2022/10/24 10:35
 *
 * @author DingJiaxiong
 */


public class BookServiceImpl1 implements BookService {
    
    @Override
    public void check() {
        System.out.println("book service 1...");
    }
}

OK,再来个运行类

package com.dingjiaxiong.app;

import com.dingjiaxiong.config.SpringConfig7;
import com.dingjiaxiong.config.SpringConfig8;
import com.dingjiaxiong.service.BookService;
import com.dingjiaxiong.service.impl.BookServiceImpl1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * ClassName: App8
 * date: 2022/10/24 13:42
 *
 * @author DingJiaxiong
 */

public class App8 {

    public static void main(String[] args) {

        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig8.class);
        BookService bookService = ctx.getBean("bookService", BookService.class);

        bookService.check();
    }

}

修改一下实现类,把它定义成一个bean

package com.dingjiaxiong.service.impl;

import com.dingjiaxiong.service.BookService;
import org.springframework.stereotype.Service;

/**
 * ClassName: BookServiceImpl1
 * date: 2022/10/24 10:35
 *
 * @author DingJiaxiong
 */

@Service("bookService")
public class BookServiceImpl1 implements BookService {

    @Override
    public void check() {
        System.out.println("book service 1...");
    }
}

在这里插入图片描述

现在结构就很清晰了,所有都在针对实现类1

OK,直接运行

在这里插入图片描述

调用成功【这和第八种方法暂时没关系,就只是一个简单的bean 调用】

接下来加上我们写的类

在这里插入图片描述

并且修改一下这个类

package com.dingjiaxiong.bean;

import com.dingjiaxiong.service.impl.BookServiceImpl2;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * ClassName: MyRegistrar
 * date: 2022/10/24 16:24
 *
 * @author DingJiaxiong
 */


public class MyRegistrar implements ImportBeanDefinitionRegistrar {


    //第一个参数就是我们之前看的元数据,而且他还有一个参数,也就是这种方式比第六种更强大
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        //1. 使用元数据进行判定【这里就不判了】
        //初始化BeanDefinition对象
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl2.class).getBeanDefinition();

        registry.registerBeanDefinition("bookService",beanDefinition);
    }
}

也就是说,我现在本身导了个 1 ,但是又用ImportBeanDefinitionRegistrar 导了个2

直接运行看看结果

在这里插入图片描述

结果很明显,它既没报错, 而且调用了实现类2的方法

实现类2 BookServiceImpl2

现在的意思就是1 被覆盖了,好家伙

在这里插入图片描述

这样子的意义是什么?前面的1 就是默认技术【比如内嵌的Tomcat、内嵌的数据源…】

而后面就是我们自己定义了一个【那万一项目组人多】

举个栗子

package com.dingjiaxiong.bean;

import com.dingjiaxiong.service.impl.BookServiceImpl2;
import com.dingjiaxiong.service.impl.BookServiceImpl3;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * ClassName: MyRegistrar2
 * date: 2022/10/24 16:24
 *
 * @author DingJiaxiong
 */


public class MyRegistrar2 implements ImportBeanDefinitionRegistrar {


    //第一个参数就是我们之前看的元数据,而且他还有一个参数,也就是这种方式比第六种更强大
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        //1. 使用元数据进行判定【这里就不判了】
        //初始化BeanDefinition对象
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl3.class).getBeanDefinition();

        registry.registerBeanDefinition("bookService",beanDefinition);
    }
}

现在的情况就是,有两个开发者,都对同一个技术进行了实现,然后!很巧的是

在这里插入图片描述

它俩都摆在了这儿,现在会是谁生效,直接运行

在这里插入图片描述

妙了,3 生效了

挪下位置

在这里插入图片描述

OK,效果很明显,和加载顺序有关【现在真正的问题来了,现在是配置的顺序说了算,没有东西能够管一下它俩?万一以后更多,那不乱死?】

OK,第八种加载方式就是干这事儿的

把它也加上

在这里插入图片描述

package com.dingjiaxiong.bean;

import com.dingjiaxiong.service.impl.BookServiceImpl4;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

/**
 * ClassName: MyPostProcessor
 * date: 2022/10/24 16:41
 *
 * @author DingJiaxiong
 */


public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        //后处理bean 定义注册,参数和第七种那个注册一样
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl4.class).getBeanDefinition();
        beanDefinitionRegistry.registerBeanDefinition("bookService",beanDefinition);

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

这个加载的4 ,OK,终局之战

直接运行

在这里插入图片描述

MyPostProcessor说了算

这就是“后” 的意义,前面的全整完之后,我一来,前面的全部没用 了

【这种后处理的机制有什么用?】

保障性工作

这就是它最牛的地方

OK,回顾一下

导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean,
实现对容器中bean的最终裁定

在这里插入图片描述

其实还有加载方式,但是这些够用了

1.10.2 小结
  1. xml+<bean/>
  2. xml:context+注解(@Component+4个@Bean)
  3. 配置类+扫描+注解(@Component+4个@Bean)
  • @Bean定义FactoryBean接口
  • @ImportResource
  • @Configuration注解的proxyBeanMethods属性
  1. @Import导入bean的类
  • @Import导入配置类
  1. AnnotationConfigApplicationContext调用register方法
  2. @Import导入ImportSelector接口
  3. @Import导入ImportBeanDefinitionRegistrar接口
  4. @Import导入BeanDefinitionRegistryPostProcessor接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ABAP学习笔记之——第五章:内表

内表&#xff1a; 内表是可以在程序内部定义且使用的表&#xff0c;属于本地表。 与C语言比较&#xff1a; C语言的数组和内表比较&#xff1a; 内表是动态数组(Dynamic Data Object) INITIALSIZE 语句并非实际占用内存空间&#xff0c;而只是预约(RESERVE)内存空间。 创建…

Python每日一练 06

Python每日一练 06 文章目录Python每日一练 06while循环实例一、斐波那契数列前n项实例二、Leibniz公式计算圆周率while循环 循环结构表示程序重复执行某个或某些操作&#xff0c;直到某条件为假&#xff08;或为真&#xff09;时才可终止循环。 在问题求解过程中&#xff0c;…

[算法笔记]最长递增子序列和编辑距离

最长递增子序列 例如对于 a[] {2,1,5,3,6,4,8,9,7}其最长递增子序列为{1,3,4,8,9}所以长度&#xff08;或者说是结果&#xff09;为5。 对于a[0...n-1]&#xff0c;用dp[i]表示a[0...i]中以a[i]结尾的最长递增子序列长度 其状态状态方程&#xff1a; dp[i]1 // 0≤i≤…

【无人机通信优化】基于粒子群算法的多跳无线网络部署优化附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

[附源码]SSM计算机毕业设计时事资讯平台JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Date对象

文章目录Date日期对象Date对象的创建格式化日期3.获取Date总的毫秒数(时间戳)&#xff0c;是距离1970年1月1日过了多少毫秒数。二&#xff1a;常用时间获取方法三&#xff1a;日期设置方法四&#xff1a;时间转字符串菜鸟工具&#xff1a;https://www.runoob.com/jsref/jsref-o…

在Express框架使用ORM模型访问关系型数据库

一、ORM模型&#xff1a;设计思想&#xff0c;主要目的是简化计算机程序访问数据库 1、ORM&#xff1a;对象关系模型(对象关系映射) Object Releastion Model,将程序中的对象和数据库中关系(表格)进行映射。可以使开发者在程序中方便的对数据库进行操作(用户在程序操作对对象实…

【网页制作课作业】用HTML+CSS制作一个简单的学校网页(9页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

一文熟悉 Go 的分支结构(if - else-if - else、switch)

哈喽大家好&#xff0c;我是陈明勇&#xff0c;今天分享的知识是 Go 的分支结构。如果本文对你有帮助&#xff0c;不妨点个赞&#xff0c;如果你是 Go 语言初学者&#xff0c;不妨点个关注&#xff0c;一起成长一起进步&#xff0c;如果本文有错误的地方&#xff0c;欢迎指出&a…

Python爬虫脚本+XML解析实现自动保存某商城的商品图

文章目录 1.背景介绍2.代码分析2.1.创建图片保存的目录2.2.定一下载函数2.3.发送请求解析数据2.源代码(全)1.背景介绍 Python脚本可以实现数据的爬取,而XML可以解析网页数据。将Python爬虫脚本与XML解析功能相结合,可以实现自动保存某商城的商品图功能。 注:本功能仅用于…

基于AlexNet卷积神经网络的手写体数字识别系统研究-附Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、手写体数字识别系统✳️ 2.1 MNIST 数据集✳️ 2.2 CNN✳️ 2.3 网络训练✳️ 三、手写体数字识别结果✳️ 四、参考文献✳️ 五、Matlab代码获取✳️ 一、引言 手写数字识别是计算机视觉领域中的一个重要应用&#xff0c;已广泛应用在很…

电动汽车充电站的最优选址matlab程序

​摘要&#xff1a;以规划期内充电站的总成本 &#xff08;包括投资、运行和维护成本&#xff09;和网损费用之和最小为目标&#xff0c;考虑了相关的约束条件&#xff0c;构造了电动汽车充电站最优规划的数学模型&#xff0c; 关键词&#xff1a;电动汽车&#xff1b;充电站&a…

角色扮演?一款跨平台可移植开源游戏

程序员宝藏库&#xff1a;gitee.com/sharetech_lee/CS-Books-Store DevWeekly收集整理每周优质开发者内容&#xff0c;包括开源项目、资源工具、技术文章等方面。 每周五定期发布&#xff0c;同步更新到 知乎&#xff1a;Jackpop 。 欢迎大家投稿&#xff0c;提交issue&#…

支付系统设计概览

前言 就个人对支付的一些理解和经验&#xff0c;在此编辑出来和大家一起交流分享。请大佬多多指正。 在各种互联网场景中&#xff0c;牵扯到交易的情况&#xff0c;大多都需要支付系统的支持。支付系统往往不是一蹴而就的&#xff0c;往往都是随着业务的不断扩展&#xff0c;…

【python】面向对象程序设计(基础篇)

个人主页&#xff1a;天寒雨落的博客_CSDN博客-初学者入门C语言,python,数据库领域博主 &#x1f4ac; 热门专栏&#xff1a;python_天寒雨落的博客-CSDN博客 ​每日赠语&#xff1a;没有窘迫的失败&#xff0c;就不会有自豪的成功&#xff1b;失败不可怕&#xff0c;只要能从失…

浅识vue的虚拟DOM和渲染器

虚拟DOM本质上是对DOM的抽象描述&#xff0c;就是一个普通的js对象。他身上的属性要比真实DOM的属性要少得多。 在一定情况下&#xff0c;使用虚拟DOM的性能要逊于直接使用真实DOM。 例如&#xff0c;在页面一开始的时候&#xff0c;Vue需要先通过生成虚拟DOM树&#xff0c;在…

【雷达通信】雷达探测项目仿真附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

《恋上数据结构与算法》第1季:链表原理实现(图文并茂)

数据结构与算法的学习笔记目录&#xff1a;《恋上数据结构与算法》的学习笔记 目录索引链表原理实现一、链表二、链表的设计三、链表的接口设计四、链表接口的实现1. 索引越界的判断2. 根据索引查找指定节点3. 添加数据4. 插入元素5. 删除元素6. 清空元素7. 修改元素8. 查找元素…

傻白入门芯片设计,RDL/Interposer/EMIB/TSV(三)

目录 一、再分配层&#xff08;RDL&#xff09; 二、硅中介层&#xff08;Si Interposer&#xff09;&#xff1a;Active and Passive 三、嵌入式硅桥&#xff08;EMIB&#xff09; 四、硅通孔 TSV&#xff08;Through Silicon Vias&#xff09; 一、再分配层&#xff08;R…

CCF CSP认证2022年6月 归一化处理、寻宝!大冒险!、光线追踪

这是我第一次参加了这次CSP考试&#xff0c;300分&#xff0c;写了124三题&#xff0c;模拟题到现在都没看过题面没看&#xff0c;笑&#xff0c;t4写成模拟加数据结构&#xff0c;200行&#xff0c;因为一个小错误调了1h&#xff0c;错失了大好机会。考试环境的VSC配置的字体太…