Spring_让Spring 依赖注入彻底废掉

news2024/11/25 10:05:45

在Spring之基于注解方式实例化BeanDefinition(1)_chen_yao_kerr的博客-CSDN博客中,我们在末尾处分享了一个甜点,就是关于实现了BeanDefinitionRegistryPostProcessor也可以实例化bean的操作,首先需要去了解一下那篇博客的甜点案例,直接搜索“BeanDefinitionRegistryPostProcessor”就能找到,接下来解释才会听的懂。

在我们Spring实例化BeanDefinition以后,并且在Spring实例化Bean之前,我们中间还有很多的功能性方法,这些方法中有一个名字叫 invokeBeanFactoryPostProcessors的方法,它就是提前预处理一些PostProcessor以及实现或继承了这些PostProcessor的类。

debug进去以后:

继续进入该方法,我们知道它是拿到了所有BeanDefinitionRegistryPostProcessor类型的类,然后进行一些具体逻辑的判断。比如: 它是否也实现了PriorityOrdered接口、Ordered接口等一些列的接口判断,并且进行各种各样的排序工作,功能很多。

而我们关注的就是BeanDefinitionRegistryPostProcessor接口,继续往下debug,我们发现他会针对BeanDefinitionRegistryPostProcessor接口调用getBean方法的调用。在上一篇Spring之实例化Bean(2)_chen_yao_kerr的博客-CSDN博客中,我们解释了getBean方法就是实例化Bean的方法。也就是说,在我们进行常规的Spring 实例化Bean操作之前,我们会针对实现了BeanDefinitionRegistryPostProcessor接口的类进行提前实例化,然后又调用了invokeBeanDefinitionRegistryPostProcessors方法:

进入invokeBeanDefinitionRegistryPostProcessors方法中:

而我们的实现类中正好也重写了此方法,因此,它必然会进入我们的实现类中:

