SpringBoot SpringBoot 原理篇 1 自动配置 1.10 bean 的加载方式【八】
创始人
2024-02-18 11:23:55
0

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 {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {//后处理bean 定义注册,参数和第七种那个注册一样BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();beanDefinitionRegistry.registerBeanDefinition("yellow",beanDefinition);}@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {//第一个参数就是我们之前看的元数据,而且他还有一个参数,也就是这种方式比第六种更强大@Overridepublic 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 {//第一个参数就是我们之前看的元数据,而且他还有一个参数,也就是这种方式比第六种更强大@Overridepublic 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 {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {//后处理bean 定义注册,参数和第七种那个注册一样BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl4.class).getBeanDefinition();beanDefinitionRegistry.registerBeanDefinition("bookService",beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
}

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

直接运行

在这里插入图片描述

MyPostProcessor说了算

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

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

保障性工作

这就是它最牛的地方

OK,回顾一下

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

在这里插入图片描述

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

1.10.2 小结
  1. xml+
  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接口

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...