Spring中有哪些扩展点

介绍

什么是spring扩展点

Spring 框架中的扩展点是指一组接口或机制,允许开发者在不修改核心框架源代码的情况下,定制和扩展 Spring 框架的功能、行为或配置。这些扩展点提供了一种方式,使开发者可以通过实现特定的接口、编写特定类型的类或配置特定的元数据,来影响和增强 Spring 框架的行为。

常用的扩展点有哪些

Spring 框架提供了多种可扩展的点,其中一些主要的扩展点包括但不限于:

  • BeanPostProcessor 和 BeanFactoryPostProcessor:允许开发者在 Bean 实例化前后或 BeanFactory 加载 Bean 定义后进行处理,例如定制化 Bean 实例化过程、修改 Bean 定义等。
  • ApplicationContextInitializer:在 Spring 应用上下文初始化时执行特定逻辑,允许对应用程序上下文进行定制。
  • ApplicationListener:允许监听并处理 Spring 应用程序中发布的事件,例如上下文启动、Bean 初始化完成等。
  • HandlerInterceptor:用于拦截 Spring MVC 请求处理过程中的请求和响应,执行特定逻辑,例如请求前的处理、请求后的处理等。
  • InitializingBean 和 DisposableBean:允许在 Bean 初始化和销毁时执行特定的操作。
  • 自定义注解和注解处理器:通过自定义注解和注解处理器,扩展 Spring 框架的功能,例如定制化 Bean 的装配方式、实现特定逻辑等。

使用场景示例

场景一:使用BeanPostProcessor对Bean进行日志记录

有时候,你可能希望在每次 Bean 初始化时记录日志。通过实现 BeanPostProcessor 接口,你可以在 Bean 初始化前后执行自定义的逻辑。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class LoggingBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("Initializing bean: " + beanName);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// 可以在此处进行其他的操作,比如打印日志或执行其他逻辑return bean;}
}

在这个例子中,LoggingBeanPostProcessor 实现了 BeanPostProcessor 接口,并在每个 Bean 初始化前后输出日志信息。 

场景二:使用自定义注解处理器实现权限校验

