手撕spring框架(3)

手撕spring框架(3)

相关系列
手撕spring框架(1)
手撕spring框架(2)

InitializingBean 接口详解

什么是 InitializingBean 接口?

InitializingBean 接口是 Spring 框架中的一个接口,用于在 Bean 初始化完成后执行特定的操作。当一个 Bean 实现了 InitializingBean 接口,Spring 容器在实例化 Bean 后会调用其 afterPropertiesSet() 方法,从而实现在 Bean 初始化阶段执行一些定制化的逻辑。

InitializingBean 接口的作用

InitializingBean 接口的主要作用是在 Bean 初始化完成后执行一些必要的操作,例如初始化一些资源、建立一些连接等。通过实现 InitializingBean 接口,开发人员可以在 Bean 初始化阶段 进行一些自定义的操作,从而更好地控制 Bean 的生命周期。

InitializingBean 接口的使用方法

要实现 InitializingBean 接口,只需要在 Bean 类中实现 afterPropertiesSet() 方法即可。在 afterPropertiesSet() 方法中编写需要在 Bean 初始化阶段执行的逻辑代码。下面是一个简单的示例:

package com.spring;public interface InitializingBean {void afterPropertiesSet();
}

调整DzendApplicationContext中的createBean方法

具体看最后文件

BeanPostProcessor类详解

什么是BeanPostProcessor?

在Spring框架中,BeanPostProcessor是一个接口,它允许在Spring容器实例化bean之后和调用bean的初始化方法之前对bean进行自定义处理。BeanPostProcessor接口定义了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization。通过实现这两个方法,我们可以在bean初始化前后做一些额外的操作,比如修改bean的属性值、添加额外的逻辑等。

BeanPostProcessor的使用场景

BeanPostProcessor可以用于很多场景,比如:

  1. AOP(面向切面编程):通过BeanPostProcessor可以在bean初始化前后动态代理bean,实现AOP功能。
  2. 属性注入:可以在bean初始化前后修改bean的属性值,实现自定义的属性注入逻辑。
  3. Bean初始化:可以在bean初始化前后执行一些额外的逻辑,比如打印日志、记录性能指标等。

BeanPostProcessor的实现方式

要实现一个BeanPostProcessor,我们需要创建一个实现了BeanPostProcessor接口的类,并实现postProcessBeforeInitialization和postProcessAfterInitialization方法。下面是一个简单的示 例:

