位置: IT常识 - 正文

【Spring Boot】SpringBoot设计了哪些可拓展的机制?(spring boot s)

编辑:rootadmin
【Spring Boot】SpringBoot设计了哪些可拓展的机制? 文章目录前言SpringBoot核心源码拓展Initializer拓展监听器ApplicationListenerBeanFactory的后置处理器 & Bean的后置处理器AOP其他的拓展点前言 当我们引入注册中心的依赖,比如nacos的时候,当我们启动springboot,这个服务就会根据配置文件自动注册到注册中心中,这个动作是如何完成的? 注册中心使用了SpringBoot中的事件监听机制,在springboot初始化的时候完成服务注册SpringBoot核心源码public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { ... this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); // Servlet this.webApplicationType = WebApplicationType.deduceFromClasspath(); this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class)); // 注意这里,Initializers this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 注意这里 Listeners this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = this.deduceMainApplicationClass(); }

推荐整理分享【Spring Boot】SpringBoot设计了哪些可拓展的机制?(spring boot s),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:spring boot poi,spring boot 揭秘,spring boot s,spring spring boot,spring-boot-actuator,spring boot+ssm,spring spring boot,spring boot spi,内容如对您有帮助,希望把文章链接给更多的朋友!

我们可以看到空的SpringBoot项目有一些initializers以及一些listeners

注意这两行,换言之我们只要实现这两个类就可以自定义拓展SpringBoot了!

这里和手写Starter都是对SpringBoot的拓展,有兴趣的小伙伴可以看这篇文章

拓展Initializer

再看这张图

我们需要研究一下ApplicationContextInitializer这个类:

@FunctionalInterfacepublic interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> { /** * Initialize the given application context. * @param applicationContext the application to configure */ void initialize(C applicationContext); }

这样就很清晰了,我们尝试手写一个继承类:

public class DemoInitializer implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext applicationContext) { System.out.println("自定义初始化器执行..."); ConfigurableEnvironment environment = applicationContext.getEnvironment(); Map<String, Object> map = new HashMap<>(1); map.put("name", "sccccc"); environment.getPropertySources().addLast(new MapPropertySource("DemoInitializer", map)); System.out.println("DemoInitializer execute, and add some property"); } }

通过SPI机制将自定义初始化器交给list集合initializers

然后再debug,就会发现:

【Spring Boot】SpringBoot设计了哪些可拓展的机制?(spring boot s)

最后经过一次回调:

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ... applyInitializers(context); ... // Add boot specific singleton beans 下面是beanFactory的操作

遍历所有的初始化器,然后

/*** Apply any {@link ApplicationContextInitializer}s to the context before it is * refreshed. * @param context the configured ApplicationContext (not refreshed yet) * @see ConfigurableApplicationContext#refresh() */ @SuppressWarnings({ "rawtypes", "unchecked" }) protected void applyInitializers(ConfigurableApplicationContext context) { for (ApplicationContextInitializer initializer : getInitializers()) { Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class); Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); initializer.initialize(context); } }

流程:

拓展监听器ApplicationListener

@FunctionalInterfacepublic interface ApplicationListener<E extends ApplicationEvent> extends EventListener { /** * Handle an application event. */ void onApplicationEvent(E event); /** * Create a new {@code ApplicationListener} for the given payload consumer. */ static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) { return event -> consumer.accept(event.getPayload()); } }

这里和上面initializer一样,就不演示了

BeanFactory的后置处理器 & Bean的后置处理器

Spring Boot解析配置成BeanDefinition的操作在invokeBeanFactoryPostProcessors方法中 自定义BeanFactory的后置处理器:

@Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Arrays.asList(beanFactory.getBeanDefinitionNames()) .forEach(beanDefinitionName -> System.out.println(beanDefinitionName)); System.out.println("BeanFactoryPostProcessor..."); }}

自定义Bean的后置处理器:

@Componentpublic class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("userController")){ System.out.println("找到了userController: "+bean); } return null; }}AOP

这个相信大家用的比较多,可以自定义切面:

