笔记整理-SpringBoot中的扩展点

SpringBoot有哪些扩展点

aware 感知类接口

aware系列的扩展接口,允许spring应用感知/获取特定的上下文环境或对象。

bean生命周期控制类接口

bean生命周期类的接口,可以控制spring容器对bean的处理。

app生命周期控制类接口

app生命周期控制类接口,可以控制spring应用启动/销毁时的逻辑

下面详细介绍各种扩展点的使用

aware 感知类接口

ApplicationContextAware

package cn.test.ext.aware;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** ApplicationContextAware* 通过实现该接口,组件可以获取ApplicationContext对象的引用,* 从而访问应用程序上下文中的bean以及其他特定的spring功能*/
@Component
@Slf4j
public class TestAppCtxAware implements ApplicationContextAware {@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {String applicationName = applicationContext.getApplicationName();log.info("context-path:{}",applicationName);String displayName = applicationContext.getDisplayName();log.info("displayName:{}",displayName);String id = applicationContext.getId();log.info("spring-applicationName:{}",id);long startupDate = applicationContext.getStartupDate();log.info("startupDate:{}",startupDate);
//        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
//        log.info("beanDefinitionNames:{}", Arrays.asList(beanDefinitionNames).toString());}
}

BeanFactoryAware

package cn.test.ext.aware;import cn.test.web.TestController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;/*** BeanFactoryAware* 实现该接口,可以使自定义类获取bean工厂对象的引用,* 允许你在运行时从bean工厂中获取其他bean*/
@Slf4j
@Component
public class TestBeanFactoryAware implements BeanFactoryAware {@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {boolean b = beanFactory.containsBean("testController");log.info("spring容器内是否含有 testController这个bean :{}",b);TestController testController =(TestController) beanFactory.getBean("testController");String tgwt43t = testController.t1("tgwt43t");log.info("get bean方式调用 TestController里的t1方法,返回值:{}",tgwt43t);}
}

EnvironmentAware

package cn.test.ext.aware;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** EnvironmentAware* 实现该接口,你的组件可以获取 Environment 环境对象的引用,* 从而可以访问spring应用程序的配置属性和配置文件*/
@Component
@Slf4j
public class TestEnvironmentAware implements EnvironmentAware {@Overridepublic void setEnvironment(Environment environment) {//获取当前默认的profile环境String[] defaultProfiles = environment.getDefaultProfiles();log.info("defaultProfiles:{}",Arrays.asList(defaultProfiles));//获取某个属性配置String property = environment.getProperty("spring.application.name");log.info("property->spring.application.name:{}",property);}
}

MessageSourceAware

package cn.test.ext.aware;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.stereotype.Component;/*** MessageSourceAware* 实现该接口,你的组件可以获取 messageSource 消息源对象的引用,* 从而访问 国际化消息内容*/
@Component
@Slf4j
public class TestMessageSourceAware implements MessageSourceAware {@Overridepublic void setMessageSource(MessageSource messageSource) {
//        messageSource.getMessage()}
}

ResourceLoaderAware

package cn.test.ext.aware;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;import java.util.Properties;/*** ResourceLoaderAware* 实现该接口,你的组件可以获取 ResourceLoader 资源加载器 对象的引用。* 从而可以加载外部资源文件*/
@Slf4j
@Component
public class TestResourceLoaderAware implements ResourceLoaderAware {@SneakyThrows@Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {//ResourceLoader可以加载自定义位置的自定义的properties配置文件//这里测试加载classpath下的test.properties文件Resource resource = resourceLoader.getResource("classpath:test.properties");if (resource.isFile()) {String filename = resource.getFilename();log.info("filename:{}",filename);Properties properties = new Properties();properties.load(resource.getInputStream());properties.list(System.out);String aaa = properties.getProperty("aaa");log.info("aaa-->:{}",aaa);}}
}

ServletContextAware

package cn.test.ext.aware;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;import javax.servlet.ServletContext;/*** ServletContextAware* 实现该接口,你的组件可以获取 ServletContext Servlet上下文对象的引用,* 从而访问与web应用程序相关的功能*/
@Component
@Slf4j
public class TestServletContextAware implements ServletContextAware {@Overridepublic void setServletContext(ServletContext servletContext) {//添加java web 过滤器
//        servletContext.addFilter()//添加java web servlet
//        servletContext.addServlet()//添加java web 监听器
//        servletContext.addListener();}
}

bean生命周期控制类接口

InitializingBean

package cn.test.ext.beanlife;import cn.test.ext.ITestStrategy;
import cn.test.ext.MyStrategyFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;/*** InitializingBean* 实现该接口,你的bean可以在 spring容器初始化当前bean时 执行自定义逻辑** 必须在afterPropertiesSet方法里写你自定义的执行逻辑*/
@Slf4j
@Component
public class TestInitializingBean implements ITestStrategy, InitializingBean {private static String str ;//实现InitializingBean接口,必须重写afterPropertiesSet方法//这样当springboot启动加载TestInitializingBean时,会自动执行里边的afterPropertiesSet方法@Overridepublic void afterPropertiesSet() throws Exception {//本方法里可以做一些初始化的操作,如设置类静态变量值 / 将类注册到策略工厂/ 执行一些其他方法或动作/...//设置类静态变量值str = "qwe123!";//将k1策略 (本类) 注册到 策略工厂里MyStrategyFactory.register("k1",this);log.info("注册了策略:{}到策略工厂里",this);}@Overridepublic void execTestMethod() {log.info("start----执行k1策略...");System.err.println(str);}
}

DisposableBean

package cn.test.ext.beanlife;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;/*** DisposableBean* 实现该接口,你的bean可以在销毁阶段执行自定义逻辑。* 该接口包含一个destory(),你可以在此方法中定义销毁逻辑。*/
@Slf4j
@Component
public class TestDisposableBean implements DisposableBean {@Overridepublic void destroy() throws Exception {log.info("TestDisposableBean 这个bean销毁了...");}
}

BeanPostProcessor

package cn.test.ext.beanlife;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;/*** BeanPostProcessor* 该接口定义了在spring容器实例化bean之后和初始化之前,* 对bean进行自定义处理的方法。* 通过实现该接口,你可以插入自定义逻辑来处理bean*/
@Component
@Slf4j
public  class TestBeanPostProcessor implements BeanPostProcessor {public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals("testController")){log.info("BeanPostProcessor Before 处理到了 beanName:{}",beanName);}return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals("testController")){log.info("BeanPostProcessor After 处理到了 beanName:{}",beanName);}return bean;}
}

BeanFactoryPostProcessor

package cn.test.ext.beanlife;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;/*** BeanFactoryPostProcessor接口* 允许在 所有bean定义加载到容器之后,但在bean实例化之前对他们进行自定义处理。* 通过实现该接口,你可以修改或添加新的bean定义***/
@Component
@Slf4j
public class TestBeanFctoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {log.info("postProcessBeanFactory 触发了....");}
}

BeanDefinitionRegistryPostProcessor

package cn.test.ext.beanlife;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;/*** BeanDefinitionRegistryPostProcessor接口** 这个接口是BeanFactoryPostProcessor接口的扩展,* 允许在bean定义注册过程中对 bean定义进行自定义处理,* 它提供了对bean定义注册表的直接访问,可以添加,修改或删除bean定义*/
@Slf4j
@Component
public class TestBeanDefineRegistPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {log.info("postProcessBeanDefinitionRegistry 触发了...");}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {log.info("postProcessBeanFactory 触发了...");}
}

