spring揭秘01-spring容器启动过程分析

news2024/11/15 6:03:21

文章目录

  • 【README】
  • 【1】Spring容器根据配置元素组装可用系统的过程
  • 【2】BeanFactoryPostProcessor-Bean工厂后置处理器
    • 【2.1】属性占位符配置器使用场景代码
    • 【2.2】CustomerEditorConfigurer-自定义编辑器配置器
      • 【2.3】自定义编属性编辑器案例代码

【README】

本文总结自《spring揭秘》,作者王福强,非常棒的一本书,墙裂推荐;

spring容器根据配置元素组装可用系统分2个阶段,包括spring容器启动, springbean实例化阶段; 本文详细分析spring容器启动阶段;


【1】Spring容器根据配置元素组装可用系统的过程

Spring容器根据配置元素组装可用系统的过程,有2个阶段:

  • spring容器启动;
  • springbean实例化;
    在这里插入图片描述

容器启动阶段: 加载配置元数据(xml文件),然后使用工具类如 BeanDefinitionReader对加载的配置元数据进行解析,并将结果编组为 BeanDefinition ,注册到相应的 BeanDefinitionRegistry,这样容器启动工作就完成了;

Bean实例化阶段: 容器会首先检查所请求的对象之前是否已经初始化,若没有,则根据注册的BeanDefinition实例化bean,并为其注入依赖。 如果该对象实现了某些回调接口,也会根据回调接口的要求来装配它; 当该对象被装配完成后 ,容器会立即将其返回给请求方使用;


【2】BeanFactoryPostProcessor-Bean工厂后置处理器

BeanFactoryPostProcessor: Spring提供了叫做 BeanFactoryPostProcessor 容器扩展机制; 该机制允许我们在容器启动阶段完成后新增逻辑;

常用BeanFactoryPostProcessor:

  1. PropertySourcePlaceHolderConfigurer:属性占位符配置器, 如jdbc连接串属性通过properties文件的属性值 替换 占位符;
  2. PropertyOverrideConfigurer : 属性覆盖替换配置器;如修改属性值;
  3. CustomEditorConfigurer:自定义编辑器配置器,用于不同数据格式间的转换;

【补充】

(1)上述2个BeanFactoryPostProcessor 都是通过修改BeanDefinition 来对属性进行替换或修改的;

(2) CustomerEditorConfigurer:没有修改BeanDefinition,而是把后期要用到的信息注册到容器;

【2.1】属性占位符配置器使用场景代码

PropertySourcesPlaceholderConfigurer-属性占位符配置器使用场景:初始化数据库连接池属性, 并利用 PropertyOverrideConfigurer 重写属性值;

【PropertySourcesPlaceholderConfigurerMain】入口

public class PropertySourcesPlaceholderConfigurerMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans0404.xml");
        BasicDataSource dataSource = context.getBean("dataSource", BasicDataSource.class);
        System.out.println(dataSource.getUrl());
        System.out.println(dataSource.getUserName());
        System.out.println(dataSource.getDriverClassName());
    }
}

【beans0404.xml】

<!-- 为 PropertySourcesPlaceholderConfigurer 这个BeanFactoryPostProcessor 配置属性文件地址 -->
    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="locations">
            <value>jdbc.properties</value>
        </property>
    </bean>

    <!-- 为 PropertyOverrideConfigurer 这个BeanFactoryPostProcessor 配置重写属性文件的地址 -->
    <bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
        <property name="locations" value="ds-pool-override.properties" />
    </bean>

    <!-- 数据源bean,其中属性值通过变量指定,变量通过 BeanFactoryPostProcessor 设置值-->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="url">
            <value>${jdbc.url}</value>
        </property>
        <property name="driverClassName">
            <value>${jdbc.driverClassName}</value>
        </property>
        <property name="username">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
    </bean>

【jdbc.properties】

jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=root


【ds-pool-override.properties】重写属性值的属性文件

