【Java设计模式】二十四、Spring重要接口回顾

文章目录

  • 1、Spring架构概述
  • 2、BeanFactory接口
  • 3、BeanDefinition
  • 4、BeanDefinitionReader
  • 5、BeanDefinitionRegistry
  • 6、创建容器

1、Spring架构概述

Spring包含约20个模块,1300多个文件。主要架构:

在这里插入图片描述

Spring面向Bean编程,Bean即受Spring容器管控的对象,而核心容器则是由beans、core、context、express(Spring Expression Language,SpEL)4个模块组成。

1)spring-beans 和 spring-core是核心,包含了控制反转IoC和依赖注入DI。核心接口BeanFactory。

BeanFactory属于延时加载,也就是说在实例化容器对象后并不会自动实例化Bean,只有当Bean被使用时,BeanFactory才会对该 Bean 进行实例化与依赖关系的装配。

2)spring-context模块,扩展了BeanFactory,其核心接口ApplicationContext就是BeanFactory的子接口。该模块添加了Bean的生命周期控制等

与BeanFactory不同,ApplicationContext实例化后会自动对所有的单实例Bean进行实例化与依赖关系的装配,使之处于待用状态。

最后,关于上面BeanFactory延时加载,而ApplicationContext非延时加载的Demo。先准备个测试Bean:

<bean id="userService" class="com.plat.service.impl.UserServiceImpl"><property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="com.plat.dao.impl.UserDaoImpl"></bean>

改下类的无参构造,让它在被调用时打印一句话,以便下面观察Bean何时被实例化的:

@Setter
public class UserServiceImpl implements UserService {private UserDao ueserDao;   //声明个UserDao类型的对象public UserServiceImpl(){System.out.println("userService被创建了");}
}
public class UserDaoImpl implements UserDao {public UserDaoImpl(){System.out.println("UserDao被创建了");}
}

打断点:

//创建Spring容器对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicaitonContext.xml");
//从容器中获取Bean
UserService bean = applicationContext.getBean("userService", UserService.class);

在这里插入图片描述
同样的断点:

//创建Spring容器对象
BeanFactory beanFacotry = new XmlBeanFactory(new ClassPathResource("applicaitonContext.xml"));
//从容器中获取Bean
UserService bean = beanFacotry.getBean("userService", UserService.class);

在这里插入图片描述

2、BeanFactory接口

Spring中Bean的创建是工厂模式的应用,确切的说是简单工厂 + 配置文件的形式
在这里插入图片描述

这一系列的Bean工厂,即IoC容器,帮助开发者创建和管理对象及对象间的依赖关系。BeanFactory作为最顶层的一个接口,定义了IoC容器的基本功能规范。

BeanFactory的源码:

public interface BeanFactory {String FACTORY_BEAN_PREFIX = "&";//根据bean的名称获取IOC容器中的的bean对象Object getBean(String name) throws BeansException;//根据bean的名称获取IOC容器中的的bean对象,并指定获取到的bean对象的类型,这样我们使用时就不需要进行类型强转了<T> T getBean(String name, Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);//判断容器中是否包含指定名称的bean对象boolean containsBean(String name);//根据bean的名称判断是否是单例boolean isSingleton(String name) throws NoSuchBeanDefinitionException;boolean isPrototype(String name) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;String[] getAliases(String name);
}

BeanFactory接口有个重要的子接口ApplicationContext,它规范了其子类IoC容器中的bean对象是非延时加载,即在创建容器对象的时候就对象bean进行初始化,并存储到一个容器中。

在这里插入图片描述

如上,不同的子类,即不同的IoC容器,它们生产对象的方式也是不同的:

  • ClasspathXmlApplicationContext : 根据类路径加载xml配置文件,并创建IOC容器对象。
  • FileSystemXmlApplicationContext :根据系统路径加载xml配置文件,并创建IOC容器对象。
  • AnnotationConfigApplicationContext :加载注解类配置,并创建IOC容器。

在这里插入图片描述

3、BeanDefinition

开发者在xml中描述自己的Bean,而定义的Bean的那些属性,在Spring中用BeanDefinition来描述。

在这里插入图片描述

BeanDefinition对xml中的Bean相关的属性进行封装,那这个xml配置文件由谁解析呢 ⇒ BeanDefinitionReader

4、BeanDefinitionReader

Bean的解析主要就是对Spring配置文件的解析。这个解析过程主要通过BeanDefinitionReader来完成。

在这里插入图片描述

BeanDefinitionReader接口定义了解析的规范,其不同的子实现类,则用于解析不同的配置文件,如xml、Properties

