Spring底层原理(三)

news2025/1/11 7:46:21

Spring底层原理(三)

Bean的生命周期
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        context.close();
    }
}
​
@Slf4j
@Component
public class LifeCycleBean {
    public LifeCycleBean(){
        log.info("构造");
    }
​
    @Autowired
    public void autowire(@Value("${JAVA_HOME}") String home){
        log.info("依赖注入:{}",home);
    }
​
    @PostConstruct
    public void init(){
        log.info("初始化");
    }
​
    @PreDestroy
    public void destroy(){
        log.info("销毁");
    }
}

启动容器后会得到以下结果

 

Bean的生命周期为:构造方法 -> 依赖注入->初始化 ->销毁

与Bean生命周期相关的后置处理器

PostProcessor中文意思为后置处理器

InstantiationAwareBeanPostProcessorDestructionAwareBeanPostProcessor都是BeanPostProcessor的子接口

@Slf4j
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.info("<<<< 销毁前执行,如@PreDestory");
        }
    }
​
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.debug("<<<< 实例化之前执行,这里返回的对象会替换掉原本的bean");
        }
        return null;
    }
​
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.debug("<<<< 实例化后执行,这里返回false会跳过依赖注入阶段");
        }
        return true;
    }
​
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.debug("<<<< 依赖注入阶段执行,如@Autowired、@Value、@Resource");
        }
        return pvs;
    }
​
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.debug("<<<< 初始化之前执行,这里返回的对象会替换掉原本的bean,如@PostConstruct、@ConfigurationProperties");
        }
        return bean;
    }
​
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
           log.debug("<<<< 初始化之后执行,这里返回的对象会替换掉原本的bean,如代理增强");
        }
        return bean;
    }
}
Bean后置处理器与模板方法模式
public class MethodTemplateTest {
    public static void main(String[] args) {
        MyBeanFactory factory = new MyBeanFactory();
        factory.addProcessor(bean -> System.out.println("解析@Autowired"));
        factory.addProcessor(bean -> System.out.println("解析@Resources"));
        factory.getBean();
    }
​
    static class MyBeanFactory {
        private List<BeanPostProcessor> processors = new ArrayList<>();
​
        public void addProcessor(BeanPostProcessor postProcessor) {
            processors.add(postProcessor);
        }
​
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造:" + bean);
            System.out.println("依赖注入:" + bean);
            for (BeanPostProcessor processor : processors) {
                processor.inject(bean);
            }
            System.out.println("初始化:" + bean);
            return bean;
        }
    }
​
    interface BeanPostProcessor {
        void inject(Object bean);//对依赖注入阶段进行拓展
    }
}
  • 将代码中不确定的部分抽象成接口,供后续拓展

常见的bean后置处理器
public class A4Application {
    public static void main(String[] args) {
        //GenericApplicationContext是一个干净的容器,没有添加BeanFactory后置处理器和Bean后置处理器
        GenericApplicationContext context = new GenericApplicationContext();
        //注册bean
        context.registerBean("bean1",Bean1.class);
        context.registerBean("bean2",Bean2.class);
        context.registerBean("bean3",Bean3.class);
        
        //初始化容器
        context.refresh();//执行beanFactory后置处理器,添加bean后置处理器,初始化所有单例bean
​
        //销毁容器
        context.close();
    }
}

添加AutowiredAnnotationBeanPostProcessor

context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new    ContextAnnotationAutowireCandidateResolver());
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
  • ContextAnnotationAutowireCandidateResolver:用于支持解析@Value

  • AutowiredAnnotationBeanPostProcessor:该处理器用于解析@Autowired @Value

添加CommonAnnotationBeanPostProcessor

context.registerBean(CommonAnnotationBeanPostProcessor.class);
  • CommonAnnotationBeanPostProcessor:用于解析@Resurce @PostConstruct @PreDestroy

ConfigurationPropertiesBindingPostProcessor.register(context);
  • ConfigurationPropertiesBindingPostProcessor:用于解析@ConfigurationProperties

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

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

相关文章

MySQL身份验证绕过漏洞

搭建 vmihub靶场:vulhub靶场搭建与使用_剁椒鱼头没剁椒的博客-CSDN博客 运行漏洞: # 这里要改成自己的 /vulhub-master 存放目录 cd /etc/docker/vulhub-master/mysql/CVE-2012-2122# 关闭防火墙,不然就要放行3306端口 systemctl stop firewalld# 重启 Docker 服务 servic…

C# | Linq基本功 —— 必学的必熟的10个方法

C# Linq基本功 —— 必学的必熟的10个方法 文章目录 C# Linq基本功 —— 必学的必熟的10个方法1. Linq简介1.1 什么是Linq1.2 Linq的优势 2. Linq基本方法2.1 Where方法2.2 Select方法2.3 OrderBy方法2.4 GroupBy方法2.5 Join方法2.6 Any方法2.7 All方法2.8 First方法2.9 Skip方…

1024勋章

&#x1f338;关于重阳节的一些发疯日常&#xff08;昨天的聊天记录&#xff0c;今天发系列&#xff09;&#x1f605; &#x1f338;没错&#xff0c;发出来单纯觉得好玩儿&#x1f609;(为了1024勋章&#x1f60f;)芜湖&#xff01;

Kepware带你玩转IEC60870-104驱动

随着越来越多电力设备自动化程度的不断提高以及OPC协议的广泛应用&#xff0c;越多客户倾向于使用更为方便、快捷的方式去获取数据&#xff0c;IEC60870-5-104协议作为一个标准的电子自动化协议&#xff0c;在电力自动化现场应用非常广泛。 本文介绍KEPServerEX的IEC-104驱动&…

WeakMap 弱引用 不会被GC所考量