@Aspect@Componentpublic class LogAspect {// 切入点 Pointcut 可以对Service服务做切面@Pointcut("execution(* com.example.service.*.*(..))")public void mypointcut(){}// 前置通知@Before(value = "mypointcut()")public void before(JoinPoint joinPoint){ System.out.println("[前置通知] 准备开始记录日志..."); System.out.println("[前置通知] 目标类是: "+joinPoint.getTarget()); System.out.println("[前置通知] 目标方法是: "+joinPoint.getSignature().getName());}// 后置通知@AfterReturning(value = "mypointcut()")public void afterReturning(JoinPoint joinPoint){ System.out.println("[后置通知] 记录日志完成..."); System.out.println("[后置通知] 目标类是: "+joinPoint.getTarget()); System.out.println("[后置通知] 目标方法是: "+joinPoint.getSignature().getName());}/*@Around(value = "mypointcut()")public void around(ProceedingJoinPoint joinPoint){ System.out.println("[环绕通知] 日志记录前的操作..."); try { joinPoint.proceed(); System.out.println("[环绕通知] 日志记录后的操作..."); System.out.println("[环绕通知] "+joinPoint.getTarget()); System.out.println("[环绕通知] "+joinPoint.getSignature().getName()); } catch (Throwable throwable) { System.out.println("[环绕通知] 发生异常的操作..."); throwable.printStackTrace(); }finally { ... }}其他的拓展点Banner

方法地址: printBanner(env)->bannerPrinter.print->SpringBootBanner#printBanner 可以在resource目录下建立banner.txt文件夹实现自定义Banner

Runners

流程:

自定义:

@Componentpublic class JackApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("JackApplicationRunner..."); }}
本文链接地址:https://www.jiuchutong.com/zhishi/300352.html 转载请保留说明!

上一篇:OpenAI GPT-3模型详解(gpt3 模型大小)