public interface BeanDefinitionReader {//获取BeanDefinitionRegistry注册器对象BeanDefinitionRegistry getRegistry();/*下面的loadBeanDefinitions都是加载bean定义,从指定的资源中*/int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}

5、BeanDefinitionRegistry

BeanDefinitionReader用来解析bean的定义,然后封装到BeanDefinition对象。而封装的BeanDefinition对象,则存储到了BeanDefinition的注册中心,该注册中心的顶层接口就是BeanDefinitionRegistry

public interface BeanDefinitionRegistry extends AliasRegistry {//往注册表中注册beanvoid registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;//从注册表中删除指定名称的beanvoid removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;//获取注册表中指定名称的beanBeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;//判断注册表中是否已经注册了指定名称的beanboolean containsBeanDefinition(String beanName);//获取注册表中所有的bean的名称,返回一个数组String[] getBeanDefinitionNames();//获取注册表中BeanDefiniton的数量int getBeanDefinitionCount();//判断bean的名字在注册表中是否已被使用boolean isBeanNameInUse(String beanName);
}

Ctrl+H看继承体系:

在这里插入图片描述

看其子类的源码,里面定义了Map,key为String,value为BeanDefinition。

在这里插入图片描述

6、创建容器

以ClassPathXmlApplicationContext这个Ioc类为例,创建它的对象(IoC容器对象)是传入了xml的文件名,找到源码中的相关构造方法,this调用了另一个构造方法,继续跟进:

在这里插入图片描述

看到调用了refresh方法:

在这里插入图片描述
跟进refresh方法,发现到了父类的refresh方法。refresh方法是一个模板方法,该方法定义好了 IoC 容器的启动流程(加载配置文件、初始化Bean对象、将Bean对象存储到容器中等等),有些逻辑要交给其子类实现。它对 Bean 配置资源进行载入,ClassPathXmlApplicationContext通过调用其父类AbstractApplicationContext的refresh方法启动整个IoC容器对Bean定义的载入过程。

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

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

相关文章

SQLiteC/C++接口详细介绍之sqlite3类(十七)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十六&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍之sqlite3类&#xff08;十八&#xff09; ​ 53.sqlite3_trace_v2 函数功能&#x…

hcia静态综合实验

1.数清广播域&#xff0c;划分网段 6个广播域加8个环回接口&#xff0c;总共14个广播域 六个骨干链路&#xff0c;每条骨干链路只需要两个ip地址。 192.168.1.0/30 有4个ip地址&#xff0c;其中主机位全0与全1不能用&#xff0c;剩两个ip地址可用&#xff0c;现在有六条骨干…

2024Vue高频面试题

前言: Vue 在前端开发领域拥有强劲的发展势头,以下是一些 Vue 的发展趋势: 1.持续增长的用户数量: Vue 作为一款轻量级、易学易用的前端框架,吸引了越来越多的开发者和企业选择使用。其活跃的社区和丰富的资源也促进了用户数量的不断增长。 2.生态系统不断丰富: 随着 V…

Gitlab CI/CD 自动化打包部署前端(vue)项目

一、虚拟机安装 1.vmware下载 2.镜像下载 3.Ubuntu 4.新建虚拟机 一直点下一步&#xff0c;直到点击完成。 5.分配镜像 二、Gitlab CI/CD 自动化部署项目 1.配置GitLab CI/CD&#xff1a; A.在你的Vue.js项目中&#xff0c;创建一个名为.gitlab-ci.yml的文件&#xff0…

System Verilog的接口、程序块与断言解析

接口、程序块与断言 1 接口 1.1 使用接口简化连接 // 接口 interface arb_if(input bit clk);logic [1:0] grant,request;logic rst; endinterface// 使用了简单接口的仲裁器 module arb (arb_if arbif);...always(posedge arbif.clk or posedge arbif.rst)beginif(arbif.rs…

【图像分割】使用Otsu 算法及迭代计算最佳全局阈值估计并实现图像分割(代码实现与分析)

本实验要求理解全局阈值分割的概念&#xff0c;并实现文本图像分割。需要大家深入理解Ostu 算法的实现过程及其迭代原理&#xff0c;同时通过学习使用Otsu 算法及其迭代&#xff0c;实践图像分割技术在文本图像处理中的应用。 以下将从实验原理、实验实现、实验结果分析三部分对…

springboot项目读取excel表格内容到数据库,excel表格字段为整数的读取方法

在我昨天的项目中&#xff0c;我需要把excel表格中字段为整数的字段读取到数据库中进行保存&#xff0c;但是在内置方法中并没有读取整数的方法&#xff08;也有可能是我没发现&#xff0c;太菜了~~&#xff09;&#xff0c;那接下来我就提供给大家一个简单地方法来读取excel表…

力扣977. 有序数组的平方

思路&#xff1a;暴力法&#xff1a;全部平方&#xff0c;然后调用排序API&#xff0c;排序算法最快是N*log(N)时间复制度。 双指针法&#xff1a;要利用好原本的数组本就是有序的数组这个条件&#xff0c; 只是有负数 导致平方后变大了&#xff0c;那么平方后的最大值就是在两…

PTAL1-006 连续因子

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

数据可视化-ECharts Html项目实战(2)

在之前的文章中&#xff0c;我们学习了如何创建简单的折线图&#xff0c;条形图&#xff0c;柱形图并实现动态触发&#xff0c;最大最小平均值。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下…

【Windows Defender 排除指定 文件夹、文件夹以提升性能】

使用webStorm时候提醒排出程序和目录提升性能, 于是我就把我的代码目录和常用程序全部排出, 不过不知道能不能提升多少性能, 先加上再说 一.使用UI配置排出项 隐私与安全性安全中心 病毒与威胁防护 添加或删除排出项 配置 二.使用命令配置 使用 PowerShell开启自动排除列表…

Android 开发 地图 polygon 显示信息

问题 Android 开发 地图 polygon 显示信息 详细问题 笔者进行Android项目开发&#xff0c;接入高德地图绘制区域后&#xff0c;需要在指定区域&#xff08;位置&#xff09;内显示文本信息&#xff0c;如何实现 实现效果 解决方案 代码 import com.amap.api.maps.model.T…