WeakMap是一种特殊的Map数据结构&#xff0c;只能以引用作为key&#xff0c;并且不会阻止其被垃圾回收。WeakMap的使用如下&#xff1a; 1. 创建WeakMap对象&#xff1a; const weakMap new WeakMap();2. 添加键值对&#xff1a;使用set()方法向WeakMap中添加键值对。注意这里…

c++ 模版的一些注意问题

声明和定义不可分离 举个例子&#xff1a; 定义一个Stack.h: 这里放声明 #include<iostream>using namespace std;template<class T> T Add(const T& left, const T& right);定义一个Stack.cpp, 这里面放定义: template<class T> T Add(const T&a…

虚拟机VMware Workstation Pro安装配置使用服务器系统ubuntu-22.04.3-live-server-amd64.iso

虚拟机里安装ubuntu-23.04-beta-desktop-amd64开启SSH(换源和备份)配置中文以及中文输入法等 ​一、获取Ubuntu服务器版 获取Ubuntu服务器版 二、配置虚拟机 选择Custom(advanced)&#xff1a; 选择Workstation 17.x: 选择“I will install the operating system later.”…

HashMap源码解析_jdk1.8(二)

HashMap源码解析_jdk1.8&#xff08;二&#xff09;构造函数put方法resize扩容方法 HashMap源码解析_jdk1.8&#xff08;二&#xff09; 构造函数 HashMap提供了如下几个构造函数&#xff1a; /*** 构造一个具有指定初始容量和负载因子的空HashMap.** param initialCapacit…

Android SystemUI setSystemUiVisibility()参数Flag详解

1&#xff1a;相关 Flag 特性详解 View.SYSTEM_UI_FLAG_LAYOUT_STABLE&#xff1a; 特性&#xff1a;默认状态下 &#xff0c;稳定页面显示布局。 当 StatusBar和 NavigationBar动态显示和隐藏时&#xff0c;系统为 fitSystemWindow“true”的view设置的padding大小都不会变化…

《机器学习实战》学习记录-ch4

4.1 线性回归 import numpy as np import matplotlib.pyplot as plt import pandas as pdX 2 * np.random.rand(100,1) # 生成 [0,1) 之间的数据 y 4 3 * X np.random.randn(100,1) # 生成一组正态分布的数据&#xff0c; 高斯噪声X_b np.c_[np.ones((100,1)), X] X_b[:5…

h265格式怎么转换mp4?一分钟教会你!

H265是一种视频编码标准&#xff0c;也被称为HEVC&#xff08;High Efficiency Video Coding&#xff09;。由联合视频组&#xff08;JVET&#xff09;开发的&#xff0c;是一种专为高清视频设计的压缩标准。播放H265文件&#xff0c;通常需要使用支持H265解码的播放器&#xf…

Docker 网络与Cgroup资源限制

目录 一、Docker 网络实现原理&#xff1a; 二、Docker 的网络模式&#xff1a; 三、网络模式详解&#xff1a; 1. host模式&#xff1a; 2. container模式&#xff1a; 3. none模式: 4&#xff0e;bridge模式: 5&#xff0e;自定义网络: 四、Cgroup资源控制&#xff1a; …

仿真调试stm32汇编代码

软件准备 ubuntu交叉编译链工具&#xff1a;arm-none-eabi-gcc, arm-none-eabi-as, arm-none-eabi-ldqemu仿真软件&#xff1a;支持stm32版本调试工具&#xff1a;gdb-multiarch 启动仿真实验 汇编代码 .thumb .syntax unified.equ STACKINIT, 0x20005000.section .text .o…

玩具玩偶经营小程序商城的作用是什么

对品牌商而言&#xff0c;传统的批发商模式&#xff0c;不利于品牌传播及构建自有私域流量池&#xff0c;无法与消费者面对面交流&#xff0c;一旦销售量不好&#xff0c;只能受限于下游的以销定产。无论销售商还是品牌商即使入驻第三方平台&#xff0c;也会面临佣金、广告位问…

开发习惯养成系列

1 开发习惯养成系列 2

【趣味Javascript】前端开发中不为人知的LHS和RHS查询,你真的弄明白了吗? 《1024程序员节特别篇》

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

你知道AI数字人可以用在哪些行业吗?

引言&#xff1a; 随着科技的不断进步&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到各个领域&#xff0c;其中包括宣传营销。AI数字人是宣传营销领域的一项革命性技术&#xff0c;它们为企业提供了全新的机会&#xff0c;从客户互动到市场分析&#xff0c;再到销…

jenkins实践篇(1)——基于分支的自动发布

问题背景 想起初来公司时&#xff0c;我们还是在发布机上直接执行发布脚本来运行和部署服务&#xff0c;并且正式环境和测试环境的脚本都在一起&#xff0c;直接手动操作脚本时存在比较大的风险就是将环境部署错误&#xff0c;并且当时脚本部署逻辑还没有检测机制&#xff0c;…

初学编程入门基础教学视频,初学编程学什么语言

学习编程捷径&#xff1a;&#xff08;不论是正在学习编程的大学生&#xff0c;还是IT人士或者是编程爱好者&#xff0c;在学习编程的过程中用正确的学习方法可以达到事半功倍的效果。对于初学者&#xff0c;可以通过下面的方法学习编程&#xff0c;通过对成百上千个实例练习&a…

ilr normalize isometric log-ratio transformation

visium_heart/st_snRNAseq/05_colocalization/create_niches_ct.R at 5b30c7e497e06688a8448afd8d069d2fa70ebcd2 saezlab/visium_heart (github.com) 更多内容&#xff0c;关注微信&#xff1a;生信小博士 The ILR (Isometric Log-Ratio) transformation is used in the anal…