app生命周期控制类接口

SmartLifecycle

package cn.test.ext.applife;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;/*** SmartLifecycle接口 可以感知springboot应用生命周期变化,是spring的一个扩展点,可以实现随springboot启动和销毁的操作。** 自定义类实现SmartLifecycle接口后,至少要重写3个方法start(),stop(),isRunning() ,其他方法可以按需实现** springboot中的内嵌tomcat启动/关闭,就是利用SmartLifecycle实现的,* 见 org.springframework.boot.web.servlet.context.WebServerStartStopLifecycle*/
@Component
@Slf4j
public class TestSmartLifeCycle implements SmartLifecycle {//模拟一个任务 (实际开发中,可以在这里引入netty,实现netty随springboot启动和销毁)private static boolean xxxStat;/*** bean初始化完毕后,该方法会被执行*/@Overridepublic void start() {xxxStat = true;log.info("启动了 xxxStat ");}/*** 容器关闭后,spring容器发现当前对象实现了SmartLifecycle,* 就调用stop(Runnable),如果只是实现了Lifecycle,就调用stop()*/@Overridepublic void stop() {log.info("stop---容器关闭了");xxxStat = false;}/*** 当前状态* @return*/@Overridepublic boolean isRunning() {log.info("isRunning 获取当前状态:{}",xxxStat);return xxxStat;}/*** start方法被执行前,先看此方法返回值,* 返回false就不执行start方法了* @return*/@Overridepublic boolean isAutoStartup() {log.info("isAutoStartup 是否自启动");return true;}/*** 容器关闭后,spring容器发现当前对象实现了SmartLifecycle,就调用stop(Runnable),* 如果只是实现了Lifecycle,就调用stop()* @param callback*/@Overridepublic void stop(Runnable callback) {//必须调用stop方法 ,确保SmartLifecycle这个bean里的任务停止了this.stop();//必须执行callback.run方法,否则app exit时无法销毁这个SmartLifecyclecallback.run();log.info("stop Runnable---容器关闭了");}/*** 返回值决定* start方法 在众多Lifecycle实现类中的执行顺序(stop也是)* @return*/@Overridepublic int getPhase() {log.info("SmartLifecycle 当前优先级 1");return 1;}
}