package com.xiangxue.jack.postProcessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        //生成bean
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(Dao2.class);

        //给Dao2属性值赋值,这样实例化完成以后就会有值了.MutablePropertyValues有很多方法,
        //也就意味着我们即使配置的类有错误,只要实现这个接口,我们依旧可以在类实例化之前,通过
        //对beanDefinition进行修改,从而达到修改类的目的
        MutablePropertyValues pValues = beanDefinition.getPropertyValues();
        pValues.addPropertyValue("name", "yyds");
        pValues.addPropertyValue("id", "测试001");

        //我们给beanDefinition起了个 名字叫 dao2, 然后注册到spring容器中
        registry.registerBeanDefinition("dao2", beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

进入我们的实现类以后,我们会把我们需要实例化BeanDefinition的java类,通过自己写的代码的方式也给实例化成BeanDefinition对象。也就是说,我们的这个java类,即使没有在spring.xml中配置具体的<bean>; 也没有注解,无法通过扫描的方式获取到这个java类的符合实例化BeanDefinition的class文件,我们依旧可以强行的让它实例化成BeanDefinition对象,然后实例化成Bean对象。

在Spring之实例化Bean(2)_chen_yao_kerr的博客-CSDN博客中,我们已经简单的介绍了实例化的主流程操作了,它就是拿到BeanDefinition对象进行实例化bean操作的。因此,咱们的实例化BeanDefinition操作完全符合实例化Bean的流程。 

此方法不仅可以实现我们常用的实例化bean操作,而且还可以对spring想要实例化bean的对象进行属性的修改,甚至可以删除beanDefinition对象,让一些对象无法被spring实例化,想想就开心,可以干很多的坏事。

下面再分享一个甜点:InstantiationAwareBeanPostProcessor

刚刚我们说到了干坏事,而InstantiationAwareBeanPostProcessor接口可以让你一次性彻底把坏事做绝了。下面代码就是干坏事的代码:

package com.xiangxue.jack.postProcessor;

import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyInstantiationAwareBeanPostProcessors implements InstantiationAwareBeanPostProcessor {

    public boolean postProcessAfterInstantiation(Object bean, String beanName) {
        //默认值是true,表示支持DI注册
        //此时,我们设置位FALSE,那么spring的DI操作将彻底失效
        return false;
    }

}

现在,我们需要一些测试的Demo:

case1: 测试Dao是否可以被实例化

package com.xiangxue.jack.bean;

import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;

@Repository
public class Dao {

    private String name;

    private String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @PostConstruct  //相当于init-method
    void init () {
        id = "001";
        name = "yy";
    }
    @Override
    public String toString() {
        return "name :" + name + " id :" + id;
    }
}

case2: 测试dao是否可以被注入

package com.xiangxue.jack.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyTestBean2 {

    @Autowired
    private Dao dao;

    public void system () {
        System.out.println(dao.toString());
    }
}

开始我们的测试:

首先测试dao是否可以被初始化:结果是可以正常实例化的

接下来dao对象是否可以被正常注入:结果是否定的,不能注入

 试想一下,Spring依赖注入都无法实现,那还要Spring干什么呢?而且这个错误,很难被发现,可谓是干坏事的鼻祖。

原理简单解析:

在上一篇Spring之实例化Bean(2)_chen_yao_kerr的博客-CSDN博客中,我们有一个方法没有讲解,那就是populateBean方法,它是依赖注入的核心方法,目的就是判断当前实例化的bean是否需要支持依赖注入的功能,里面有这么一段代码:

 它的目的就是判断当前实例化完成的bean对象,是否需要支持依赖注入功能,默认是支持的。而我们重写了这个接口的默认值,直接设置成了FALSE,这就导致这个接口默认就不支持DI 依赖注入, 那还扯什么呢,直接把Spring就给干废了。当前,对于一些简单的类,不涉及到任何的注入信息,那还是可以正常运行的。

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

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

相关文章

宝塔(二):升级JDK版本

目录 背景 一、下载JDK17 二、配置环境变量 三、配置新的JDK路径 背景 宝塔的软件商店只有JDK8&#xff0c;不满足我当前项目所需的JDK版本&#xff0c;因此想对JDK版本进行升级&#xff0c;升级为JDK17。 一、下载JDK17 先进入 /usr/lib/jvm 目录 点击终端&#xff0c;进…

OpenCV——line、circle、rectangle、ellipse、polylines函数的使用和绘制文本putText函数以及绘制中文的方法。

学习OpenCV的过程中&#xff0c;画图是不可避免的&#xff0c;本篇文章旨在介绍OpenCV中与画图相关的基础函数。 1、画线条——line()函数 介绍&#xff1a; cv2.line(image, start_point, end_point, color, thickness)参数&#xff1a; image: 图像start_point&#xff1a…

拉链表(小记)

拉链表创建外部表将编写的orders.txt上传到hdfs创建一个增减分区表将orders表的数据传入ods_orders_inc查看分区创建历史表插入数据操作创建外部表 create database lalian; use lalian;create external table orders(orderId int,createDate string,modifiedTime string,stat…

Redis集群方案应该怎么做?

今天我们来跟大家唠一唠JAVA核心技术-RedisRedis是一款流行的内存数据库&#xff0c;适用于高性能的数据缓存和实时数据处理。当需要处理大量数据时&#xff0c;可以使用Redis集群来提高性能和可用性。Redis在单节点模式下&#xff0c;虽然可以支持高并发、快速读写、丰富的数据…

sizeof与一维数组和二维数组

&#x1f355;博客主页&#xff1a;️自信不孤单 &#x1f36c;文章专栏&#xff1a;C语言 &#x1f35a;代码仓库&#xff1a;破浪晓梦 &#x1f36d;欢迎关注&#xff1a;欢迎大家点赞收藏关注 sizeof与一维数组和二维数组 文章目录sizeof与一维数组和二维数组前言1. sizeof与…

专业版即将支持自定义场景测试

物联网 MQTT 测试云服务 XMeter Cloud 专业版于 2022 年底上线后&#xff0c;已有不少用户试用&#xff0c;对数千甚至上万规模的 MQTT 并发连接和消息吞吐场景进行测试。同时我们也收到了希望支持更多物联网协议测试的需求反馈。 新年伊始&#xff0c;XMeter 团队全力聚焦于 …

搭建Gerrit环境Ubuntu

搭建Gerrit环境 1.安装apache sudo apt-get install apache2 注意:To run Gerrit behind an Apache server using mod_proxy, enable the necessary Apache2 modules: 执行:sudo a2enmod proxy_http 执行:sudo a2enmod ssl 使新的配置生效&#xff0c;需要执行如下命令:serv…

ctfshow【菜狗杯】wp

文章目录webweb签到web2 c0me_t0_s1gn我的眼里只有$抽老婆一言既出驷马难追TapTapTapWebshell化零为整无一幸免无一幸免_FIXED传说之下&#xff08;雾&#xff09;算力超群算力升级easyPytHon_P遍地飘零茶歇区小舔田&#xff1f;LSB探姬Is_Not_Obfuscateweb web签到 <?ph…

在社交媒体上行之有效的个人IP趋势

如果您认为无论是获得一份工作、建立一家企业还是推动个人职业发展&#xff0c;社交媒体都是帮助您实现目标的可靠工具&#xff0c;那么个人IP就是推动这一工具前进的燃料。个人IP反映了您是谁&#xff0c;您在所处领域的专业程度&#xff0c;以及您与他人的区别。社交媒体将有…

打破原来软件开发模式的无代码开发平台

前言传统的系统开发是需要大量的时间和成本的&#xff0c;如今无代码开发平台的出现就改变了这种状况。那么你知道什么是无代码开发平台?无代码开发对企业来说有什么特殊的优势么?什么是无代码平台无代码平台指的是&#xff1a;使用者无需懂代码或手写代码&#xff0c;只需通…

代码分享:gprMax钻孔地质雷达波场模拟

代码分享&#xff1a;gprMax钻孔地质雷达波场模拟 前言 gprMax模拟地面地质雷达被广泛使用&#xff0c;但是在钻孔内进行地质雷达的模拟较少。本博文尝试利用gprMax进行钻孔地质雷达的模拟&#xff0c;代码仅供大家借鉴。 文章目录代码分享&#xff1a;gprMax钻孔地质雷达波场…

【数据结构】链表练习题(1)

练习题1.移除链表元素(LeetCode203)2.链表的中间结点(LeetCode876)3.链表的倒数第k个结点(剑指offer)4.反转链表(LeetCode206)5.合并两个有序链表(LeetCode21)6.链表分割(牛客)7.链表的回文结构(牛客)1.移除链表元素(LeetCode203) 给你一个链表的头结点 head 和一个整数 val &…

第十四届蓝桥杯三月真题刷题训练——第 4 天

目录 题目 1 &#xff1a;九数算式_dfs回溯(全排列) 题目描述 运行限制 代码&#xff1a; 题目2&#xff1a;完全平方数 问题描述 输入格式 输出格式 样例输入 1 样例输出 1 样例输入 2 样例输出 2 评测用例规模与约定 运行限制 代码&#xff1a; 题目 1 &am…

数据结构刷题(十九):77组合、216组合总和III

1.组合题目链接过程图&#xff1a;先从集合中取一个数&#xff0c;再依次从剩余数中取k-1个数。思路&#xff1a;回溯算法。使用回溯三部曲进行解题&#xff1a;递归函数的返回值以及参数&#xff1a;n&#xff0c;k&#xff0c;startIndex(记录每次循环集合从哪里开始遍历的位…

场景式消费激发春日经济,这些电商品类迎来消费热潮

春日越临近&#xff0c;商机越浓郁。随着气温渐升&#xff0c;春日经济已经潜伏在大众身边。“春菜”、“春装”、“春游”、“春季养生”等春日场景式消费走热。 下面&#xff0c;鲸参谋为大家盘点几个与春日经济紧密相关的行业。 •春日仪式之春游踏青 ——户外装备全面开花…

查看 WiFi 密码的两种方法

查看 WiFi 密码的两种方法1. 概述2. 在控制面板中查看 WiFi 密码3. 使用 CMD 查看 WiFi 密码结束语1. 概述 突然忘记 WiFi 密码怎么办&#xff1f; 想连上某个使用过的 WiFi&#xff0c;但有不知道 WiFi 密码怎么办&#xff1f; 使用电脑如何查询 WiFi 密码&#xff1f; 以下是…

zabbix4.0 网络发现-自动添加主机-自动注册

zabbix的网络发现 网络发现的好处&#xff1a; 加快zabbix部署 简化管理 无需过多管理就能在快速变化的环境中使用zabbix zabbix网络发现给予以下信息 IP范围 可用的外部服务&#xff08;FTP&#xff0c;SSH&#xff0c;WEB&#xff0c;POP3&#xff0c;IMAP&#xff0c;TCP等&…

一篇深入解析BTF 实践指南

BPF 是 Linux 内核中基于寄存器的虚拟机&#xff0c;可安全、高效和事件驱动的方式执行加载至内核的字节码。与内核模块不同&#xff0c;BPF 程序经过验证以确保它们终止并且不包含任何可能锁定内核的循环。BPF 程序允许调用的内核函数也受到限制&#xff0c;以确保最大的安全性…

FPGA使用GTX实现SFP光纤收发SDI视频 全网首创略显高端 提供工程源码和技术支持

目录1、前言2、设计思路和框架3、vivado工程详解4、上板调试验证并演示5、福利&#xff1a;工程代码的获取1、前言 FPGA实现SDI视频编解码目前有两种方案&#xff1a; 一是使用专用编解码芯片&#xff0c;比如典型的接收器GS2971&#xff0c;发送器GS2972&#xff0c;优点是简…

如何让网络安全的防守技术更强?20年白帽子老江湖告诉你【蓝队】

网络安全的防守技术是网络安全工程师必备技能&#xff0c;只有攻防兼备的白帽子&#xff0c;才算是真正的网安精英。 网络安全的攻击技术在前面我已经讲过了&#xff0c;感兴趣的可以去看看&#xff1a; 90%的人都不算会网络安全&#xff0c;这才是真正的白帽子技术【红队】 . …