假设你需要实现一个权限校验的功能,可以通过自定义注解和注解处理器来完成。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiresPermission {String value(); // 定义权限名称
}// 自定义注解处理器
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Method;@Component
public class PermissionCheckProcessor {public void checkPermission(Object target) {Method[] methods = target.getClass().getMethods();for (Method method : methods) {if (method.isAnnotationPresent(RequiresPermission.class)) {RequiresPermission annotation = method.getAnnotation(RequiresPermission.class);String permission = annotation.value();if (StringUtils.hasText(permission)) {// 执行权限检查逻辑,根据需求进行权限验证System.out.println("Checking permission for method: " + method.getName());}}}}
}

在这个场景中,自定义注解 RequiresPermission 定义了权限名称,PermissionCheckProcessor 类则扫描被该注解标记的方法,并执行相应的权限检查逻辑。

场景三:使用ApplicationListener监听应用程序事件

假设你需要在某个特定事件发生时触发某些操作,可以通过实现 ApplicationListener 接口监听相应的事件。

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class CustomEventListener implements ApplicationListener<ApplicationEvent> {@Overridepublic void onApplicationEvent(ApplicationEvent event) {// 这里可以根据不同的事件类型执行相应的操作if (event instanceof CustomEvent) {System.out.println("Custom event occurred: " + event.toString());}}
}

 在这个例子中,CustomEventListener 监听所有的应用程序事件,并在自定义事件 CustomEvent 发生时执行相应的操作。

场景四:使用 InitializingBean 和 DisposableBean 完成资源的初始化和销毁

假设你有一个需要在初始化和销毁时释放资源的类,你可以使用 InitializingBeanDisposableBean 接口完成这些操作。

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;public class ResourceHandler implements InitializingBean, DisposableBean {private String resource;public void setResource(String resource) {this.resource = resource;}@Overridepublic void afterPropertiesSet() throws Exception {// 在初始化时执行的逻辑,比如资源的加载System.out.println("Initializing ResourceHandler with resource: " + resource);}@Overridepublic void destroy() throws Exception {// 在销毁时执行的逻辑,比如资源的释放System.out.println("Destroying ResourceHandler");// 这里进行资源的释放操作,比如关闭连接、释放文件资源等}
}

在这个场景中,ResourceHandler 类实现了 InitializingBeanDisposableBean 接口。afterPropertiesSet 方法用于在 Bean 初始化后执行逻辑,destroy 方法用于在 Bean 销毁前执行逻辑。

场景五:使用自定义的HandlerInterceptor实现请求拦截

如果你想要在请求到达处理程序之前或之后执行某些逻辑,可以使用 HandlerInterceptor 接口来实现拦截器。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class CustomHandlerInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在处理程序之前执行逻辑,返回true则继续执行,返回false则中断请求System.out.println("Before handling the request");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在处理程序执行后、视图渲染前执行逻辑System.out.println("After handling the request, before rendering the view");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在视图渲染后执行逻辑System.out.println("After rendering the view");}
}

在这个示例中,CustomHandlerInterceptor 实现了 HandlerInterceptor 接口,用于在请求处理前后执行自定义的逻辑,比如日志记录、权限校验等。

结语

通过 InitializingBean DisposableBean 接口,可以在 Spring 容器管理的 Bean 的初始化和销毁阶段执行特定的逻辑,这对于资源的初始化和释放是非常有用的。然而,考虑到 Spring 的灵活性,通常推荐使用 @PostConstruct @PreDestroy 注解或者自定义的销毁方法和初始化方法,以提高代码的可读性和易维护性。

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

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

相关文章

使用 sourcetree 的《遴选》功能

假设你有一个分支&#xff0c;有两个提交 A&#xff0c;和B&#xff0c;你现在想在A提交的基础上把 B提交的功能做修改&#xff0c;你可以使用 遴选功能。 在A 提交的基础上新建一个分支&#xff0c;然后在B提交上面&#xff0c;右键&#xff0c;选择 遴选&#xff0c;那么B修改…

【开题报告】基于SSM的仓库管理系统设计与实现

1.引言 随着物流行业的蓬勃发展&#xff0c;仓库管理成为了企业物流运作中的关键环节。为了提高仓库管理的效率和准确性&#xff0c;开发一个基于SSM框架的仓库管理系统是非常必要和有意义的。 传统的仓库管理方式往往依赖于手工操作和纸质记录&#xff0c;这种方式存在着许多…

业务中台-研发

在业务中台研发阶段&#xff0c;我们主要聚焦于研发工作。首先&#xff0c;让我们了解一下我们的研发团队构成&#xff1a;UI设计师、开发工程师、测试工程师和前端工程师。 在业务中台项目中&#xff0c;我们采取了领域划分的策略&#xff0c;成立了商品、订单、库存、客户和…

软件行业也来一场“仅退款”,可行否?

“仅退款”战役&#xff0c;算是全面打响了&#xff01;某夕夕&#xff0c;用超级流量倒逼供应商提升产品品质&#xff08;这里先不能用质量一词&#xff09;&#xff0c;确实产生了奇效&#xff0c;完成了逆袭&#xff0c;现在逼得阿猫和阿狗不得不加入。但我个人认为&#xf…

工厂传送带应用西门子Profinet连接EtheCAT伺服驱动器

在工业现场&#xff0c;我们采用了1500系列的PLC&#xff0c;以及带有EtherCAT通讯协议的伺服驱动器。由于1500系列的PLC采用的是PROFINET实时以太网通讯协议&#xff0c;为了实现与EtherCAT设备的连接&#xff0c;我们必须进行通讯协议的转换。为此&#xff0c;开疆智能Profin…

计网_05IP地址

一、IP地址  &#xff11;、IP地址基本概念 用于标识网络中的某一台主机或某一个网络接口&#xff0c;主机的唯一标识&#xff0c;保证主机间的正常通信&#xff08;主机之间要想通信就必须配置相应的IP地址&#xff09; 一种网络编码&#xff0c;用来确定网络中的一个节点…

汽车发动机缸体缸盖自动化光学测量系统尺寸测量偏差检测-CASAIM品质检测自动化设备

汽车行驶在不同的环境中&#xff0c;汽车的安全性是必须考虑的&#xff0c;汽车发动机盖体缸盖的加工质量问题是汽车安全可靠性的一个关注点。目前客户检测方案是通过三坐标检测工件进行检测&#xff0c;只能对于位置点进行相关测量&#xff0c;需要规划测量路径&#xff0c;费…

Android Studio修改创建新布局时默认根布局

将Android Studio默认布局ConstraintLayout切换成LinearLayout 打开设置&#xff0c; Editor> File and Code Templates > Other > layoutResourceFile.xml 备注&#xff1a;创建时提示根布局仍然为ConstraintLayout&#xff0c;不用管这个&#xff0c;实际创建的…

炎症状态重塑了急性髓系白血病的免疫微环境并改善了风险分层

今天给同学们分享一篇实验文章“An inflammatory state remodels the immune microenvironment and improves risk stratification in acute myeloid leukemia”&#xff0c;这篇文章发表在Nat Cancer期刊上&#xff0c;影响因子为22.7。 结果解读&#xff1a; 成人和儿童AML的…

HDMI2.1输入转4Port MIPI/LVDS输出,嵌入式SPI闪存固件存储,VR和AR应用首选国产芯片方案-LT6911GXC

描述 LT6911GXC是一款高性能的HDMI2.1到MIPI或LVDS芯片&#xff0c;用于VR/显示应用。 HDCP RX作为HDCP中继器的上游&#xff0c;可配合其他芯片的HDCPTX实现中继器功能。 对于HDMI2.1输入&#xff0c;LT6911GXC可以配置为3/4通道。自适应均衡使其适合于长电缆应用&#xff0c;…

如何做好机电设备全生命周期管理?

机电设备是现代工业运作中不可或缺的重要资产&#xff0c;对生产运营具有关键影响。为了确保机电设备的长期运行和高效性能&#xff0c;机电设备全生命周期管理是必不可少的。下面将介绍一些关键步骤和策略&#xff0c;帮助企业效地进行机电设备全生命周期管理。 1. 选型和规划…

NXP实战笔记(一):基于RTD-SDK新建一个S32DS工程

目录 1、概述 2、操作步骤 2.1、新建Application工程 2.2、命名工程、选择芯片型号、选择编译器GCC版本 2.3、配置基本参数 3、文件描述 3.1、文件结构描述 3.2、编译之后 4、下载调试 1、概述 安装了S32DS之后&#xff0c;导入SDK插件&#xff0c;这个步骤不赘述&…

【AI】图像识别和无人零售

目录 一、引言 二、AI商品识别的定义 三、所用技术 四、解决方案的种类 五、发展历程 六、瓶颈 七、未来趋势 一、引言 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;AI商品识别已经成为无人零售领域的一项关键技术。特别是在智能无人售货柜等场景…

Qt篇——QwtPainter::drawPie绘制扇形

QwtPainter::drawPie(QPainter *painter, const QRectF &rect, int startAngle, int angle); 一、参数含义&#xff1a; painter&#xff1a; 重绘函数中的painter对象 rect&#xff1a; 要绘制扇形的圆的外切矩形。 startAngle: 要绘制的扇形的起始角 …

du和df

du 和df 不一致的问题&#xff1a; 情况如下&#xff1a; innode 没有满 同事求助&#xff0c; 他在删掉一个很大的文件后&#xff0c; 磁盘空间依旧没释放。上去一看&#xff0c; 果然 df 看到磁盘空间占用依旧是100%&#xff0c;等等 du 看了一把&#xff0c;磁盘空间剩余很…

【软件测试】为bug而生

为什么定位问题如此重要&#xff1f; 可以明确一个问题是不是真的“bug” 很多时候&#xff0c;我们找到了问题的原因&#xff0c;结果发现这根本不是bug。原因明确&#xff0c;误报就会降低多个系统交互&#xff0c;可以明确指出是哪个系统的缺陷&#xff0c;防止“踢皮球”&…

使用海外proxy進行網頁抓取採集指南

作為從互聯網提取大量數據的強大工具&#xff0c;網路抓取徹底改變了企業收集和分析數據的方式&#xff0c;為他們提供了推動決策過程的寶貴見解。然而&#xff0c;有效的網路抓取通常需要使用特定的工具&#xff1a;海外proxy抓取代理。 在本文中&#xff0c;我們將瞭解什麼是…

Windows定时重启Tomcat

项目场景&#xff1a; 系统&#xff1a;Windows 7 Tomcat&#xff1a;apache-tomcat-8.0.5 JDK&#xff1a;1.8 问题描述 最近项目的Tomcat隔一段时间就假死&#xff0c;最后想到的解决方式就是&#xff1a;每天凌晨1点重启tomact。 解决方案&#xff1a; 使用Windows系统…

南大通用数据库 GBase 8a 性能调优方法--压缩策略选择

大部分应用中性能的瓶颈是磁盘IO&#xff0c;所以新型数据库的设计都已降低磁盘IO为主要设计目标&#xff0c;压缩可减少I/O的时间&#xff0c;提升性能&#xff0c;南大通用数据库的 GBase 8a也不例外&#xff0c;压缩也是提高性能的主要技术之一&#xff0c;GBase 8a并行执行…

c 语言, 随机数,一个不像随机数的随机数

c 语言&#xff0c; 随机数&#xff0c;一个不像随机数的随机数 使用两种方式获取随机数&#xff0c;总感觉使用比例的那个不太像随机数。 方法一&#xff1a; rand() 获取一个随机数&#xff0c;计算这个随机数跟最大可能值 RAND_MAX&#xff08;定义在 stdlib.h 中&#xf…