下一篇:浅谈DNS域名解析的过程(dns域名解析两种方式)

  • 早期最简单的赚钱方式,你造吗?(最简单最赚钱的行业)

    早期最简单的赚钱方式,你造吗?(最简单最赚钱的行业)

  • 很多简单的道理不是谁都明白(很多简单的道理都不懂是什么原因)

    很多简单的道理不是谁都明白(很多简单的道理都不懂是什么原因)

  • 爱奇艺vip可以同时几个人在线呢(爱奇艺会员可以两个人一起同步看吗)

    爱奇艺vip可以同时几个人在线呢(爱奇艺会员可以两个人一起同步看吗)

  • 华为nm存储卡和普通存储卡区别(华为nm存储卡和TF存储卡区别)

    华为nm存储卡和普通存储卡区别(华为nm存储卡和TF存储卡区别)

  • qq为什么加不了好友(qq为什么加不了好友了qq也搜不到)

    qq为什么加不了好友(qq为什么加不了好友了qq也搜不到)

  • 手机一充电就有广告推送怎么办(手机一充电就有滴答声)

    手机一充电就有广告推送怎么办(手机一充电就有滴答声)

  • 怎么用手机识别花草(怎么用手机识别颜色)

    怎么用手机识别花草(怎么用手机识别颜色)

  • iphonexr双卡支持同一家运营商吗(iphonexr支持双卡的版本)

    iphonexr双卡支持同一家运营商吗(iphonexr支持双卡的版本)

  • 在word文档中怎么在方框里面打勾(在word文档中怎么查找关键字)

    在word文档中怎么在方框里面打勾(在word文档中怎么查找关键字)

  • ipad a1416是ipad几代(pad a1416是几代)

    ipad a1416是ipad几代(pad a1416是几代)

  • 8g是多少mb(80g是多少mb)

    8g是多少mb(80g是多少mb)

  • 抖音不给流量的原因(抖音不给流量的说说)

    抖音不给流量的原因(抖音不给流量的说说)

  • va和ips差距大吗(va 和 ips)

    va和ips差距大吗(va 和 ips)

  • 便捷访问有什么用(便捷访问有什么关)

    便捷访问有什么用(便捷访问有什么关)

  • 计算机网络系统是由(计算机网络系统的功能有)

    计算机网络系统是由(计算机网络系统的功能有)

  • 苹果ipad哪款可以插卡(看看哪款ipad适合你)

    苹果ipad哪款可以插卡(看看哪款ipad适合你)

  • 抖音橱窗类目可以更改吗(抖音橱窗商品分类有哪些)

    抖音橱窗类目可以更改吗(抖音橱窗商品分类有哪些)

  • 为什么文档不能编辑了(为什么文档不能修改)

    为什么文档不能编辑了(为什么文档不能修改)

  • 南方gps使用步骤(南方gps使用步骤视频)

    南方gps使用步骤(南方gps使用步骤视频)

  • miui10怎么看手机痕迹(小米10如何查看)

    miui10怎么看手机痕迹(小米10如何查看)

  • 一加7t是什么牌子的手机(一加7是什么手机品牌)

    一加7t是什么牌子的手机(一加7是什么手机品牌)

  • 拼多多怎么设置备注(拼多多怎么设置匿名评价)

    拼多多怎么设置备注(拼多多怎么设置匿名评价)

  • 怎样把文件发送到qq里(怎样把文件发送到微信)

    怎样把文件发送到qq里(怎样把文件发送到微信)

  • 蓝牙耳机lr什么意思(蓝牙耳机的rl是什么意思)

    蓝牙耳机lr什么意思(蓝牙耳机的rl是什么意思)

  • 阿里鱼卡是全国免流吗(阿里鱼卡官网)

    阿里鱼卡是全国免流吗(阿里鱼卡官网)

  • 蓝牙耳机怎么设置弹窗(蓝牙耳机怎么设置自动接听)

    蓝牙耳机怎么设置弹窗(蓝牙耳机怎么设置自动接听)

  • 280元抵减税控设备
  • 稽查局和税务局的关系
  • 流转税解释
  • 利润分配未分配利润和未分配利润的区别
  • 装卸搬运服务属于什么税目
  • 主营业务收入体现在资产负债表哪里
  • 建筑工程怎么确定施工工程进度
  • 员工报销公司是哪个部门
  • 专项拨款形成的固定资产递延收益
  • 增值税没有按时缴纳会影响开票吗
  • 增值税纳税申报表怎么填
  • 营改增后印花税计税依据文件
  • 设计服务发票怎么入账
  • 企业外币交易会计核算方法
  • 三免三减半税收优惠政策文件
  • 销售方开票不填开户行
  • 怎么看是不是专用发票
  • 上报汇总完成,远程清卡清不了
  • win11dns电脑服务器未响应如何处理
  • 苹果7充电设置在哪里
  • win11如何更改开始菜单位置
  • 差旅费津贴可以扣除吗
  • 装电脑系统的方法和步骤
  • cmos是bios参数设置的
  • win7纯净版怎么联网
  • 公司从其他公司买一个项目花了100万
  • 租赁公司经营项目
  • 舍夫沙万的蓝色是什么意思
  • PHP:imagesetbrush()的用法_GD库图像处理函数
  • 土地出资是否涉及企业所得税
  • 固定资产明细账登记
  • 资产变现率减资产负债率
  • cobit框架
  • 我一定要用自己的双手拼出来
  • login user
  • php 性能优化
  • 保险代理人展业成本如何计算
  • 原材料存货跌价准备会计分录
  • 社保断交一个月但是后面正常缴费
  • 什么是进项税转出成本
  • 社保局申报工伤款多久能下
  • python requests检测响应状态码
  • 小规模纳税人不超过30万怎么做账
  • 销项税用转出吗
  • 国外佣金代扣代缴增值税可以抵扣吗
  • 购入钢材
  • 税控盘年费每年都可以抵扣吗
  • 收到国库退款
  • 以前年度损益调整账务处理分录
  • 建筑工程承包合同保证保险中,承保工程所有人
  • 营改增税法
  • 给员工买的手机能抵扣税吗
  • 连锁店会计处理流程
  • 小微企业的认定标准2023最新
  • 在建工程进项税额抵扣规定
  • 累计折旧余额在哪方
  • 新公司要建哪些项目
  • sqlserver2012序列号
  • win7提示oxcooooo98
  • linux中fi
  • win7老是自动开机启动是怎么回事啊
  • win10系统如何禁用触摸板
  • win8尝试修复
  • linux 进入命令
  • manager是啥
  • Win7系统打开IE提示“堆栈满溢”的多种解决方案
  • centos6.9
  • linux block io
  • cocos引擎教程
  • android开发工程师案例教程源码
  • unity集成到app后变大了
  • javascript中math.ceil
  • JavaScript中iframe实现局部刷新的几种方法汇总
  • javascript面向对象精要pdf下载
  • 使用jquery操作dom
  • python的了解
  • 福建省电子税务局官网登录入口
  • 增值税电子普通发票需要盖章吗
  • 个人所得税法实施条例2011
  • 浙江蹦极哪里好玩
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设