package com.spring;public interface BeanPostProcessor {default Object postProcessBeforeInitialization(Object bean, String beanName) {// 在bean初始化前执行的逻辑return bean;}default Object postProcessAfterInitialization(Object bean, String beanName) {// 在bean初始化后执行的逻辑return bean;}
}

调整DzendApplicationContext的代码

主要流程是添加一个BeanPostProcessorList,在扫描路径的时候,把符合条件的类添加到beanPostProcessorList队列中

添加一个beanPostProcessorList列表

private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

scan方法中加入

if (clazz.isAnnotationPresent(Component.class)) {

代码下添加以下代码

if (BeanPostProcessor.class.isAssignableFrom(clazz)) {BeanPostProcessor instance = (BeanPostProcessor) clazz.getConstructor().newInstance();beanPostProcessorList.add(instance);}

在createBean方法中调整代码

for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {instance = beanPostProcessor.postProcessBeforeInitialization(instance,beanName);}
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {instance = beanPostProcessor.postProcessAfterInitialization(instance,beanName);}

最后附修改后的代码

DzendApplicationContext.java

package com.spring;import java.beans.Introspector;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class DzendApplicationContext {private Class<?> configClass;private Map<String,BeanDefinition> beanDefinitionMap= new HashMap<>();private Map<String, Object> singletonObjects=new HashMap<>();private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();public DzendApplicationContext(Class configClass)   {this.configClass=configClass;scan(configClass);}private void scan(Class configClass) {if(configClass.isAnnotationPresent(ComponentScan.class)){ComponentScan componentScan = (ComponentScan) configClass.getAnnotation(ComponentScan.class);String path = componentScan.value();path = path.replace(".","/");ClassLoader classLoader = DzendApplicationContext.class.getClassLoader();URL resource = classLoader.getResource(path);try {path = URLDecoder.decode(path, "UTF-8");} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}File file = null;try {file = new File(  URLDecoder.decode(resource.getFile(), "UTF-8"));} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}if(file.isDirectory()){for (File f : file.listFiles()) {String absolutePath = f.getAbsolutePath();absolutePath = absolutePath.substring(absolutePath.indexOf("com"),absolutePath.indexOf(".class"));absolutePath=absolutePath.replace("\\",".");try {Class<?>  clazz = classLoader.loadClass(absolutePath);if (clazz.isAnnotationPresent(Component.class)) {if (BeanPostProcessor.class.isAssignableFrom(clazz)) {BeanPostProcessor instance = (BeanPostProcessor) clazz.getConstructor().newInstance();beanPostProcessorList.add(instance);}Component componentAnnotaion = clazz.getAnnotation(Component.class);String beanName= componentAnnotaion.value();if("".equals(beanName)){beanName = Introspector.decapitalize(clazz.getSimpleName());}BeanDefinition beanDefinition = new BeanDefinition();beanDefinition.setType(clazz);if (clazz.isAnnotationPresent(Scope.class)) {Scope scopeAnnotation = clazz.getAnnotation(Scope.class);String value = scopeAnnotation.value();beanDefinition.setScope(value);}else{beanDefinition.setScope("singleton");}beanDefinitionMap.put(beanName,beanDefinition);}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (NoSuchMethodException e) {throw new RuntimeException(e);}}}}}public Object getBean(String beanName){if(!beanDefinitionMap.containsKey(beanName)){throw new NullPointerException();}BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if(beanDefinition.getScope().equals("singleton")){Object singletonObject = singletonObjects.get(beanName);if(singletonObject == null){singletonObject = createBean(beanName,beanDefinition);singletonObjects.put(beanName,singletonObject);}return singletonObject;}else{//原型Object prototypeBean = createBean(beanName, beanDefinition);return prototypeBean;}}private Object createBean(String beanName, BeanDefinition beanDefinition) {Class clazz = beanDefinition.getType();Object instance = null;try {instance = clazz.getConstructor().newInstance();for (Field field : clazz.getDeclaredFields()) {if(field.isAnnotationPresent(Autowired.class)){field.setAccessible(true);field.set(instance,getBean(field.getName()));}}for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {instance = beanPostProcessor.postProcessBeforeInitialization(instance,beanName);}if(instance instanceof BeanNameAware){((BeanNameAware) instance).setBeanName(beanName);}if(instance instanceof InitializingBean){((InitializingBean) instance).afterPropertiesSet();}for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {instance = beanPostProcessor.postProcessAfterInitialization(instance,beanName);}} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (NoSuchMethodException e) {throw new RuntimeException(e);}return instance;}
}

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

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

相关文章

Pandas入门篇(三)-------数据可视化篇3(seaborn篇)(pandas完结撒花!!!)

目录 概述一、语法二、常用单变量绘图1. 直方图&#xff08;histplot&#xff09;2. 核密度预估图&#xff08;kdeplot&#xff09;3. 计数柱状图&#xff08;countplot&#xff09; 三、常用多变量绘图1.散点图(1) scatterplot(2)regplot 散点图拟合回归线(3)jointplot 散点图…

【Flask开发实战】通过python将csv数据导入mysql数据库

一、前言 在前面章节介绍过&#xff0c;我们处理的防火墙规则数据&#xff0c;数据清洗处理后&#xff0c;会产生几类表&#xff0c;以csv形式保存。在接下来的开发测试中&#xff0c;前台页面开始需要用到一些数据&#xff0c;此时我们就需要将csv中数据添加到mysql数据库中。…

fdfs安装启动及性能优化

fsatDFS安装 1、使用 wget 命令下载压缩包&#xff0c;如果没有 wget 命令使用 yum 命令安装 yum install wget 2、下载 fastdfs wget -c “https://github.com/happyfish100/fastdfs/archive/V6.06.tar.gz” 3、下载 libfastcommon wget -c “https://github.com/happyfish10…

ELK Stack 8 接入ElasticFlow

介绍 Netflow v5 / v9 / v10&#xff08;IPFIX&#xff09;&#xff0c;支持大部分网络厂商及VMware的分布式交换机。 NetFlow是一种数据交换方式。Netflow提供网络流量的会话级视图&#xff0c;记录下每个TCP/IP事务的信息。当汇集起来时&#xff0c;它更加易于管理和易读。…

什么是红队?

美国国家安全数据遭到攻击数据泄露数据检测和响应&#xff1a;增强威胁情报和事件响应美国国际开发署进行的全球互联网审查人工智能战争的杀戮问题 微信搜索关注公众号&#xff1a;网络研究观&#xff0c;了解获取更多信息。 红队由安全专业人员组成&#xff0c;他们充当克服网…

Linux procinfo命令教程:如何查看和理解系统信息(附案例详解和注意事项)

Linux procinfo命令介绍 procinfo&#xff08;process information&#xff09;是一个简单的命令行工具&#xff0c;用于查看从/proc目录收集的系统信息&#xff0c;并将其美观地格式化输出到标准输出设备。 Linux procinfo命令适用的Linux版本 procinfo命令在大多数Linux发…

Linux 第十八章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

React 之 Suspense

Suspense Suspense 组件我们并不陌生&#xff0c;中文名可以理解为暂停or悬停 , 在 React16 中我们通常在路由懒加载中配合 Lazy 组件一起使用 &#xff0c;当然这也是官方早起版本推荐的唯一用法。 那它暂停了什么&#xff1f; 进行异步网络请求&#xff0c;然后再拿到请求…

2024-05-02 问AI: 介绍一下IMDB数据集

文心一言 IMDB数据集是一个在自然语言处理&#xff08;NLP&#xff09;和机器学习领域广泛使用的数据集&#xff0c;主要用于文本情感分析任务。以下是对IMDB数据集的详细介绍&#xff1a; 数据来源&#xff1a;IMDB数据集来源于全球最大的电影资料库和评分网站——Internet …

CentOS 7 SSH 升级修复漏洞操作文档

CentOS 7 最新版&#xff08;CentOS 7.9 2009&#xff09; 默认 OpenSSH 版本为 7.4p1&#xff0c;OpenSSH 9.3p2 之前版本存在安全漏洞&#xff0c;需升级 OpenSSH 到安全版本避免漏洞。 本文将介绍 OpenSSH 升级到 9.7p1 版本&#xff0c;依赖的 OpenSSL 版本升级到 1.1.1 版…

基于EBAZ4205矿板的图像处理:01简介

基于EBAZ4205矿板的图像处理&#xff1a;01简介 flag 最近入手了性价比超强的ebaz矿板&#xff0c;决定把之前掌握的知识融汇贯通&#xff0c;将各种图像处理算法部署其中&#xff0c;专门写这个帖子&#xff0c;也是想激励自己&#xff0c;所以&#xff0c;在此立贴为证&…

瑞_23种设计模式_解释器模式

文章目录 1 解释器模式&#xff08;Interpreter Pattern&#xff09;1.1 介绍1.2 概述1.2.1 文法&#xff08;语法&#xff09;规则1.2.2 抽象语法树 1.3 解释器模式的结构1.4 解释器模式的优缺点1.5 解释器模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代…

STM32 DMA直接存储器存取

单片机学习&#xff01; 目录 文章目录 前言 一、DMA简介 1.1 DMA是什么 1.2 DMA作用 1.3 DMA通道 1.4 软硬件触发 1.5 芯片资源 二、存储器映像 2.1 存储器 2.2 STM32存储器 三、DMA框图 3.1 内核与存储器 3.2 寄存器 3.3 DMA数据转运 3.4 DMA总线作用 3.5 DMA请求 3.6 DMA结构…

上位机图像处理和嵌入式模块部署(树莓派4b读写json数据)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;ini文件是用来进行配置的&#xff0c;数据库是用来进行数据存储的。那json是用来做什么的呢&#xff0c;json一般是用来做…

【JavaEE】线程的概念

文章目录 1、什么是线程2、进程和线程的区别3、多线程的概述4、在Java中实现多线程的方法1.继承Thread类2.实现Runnable接口3.使用匿名内部类来继承Thread类&#xff0c;实现run方法4.使用匿名内部类来实现Runnable接口&#xff0c;实现run方法5.使用 lambda表达式 1、什么是线…

【R语言数据分析】数据类型与数据结构

目录 对数据框的基本操作 创建矩阵 列表 字符串 日期变量与时间变量 缺失值NA 缺失值NA的处理 重新编码 R的数据类型有数值型num&#xff0c;字符型chr&#xff0c;逻辑型logi等等。 R最常处理的数据结构是&#xff1a;向量&#xff0c;数据框&#xff0c;矩阵&#x…

MySQL如何设计库表结构

一、引言 在设计数据库时&#xff0c;表结构的设计是至关重要的。合理的表结构设计不仅可以提高数据库的性能&#xff0c;还可以使数据更加清晰、易于维护。MySQL作为一种流行的关系型数据库管理系统&#xff0c;其表结构设计也遵循一定的原则和最佳实践。本文将介绍MySQL表结…

JAVA第二周学习笔记

文章目录 JAVA第二周学习笔记IDEA方法格式带参数及返回值的方法方法的重载方法的内存 二维数组静态初始化动态初始化 面向对象类和对象如何定义类如何得到对象注意 封装封装的优点private关键字成员变量和局部变量 this关键字构造方法作用类型特点执行时机定义重载 标准javabea…

docker-compose 网络

自定义网络 - HOST 与宿主机共享网络 version: "3" services:web:image: nginx:1.21.6restart: alwaysports:- 80:80network_mode: host自定义网络 - 固定ip version: "3" services:web:image: nginx:1.21.6restart: alwaysports:- 80:80networks:app&am…

目标检测YOLO实战应用案例100讲-基于FPGA的目标检测硬件加速技术及其应用研究(下)

目录 基于异构FPGA的硬件加速器设计及优化 3.1 硬件平台 3.2 系统架构设计