CommandLineRunner

CommandLineRunner可以让springboot-jar启动时接收一些jvm参数或自定义cmd参数,然后执行一些操作

package cn.test.ext.applife;import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class TestCmdLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {log.info("CommandLineRunner 执行了...");}
}

ApplicationRunner

ApplicationRunner可以让springboot-jar启动时接收一些应用配置参数如server.port,然后执行一些操作

package cn.test.ext.applife;import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class TestApplictionRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {log.info("ApplicationRunner 执行了...");}
}

ApplicationListener

要通过spring内置的ApplicationListener监听ContextRefreshedEvent
上下文刷新事件,springboot启动时会触发一次,
一般常用来做业务缓存预热,如在springboot启动时把系统字典数据/系统配置项数据加到缓存中,方便后续调用。

package cn.test.ext.applife;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class AppCtxRefreshListener implements ApplicationListener<ContextRefreshedEvent> {/*** 监听到上下文刷新事件时,* 执行相应的操作* @param contextRefreshedEvent 上下文刷新事件*/@Overridepublic void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {log.info("监听到了spring应用 上下文刷新事件...");}
}

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

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

相关文章

【Lua学习笔记】Lua进阶——Table,迭代器

文章目录 官方唯一指定数据结构--tabletable的一万种用法字典和数组 迭代器ipairs()pairs() 回到Table 在【Lua学习笔记】Lua入门中我们讲到了Lua的一些入门知识点&#xff0c;本文将补充Lua的一些进阶知识 官方唯一指定数据结构–table 在上篇文章的最后&#xff0c;我们指出…

第九十四回 如何打造一个网络框架

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了"如何mock数据"相关的内容&#xff0c;本章回中将介绍如 何打造一个网络框架闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 最近在项目中使用dio处理网络相关的内容&#xff0c;有些地方的代…

Mybatis使用collection映射一对多查询分页问题

场景&#xff1a;页面展示列表&#xff0c;需要查询多的字段&#xff0c;和一的字段。并且还要分页。 这时候直接想到的是手写sql。 /*** 标签*/private List<BasicResidentTags> tags;Data TableName("basic_resident_tags") public class BasicResidentTag…

SpringCloud微服务实战——搭建企业级开发框架(五十三):微信小程序授权登录增加多租户可配置界面

GitEgg框架集成weixin-java-miniapp工具包以实现微信小程序相关接口调用功能&#xff0c;weixin-java-miniapp底层支持多租户扩展。每个小程序都有唯一的appid&#xff0c;weixin-java-miniapp的多租户实现并不是以租户标识TenantId来区分的&#xff0c;而是在接口调用时&#…

C#如何使用SQLite数据库?

文章目录 0.引言1.SQLite工具准备2.创建窗体项目并添加SQLite的命名空间3.编写使用SQLite代码4.结果展示 0.引言 SQLite是一个轻量级的嵌入式数据库&#xff0c;它的库文件非常小巧&#xff0c;不需要独立的服务器进程或配置。这使得它非常适合在资源受限的环境中使用&#xff…

【Terraform学习】Terraform-AWS部署快速入门(快速入门)

Terraform-AWS部署快速入门 实验步骤 连接到 Terraform 环境 SSH 连接到Terraform 环境(名为MyEC2Instance的实例) 在 Amazon Web Services &#xff08;AWS&#xff09; 上预置 EC2 实例 用于描述 Terraform 中基础结构的文件集称为 Terraform 配置。您将编写一个配置来定义…

防御第三天

1.总结当堂NAT与双机热备原理&#xff0c;形成思维导图 2.完成课堂NAT与双机热备实验 fw1: <USG6000V1>sy [USG6000V1]int g0/0/0 [USG6000V1-GigabitEthernet0/0/0]ip add 192.168.18.2 24 [USG6000V1-GigabitEthernet0/0/0]service-manage all permit (地址无所谓&…

设计模式适合用于解决特定的软件设计问题呢