dataSource.username=rootOverride

【打印日志】

jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai
rootOverride
com.mysql.cj.jdbc.Driver

【2.2】CustomerEditorConfigurer-自定义编辑器配置器

应用场景: xml配置的bean信息都是字符串,但最终都要要转换为bean对象的,从字符串类型到对象类型的转换,就是由CustomerEditorConfigurer(EditorConfigurer)来完成的;

  • 只要为每种对象类型提供一个 PropertyEditor,就可以做类型转换

Spring 提供的PropertyEditor列表

  • (1) StringArrayPropertyEditor:把符合csv格式的字符串转换为String[] 数组的形式;类似的还有 ByteArrayPropertyEditor, CharArrayPropertyEditor;
  • (2) ClassEditor: 根据class名称转为 Class对象;
  • (3) FileEditor: file类型的PropertyEditor;类似的还有InputStreamEditor, URLEditor;
  • (4) LocaleEditor: 本地化转换;
  • (5) PatternEditor: 正则表达式转换

自定义属性编辑器PropertyEditor: 继承自 PropertyEditorSupport ; PropertyEditorSupport 实现了 PropertyEditor 接口; PropertyEditor 接口定义如下:

public interface PropertyEditor {

    void setValue(Object value);

    Object getValue();

    boolean isPaintable();
    
    void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box);

    String getJavaInitializationString();

    String getAsText();
   
    void setAsText(String text) throws java.lang.IllegalArgumentException;
    
    String[] getTags();
    
    java.awt.Component getCustomEditor();

    boolean supportsCustomEditor();

    void addPropertyChangeListener(PropertyChangeListener listener);

    void removePropertyChangeListener(PropertyChangeListener listener);
}

【2.3】自定义编属性编辑器案例代码

自定义日期i字符串转日期类型的编辑器;

【CustomPropertyEditorMain】入口

public class CustomPropertyEditorMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans0404.xml");
        System.out.println(context.getBean("customDateDto", CustomDateDto.class));
    }
}

【beans0404.xml】

<!-- 自定义属性编辑器  -->
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="propertyEditorRegistrars">
        <list>
            <ref bean="customDatePropertEditroResigtrar" />
        </list>
    </property>
</bean>
<bean id="customDatePropertEditroResigtrar" class="com.tom.springnote.chapter04.t0404.CustomDatePropertEditroResigtrar">
    <property name="customDatePropertyEditor">
        <ref bean="customDatePropertyEditor"/>
    </property>
</bean>
<bean id="customDatePropertyEditor" class="com.tom.springnote.chapter04.t0404.CustomDatePropertyEditor">
    <property name="datePattern" value="yyyy-MM-dd" />
</bean>
<bean id="customDateDto" class="com.tom.springnote.chapter04.t0404.CustomDateDto">
    <property name="date" value="2024-08-04" />
</bean>

在这里插入图片描述

【CustomDatePropertEditroResigtrar】自定义日期属性编辑器注册器

public class CustomDatePropertEditroResigtrar implements PropertyEditorRegistrar {
    private PropertyEditor customDatePropertyEditor;
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(Date.class, getCustomDatePropertyEditor());
    }

    public PropertyEditor getCustomDatePropertyEditor() {
        return customDatePropertyEditor;
    }

    public void setCustomDatePropertyEditor(PropertyEditor customDatePropertyEditor) {
        this.customDatePropertyEditor = customDatePropertyEditor;
    }
}

【CustomDatePropertyEditor】自定义日期属性编辑器

public class CustomDatePropertyEditor extends PropertyEditorSupport {
    private String datePattern;

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        try {
            setValue(new SimpleDateFormat(getDatePattern()).parse(text));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public String getDatePattern() {
        return datePattern;
    }

    public void setDatePattern(String datePattern) {
        this.datePattern = datePattern;
    }
}

【CustomDateDto】自定义dto (带date类型属性)

public class CustomDateDto {
    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "CustomDateDto{" +
                "date=" + date +
                '}';
    }
}

