手撕spring框架(3)

news2024/10/6 22:23:58

手撕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.coloradmin.cn/o/1637941.html

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

相关文章

Vue3管理系统-路由设置+表单校验

一、配置路由规则 1.在views 下创建文件夹分类,搭好架子 2.配置路由规则 在router下Index.js import { createRouter, createWebHistory } from vue-routerconst router createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [//一级路由//这里可以…

GitLab服务器的搭建

GitLab服务器的搭建 为公司搭建一台代码托管服务器 服务器规格&#xff1a;2vCPUs4GiB20G 操作系统&#xff1a;RockyLinux8.8 下载软件 gitlab官网&#xff1a;http://about.gitlab.com 在官网下载比较麻烦&#xff0c;推荐从《清华大学开源软件镜像站》下载 清华大学开…

java线上问题排查之CPU使用率过高(一)【保姆级教程】

线上故障排查&#xff0c;主要包括CPU&#xff0c;磁盘&#xff0c;内存以及网络。基本上出问题就是 df、free、top 三连&#xff0c;然后依次 jstack、jmap df&#xff1a;用于显示文件系统的磁盘空间使用情况。 df -h&#xff1a;以人类可读的方式显示磁盘空间使用情况。 d…

微软如何打造数字零售力航母系列科普06 - 如何使用微软的Copilot人工智能

如何使用微软的Copilot人工智能&#xff1f; Copilot和ChatGPT有很多相似之处&#xff0c;但微软的聊天机器人本身就有一定的优势。以下是如何对其进行旋转&#xff0c;并查看其最引人注目的功能。 ​​​​​​​ &#xff08;资料来源&#xff1a;Lance Whitney/微软&…

前端素材库

大家好我是苏麟 , 今天推荐一个前端素材库 . 官网 : iconfont-阿里巴巴矢量图标库 这期就到这里 , 下期见!

WSL2-Ubuntu使用Conda配置百度飞浆paddlepaddle虚拟环境

0x00 缘起 本文将介绍在WSL2-Ubuntu系统中,使用Conda配置百度飞浆paddlepaddle虚拟环境中所出现的各种问题以及解决方法,最终运行"run_check()"通过测试。 在WSL2中配置paddlepaddle不像配置Pytorch那样顺滑,会出现各种问题(如:库的文件缺失、不知道如何匹配C…

Ps 滤镜:锐化

Ps菜单&#xff1a;滤镜/锐化 Filter/Sharpen “锐化”类滤镜一般都是通过增加相邻像素的对比度来达到锐化的目的。 请参阅&#xff1a; 《Ps&#xff1a;更好地进行锐化的建议》 较小范围的局部锐化&#xff0c;可尝试 Photoshop 工具箱里的“锐化工具”。 Photoshop 锐化类的…

ES与关系数据库的同步练习(hotel_admin)

目录 1 es与数据库同步的方法2 实践2.1 任务介绍2.2 MQ方面操作2.2.1 声明交换机队列并且绑定2.2.2 hotel_admin端web层设置mq发送消息2.3 hotel_demo端监听接受消息并执行es操作 1 es与数据库同步的方法 方式一&#xff1a;同步调用 优点&#xff1a;实现简单&#xff0c;粗…

【C++】学习笔记——string_4

文章目录 六、string类7. string类的模拟实现 未完待续 六、string类 7. string类的模拟实现 我们在上文简单实现了string类的构造函数。不知道大家有没有发现一个问题&#xff0c;我们在进行实现无参的构造函数时&#xff0c;初始化列表将 _str 初始化为 nullptr 了&#xf…

GAI工具哪家强?(ChatGPT 4 vs 文心一言)

开始之前&#xff0c; 先来看看 GAI和AI的区别和关系。 AI 和GAI AI 和GAI的概念 AI&#xff08;Artificial Intelligence&#xff09;是人工智能的缩写&#xff0c;是计算机科学的一个分支&#xff0c;旨在使机器像人类一样进行学习和思考。AI技术的研究领域包括机器人、语…

【Mac】Axure RP 9(交互原型设计软件)安装教程

软件介绍 Axure RP 9是一款强大的原型设计工具&#xff0c;广泛用于用户界面和交互设计。它提供了丰富的功能和工具&#xff0c;能够帮助设计师创建高保真的交互原型&#xff0c;用于展示和测试软件应用或网站的功能和流程。以下是Axure RP 9的主要特点和功能&#xff1a; 交…

基于t972 Android9 AP6256,如何在设置中添加5G热点选项,并使其正常打开

通过设置的的WiFi热点选项可以知道关键词“2.4GHz”&#xff0c;因此可以其全局搜索&#xff0c;在packages\apps\Settings\res\values\strings.xml文件下找到如下图所示&#xff0c; 从上面注释可以知道&#xff0c;选项按键选择2.4GHz触发的按键关键词是“wifi_ap_choose_2G…

9U_VPX信号处理机,传感器大数据异构计算平台

9U_VPX信号处理机 1 介绍 1.1 产品概述 9U_VPX信号处理机是一款面向前端射频系统的高速记录、存储和处理系统。信号处理机为应对军用电子信息系统面临的目标种类多样化、战场环境复杂化、执行任务多元化等多重难题&#xff0c;而研发出来的***数据记录存储系统。信号处理机担…

基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 遗传算法&#xff08;GA&#xff09;原理 4.2 BP神经网络原理 4.3 遗传优化BP神经网络结合应用 4.4 遗传算法简要改进 5.完整程序 1.程序功能描述 基于改进遗传优化的BP神经网络金融…

【计算机网络】FTP站点配置搭建教程以及相关问题解决方案(超详细)

文章目录 1、安装Window Server 20082、搭建FTP环境&#xff08;1&#xff09;安装FTP服务器&#xff08;2&#xff09;配置FTP服务器&#xff08;3&#xff09;测试FTP连接 3、遇到的问题以及解决方案&#xff08;1&#xff09;Windows无法访问此文件夹&#xff08;2&#xff…

Github 2024-05-01 开源项目月报Top20

根据Github Trendings的统计,本月(2024-05-01统计)共有20个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目13TypeScript项目5C项目2非开发语言项目1C++项目1JavaScript项目1Rust项目1Go项目1Shell项目1Svelte项目1编程面试大学:成为软件工程…

UDP/TCP

udp/tcp特征 udp&#xff1a; 无连接不可靠传输面向数据包全双工 tcp&#xff1a; 有连接可靠传输面向字节流全双工 解释&#xff1a; 有连接/无连接&#xff1a;发送消息时&#xff0c;对方是否必须要在线 比如我们聊天程序&#xff0c;我们给对方发送消息&#xff0c;是不管现…

HTML5实用大全(Part.1)

引言&#xff1a; 哈喽&#xff0c;各位小伙伴们&#xff0c;在本篇博客我将带领大家走进前端中的HTML5,利用HTML我们将可以在网页上自我创作内容&#xff0c;现在学起来&#xff0c;不久后自己也能制作一个花哨的项目了呢&#xff0c;那么&#xff0c;我们开始吧&#xff01; …

使用c++类模板和迭代器进行List模拟实现

List 一、创建节点结构二、创建迭代器类1、类的结构2、一系列的运算符重载 三、创建list1、细节把握2、迭代器函数3、构造函数和析构函数4、增删查改的成员函数 一、创建节点结构 template <class T>//节点结构 struct ListNode {ListNode<T>* _next;ListNode<…

交通 | 电动汽车车辆路径问题及FRVCP包的调用以及代码案例

编者按&#xff1a; 电动汽车的应用给车辆路线问题带来了更多的挑战&#xff0c;如何为给定路线行驶的电动汽车设计充电决策是一个需要解决的难题&#xff0c;本文介绍了开源python包frvcpy使用精确式算法对该问题求解。 文献解读&#xff1a;Aurelien Froger, Jorge E Mendo…