当我们在开发软件时&#xff0c;经常会遇到各种各样的问题和挑战&#xff0c;例如如何处理对象之间的关系、如何实现复杂的业务逻辑、如何处理并发访问等。这些问题都是软件设计中经常遇到的问题&#xff0c;而设计模式就是为了解决这些问题而诞生的。 以下是一些常见的软件设…

SpringCloud学习路线(11)——分布式搜索ElasticSeach场景使用

一、DSL查询文档 &#xff08;一&#xff09;DSL查询分类 ES提供了基于JSON的DSL来定义查询。 1、常见查询类型&#xff1a; 查询所有&#xff1a; 查询出所有的数据&#xff0c;例如&#xff0c;match_all全文检索&#xff08;full text&#xff09;查询&#xff1a; 利用…

leetcode 50. Pow(x, n)(x的n次方)

求x的n次方。 思路&#xff1a; 第一个想到的思路是x和它自己乘n次&#xff0c; 但是这样做会面临一些问题&#xff1a; 如果是简单的n很小的情况还好&#xff0c;但是可以看到n的取值横跨整个整数范围&#xff0c; 如果n非常大&#xff0c;一次一次乘x效率低是其一。 一般来…

探索网页原型设计:构建出色的用户体验

在当今数字化时代&#xff0c;用户对网页体验的要求日益提高。在网页设计过程中&#xff0c;扮演着至关重要的角色。通过网页原型设计&#xff0c;产品经理能够更好地展示和传达网页的整体布局、导航结构、元素位置和交互效果&#xff0c;从而使团队成员更清晰地了解设计意图&a…

mapboxGL中楼层与室内地图的结合展示

概述 质量不够&#xff0c;数量来凑&#xff0c;没错&#xff0c;本文就是来凑数的。前面的几篇文章实现了楼栋与楼层单体化的展示、室内地图的展示&#xff0c;本文结合前面的几篇文章&#xff0c;做一个综合的展示效果。 实现效果 实现 1. 数据处理 要实现上图所示的效果…

Excel透视表与python实现

目录 一、Excel透视表 1、源数据 2、数据总分析 3、数据top分析 二、python实现 1、第一张表演示 2、第二张表演示 一、Excel透视表 1、源数据 1&#xff09;四个类目&#xff0c;每类50条数据 2&#xff09;数据内容 2、数据总分析 1&#xff09;选择要分析的字段&…

leetcode做题笔记46

给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 思路一&#xff1a;回溯 void swap(int *nums,int index1,int index2) {int temp nums[index1];nums[index1] nums[index2];nums[index2] temp; }void prem(int* nu…

已经重新安装了MySQL,第一次应该如何登录root用户

如果已经重新安装了MySQL&#xff0c;第一次登录root用户需要按照以下步骤进行&#xff1a; 1. 打开命令行终端或控制台。 2. 通过一下命令启动MySQL服务器&#xff1a; sudo systemctl start mysql3. 登录MySQL服务器&#xff1a; sudo mysql -u root 如果服务器在本地主…

vue项目登录页面实现记住用户名和密码

vue项目登录页面实现记住用户名和密码 记录一下实现的逻辑&#xff0c;应该分两步来理解这个逻辑 首次登录&#xff0c;页面没有用户的登录信息&#xff0c;实现逻辑如下&#xff1a; 用户输入用户名和密码登录&#xff0c;用户信息为名为form的响应式对象&#xff0c;v-model…

Linux Day03

一、基础命令(在Linux Day02基础上补充) 1.10 find find 搜索路径 -name 文件名 按文件名字搜索 find 搜索路径 -cmin -n 搜索过去n分钟内修改的文件 find 搜索路径 -ctime -n搜索过去n分钟内修改的文件 1&#xff09;按文件名字 2&#xff09;按时间 1.11 grep 在文件中过…

linux+Jenkins+飞书机器人发送通知(带签名)

文章目录 如何使用在linux 上安装python 环境发送消息python脚本把脚本上传倒linux上 jenkins 上执行脚本 如何使用 自定义机器人使用指南飞书官网https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot 在linux 上安装python 环境 yum install python3 python…

yolov5检测到的框画到原图上

1.把检测到的框画到原图上 import warnings warnings.filterwarnings(ignore) warnings.simplefilter(ignore) import torch import cv2 import numpy as np import requests import torchvision.transforms as transformsfrom models.common

“深入解析Spring Boot:从入门到进阶“

标题&#xff1a;深入解析Spring Boot&#xff1a;从入门到进阶 摘要&#xff1a;本文将深入解析Spring Boot框架&#xff0c;从入门到进阶&#xff0c;帮助开发者更好地理解和应用Spring Boot。内容包括Spring Boot的基本概念、核心特性、常用组件和高级用法&#xff0c;并提…