【打印日志】 (把字符串2024-08-04转换为 date类型属性)

CustomDateDto{date=Sun Aug 04 00:00:00 CST 2024}

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

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

相关文章

为什么electron占用空间大,而Tauri占用小,他们不都是封装Chromium吗

Electron 和 Tauri&#xff08;使用 WebView&#xff09;的确都涉及嵌入浏览器引擎来渲染 HTML、CSS 和 JavaScript&#xff0c;但它们的架构和设计有显著不同&#xff0c;这导致了它们在应用程序体积和资源占用上的差异。以下是一些关键的原因&#xff1a; 1. 嵌入的浏览器引…

【中等】 猿人学web第一届 第6题 js混淆-回溯

文章目录 请求流程请求参数 加密参数定位r() 方法z() 方法 加密参数还原JJENCOde js代码加密环境检测_n("jsencrypt")12345 计算全部中奖的总金额请求代码注意 请求流程 请求参数 打开 调试工具&#xff0c;查看数据接口 https://match.yuanrenxue.cn/api/match/6 请…

MySQL运维-分库分表

介绍 问题分析 拆分策略 垂直拆分 水平拆分 实现技术 Mycat概述 介绍 概念介绍 Mycat配置 schema.xml schema标签 schema标签&#xff08;table&#xff09; datanode标签 datahost标签 rule.xml sever.xml system标签 user标签 Mycat分片 分片规则-范围 分片规则-取模 分…

linux部署elasticserch单节点

简介 Elasticsearch概述&#xff1a;Elasticsearch是一个建立在Apache Lucene之上的分布式、实时文档存储搜索引擎&#xff0c;它能够胜任上百个服务节点的扩展&#xff0c;并支持PB级别的结构化或非结构化数据。 Lucene与Elasticsearch&#xff1a;简要介绍Lucene作为搜索引擎…

分布式中的CAP理论是什么?BASE理论是什么?看完你就彻底懂啦

CAP 理论 CAP理论是分布式系统理论中的一个重要概念&#xff0c;它阐述了在分布式计算环境中&#xff0c;一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和分区容错性&#xff08;Partition Tolerance&#xff09;三者之间的权衡关系…

深化解析:企业内耗的解决之道

在缺乏有效的冲突解决机制下&#xff0c;企业内部冲突难以得到妥善处理&#xff0c;这加剧了内耗&#xff0c;破坏了团队协作的和谐氛围。而当工作环境充满紧张和压力时&#xff0c;员工容易陷入焦虑和疲劳的困境&#xff0c;进而影响工作效率和团队士气。 当员工感受不到应有…

拯救中医 刻不容缓

文&#xff5c;琥珀食酒社 作者 | 积溪 “真是毫无底线” “这是挂羊头卖狗肉” “这钱也赚&#xff0c;华为太让人失望了” 看到网上的这些评论 我的拳头都硬了 华为进军中医药产业 给咱中医药打造独一无二的人工智能大模型 让中医彻底摆脱西方的围剿 这是多好的事情…

如何提取PDF其中的一页或多页?推荐4种方法!

工作中&#xff0c;我们经常需要用到PDF文件&#xff0c;如果需要提取PDF文件中的其中一页或多页内容&#xff0c;要如何做呢&#xff1f;下面小编分享4种方法&#xff0c;看下哪种适合你&#xff01; 方法1&#xff1a;使用复制粘贴 如果PDF文件中需要提取的内容是纯文字&am…

一起学习LeetCode热题100道(42/100)

42.将有序数组转换为二叉搜索树(学习) 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0…

python连接mysql+mycat读写分离实现

python连接mysql >>>import pymysql >>>connpymysql.connect(host"192.168.118.57",port3306,database"test",user"root",password"root") >>> cursorconn.cursor() >>> cursor.execute(&quo…

ISO 13485认证:医疗器械行业的质量护航者

在医疗器械行业&#xff0c;产品质量关乎生命。为确保每一件医疗器械的安全与可靠&#xff0c;ISO 13485认证作为全球公认的质量管理体系标准&#xff0c;正为无数企业提供强大的质量保障。对于企业来说&#xff0c;获得这一认证不仅是质量管理的提升&#xff0c;更是开拓全球市…

FFmpeg源码:av_log2函数分析

一、av_log2函数的声明 av_log2函数声明在FFmpeg源码&#xff08;本文演示用的FFmpeg源码版本为7.0.1&#xff09;的头文件libavutil/common.h中&#xff1a; #ifndef av_log2 av_const int av_log2(unsigned v); #endif 该函数作用是&#xff1a;求形参v是2的多少次幂&#…

【漏洞复现】某成科信票务管理系统 TicketManager SQL注入漏洞

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 某成科信票务管理系统以私有/公有云为基础部署&#xff0c;实现了基础六管控多协同的智慧票务系统。该系…

企业的安全管家——加密软件

一、加密软件的重要性 数据安全保护&#xff1a;加密软件能够对企业数据进行加密处理&#xff0c;确保即使数据被窃取&#xff0c;也无法被未经授权的人员轻易解密。 合规性要求&#xff1a;许多行业和企业都面临严格的数据保护法规要求&#xff0c;如GDPR、HIPAA等&#xff…

和小米比起来希喂宠物空气净化器怎么样?

有宠物用哪个牌子空气净化机比较好呢&#xff1f;有宠物的家庭除异味、除毛、除菌需求比不养宠的更大&#xff0c;所以有宠物的家庭选空气净化器时一定要着重看这几点。 最近&#xff0c;我发现身边的朋友们都开始重视起家居空气质量&#xff0c;特别是有了宠物之后&#xff0…

Linux笔记 --- 文件属性

在操作文件时时常要获取文件的属性&#xff0c;比如类型、大小、权限、所有者等等信息&#xff0c;这些信息对于文件的传输管理等非常重要&#xff0c;而这些信息则可以通过下面这些函数获取。 这三个函数功能相同&#xff0c;区别在于&#xff0c;stat参数是文件名字&#xff…

git的下载与安装(Windows)

Git是一个开源的分布式版本控制系统&#xff08;Distributed Version Control System&#xff0c;简称DVCS&#xff09;&#xff0c;它以其高效、灵活和强大的功能&#xff0c;在现代软件开发中扮演着至关重要的角色。 git官网&#xff1a;Git (git-scm.com) 1.进入git官网 2…

[图解]用例规约之扩展路径

1 00:00:01,710 --> 00:00:03,670 基本路径写完之后 2 00:00:04,690 --> 00:00:07,270 接下来就是扩展路径 3 00:00:08,620 --> 00:00:14,000 扩展路径就是系统要处理的意外和分支 4 00:00:14,010 --> 00:00:19,710 系统要处理的 5 00:00:20,970 --> 00:00:…

【题解】【高精度】—— [NOIP2003 普及组] 麦森数

【题解】【高精度】—— [NOIP2003 普及组] 麦森数 [NOIP2003 普及组] 麦森数题目描述输入格式输出格式输入输出样例输入 #1输出 #1 提示 1.题意解析1.1.求位数1.2.输出最后500位1.2.1.输出1.2.2.高精度乘法1.2.3.快速幂 2.AC代码 [NOIP2003 普及组] 麦森数 题目描述 形如 2…

(一)C++学习笔记(满满的都是水货咕噜!)

1、基本概念 1 – 什么是C c就是c语言的扩展&#xff0c;完全兼容c语言 c语言在c语言的基础上添加了面向对象编程和泛型编程的支持。c继承了c语言高效&#xff0c;简洁&#xff0c;快速和可移植的传统。 c融合了3种不同的编程方式: c语言代表的过程性语言. c在c语言基础上添加…