深入理解 : Spring BeanFactory

news/2024/10/10 21:08:18

深入理解 : Spring BeanFactory

1 概述:Spring BeanFactory

1.1 什么是 BeanFactory : Spring Bean 容器的抽象接口

  • BeanFactory 是Spring框架(spring-beans模块)中的一个接口,它是一个工厂类,用来创建和管理Spring中的Bean对象。
  • BeanFactory接口定义了Spring容器的基本规范和行为,它提供了一种机制来将配置文件中定义的Bean实例化、配置和管理起来。

1.2 BeanFactory 所属模块: Spring Context

1.3 BeanFactory 的作用

  • BeanFactory的主要作用是提供Bean的创建、配置、初始化和销毁等基本操作。
  • 它可以根据配置文件或注解来创建并管理Bean实例,并提供了各种方法来获取和操作Bean实例。

1.4 BeanFactory 的接口定义

  • org.springframework.beans.factory 源码的文档描述

这是访问Spring bean容器的根接口。
这是bean容器的基本客户端视图;
其他接口如ListableBeanFactory和org.springframework.beans.factory.config.ConfigurableBeanFactory可用于特定目的。
这个接口是由包含许多bean定义的对象实现的,每个bean定义由一个String名称唯一标识。根据bean定义,工厂将返回所包含对象的独立实例(Prototype设计模式)或单个共享实例(Singleton设计模式的高级替代方案,其中实例是工厂范围内的单例)。返回哪种类型的实例取决于bean工厂配置:API是相同的。从Spring 2.0开始,根据具体的应用程序上下文(例如:web环境中的“请求”和“会话”作用域)。
这种方式的关键在于 BeanFactory 是应用程序组件的注册中心,并集中化应用程序组件的配置(例如,单个对象不再需要读取属性文件)。详情请参阅“专家一对一J2EE设计与开发”的第4章和第11章,了解这种方法的好处。

请注意,通常最好依赖依赖注入(“推送”配置)通过 setter 或 构造函数 来配置应用程序对象,而不是使用任何形式的“拉”配置,如BeanFactory查找。
Spring的依赖注入功能,是使用这个BeanFactory接口及其子接口实现的。

通常, BeanFactory 将加载存储在配置源(如XML文档)中的bean定义,并使用org.springframework.beans包来配置bean。
但是,实现可以根据需要直接在Java代码中返回它创建的Java对象。对于如何存储定义没有任何限制:LDAP、RDBMS、XML、属性文件等。鼓励实现支持bean之间的引用(依赖注入)。

与ListableBeanFactory中的方法相反,如果这是一个HierarchicalBeanFactory,则该接口中的所有操作也将检查父工厂。如果在这个工厂实例中没有找到bean,将询问直接的父工厂。这个工厂实例中的bean应该覆盖任何父工厂中同名的bean。

BeanFactory 实现应该尽可能地支持标准的Bean生命周期接口。初始化方法的完整集合及其标准顺序为:

  • BeanNameAware's setBeanName
  • BeanClassLoaderAware's setBeanClassLoader
  • BeanFactoryAware's setBeanFactory
  • EnvironmentAware's setEnvironment
  • EmbeddedValueResolverAware's setEmbeddedValueResolver
  • ResourceLoaderAware's setResourceLoader (only applicable when running in an application context)
  • ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context)
  • MessageSourceAware's setMessageSource (only applicable when running in an application context)
  • ApplicationContextAware's setApplicationContext (only applicable when running in an application context)
  • ServletContextAware's setServletContext (only applicable when running in a web application context)
  • postProcessBeforeInitialization methods of BeanPostProcessors
  • InitializingBean's afterPropertiesSet
  • a custom init-method definition
  • postProcessAfterInitialization methods of BeanPostProcessors
  • On shutdown of a bean factory, the following lifecycle methods apply:
  • postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
  • DisposableBean's destroy
  • a custom destroy-method definition
  • BeanFactory 的接口定义

所属模块: spring-beans
SPRING 版本 : 5.2.15.RELEASE

package org.springframework.beans.factory;public interface BeanFactory {String FACTORY_BEAN_PREFIX = "&";Object getBean(String name) throws BeansException;<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);boolean containsBean(String name);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;Class<?> getType(String name) throws NoSuchBeanDefinitionException;Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;String[] getAliases(String name);
)

1.5 BeanFactory 中 Bean 的生命周期

Bean 生命周期

Bean 的作用域

1.6 BeanFactory 的实现类

  • BeanFactory 接口有多个实现类,其中最常用的是 XmlBeanFactoryDefaultListableBeanFactory

  • XmlBeanFactory是通过XML文件来配置Bean的实例化、配置和管理的,而 DefaultListableBeanFactory 则是通过Java代码 来配置Bean的实例化、配置和管理的。

节选

  • spring-beans 模块

  • spring-context 模块

  • spring-tx 模块

  • spring-web 模块

  • spring-boot 模块

  • spring-boot-test 模块

2 BeanFactory的使用

BeanFactory的创建

  • BeanFactory的创建有三种方式:XML配置方式、Java配置方式和注解配置方式。

1)XML配置方式

在使用XML配置方式时,需要在配置文件中定义Bean的实例化、配置和管理信息。

下面是一个简单的XML配置文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userService" class="com.example.UserService"><property name="userDao" ref="userDao"/></bean><bean id="userDao" class="com.example.UserDaoImpl"><property name="dataSource" ref="dataSource"/></bean><bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test"/><property name="username" value="root"/><property name="password" value="123456"/></bean></beans>

在上面的示例中,定义了3个Bean:userService、userDao和dataSource。其中,userService和userDao之间存在依赖关系,userService依赖于userDao,而userDao又依赖于dataSource。

2)Java配置方式

在使用Java配置方式时,需要编写Java代码来定义Bean的实例化、配置和管理信息。

下面是一个简单的Java配置类示例:

@Configuration
public class AppConfig {@Beanpublic UserService userService() {UserService userService = new UserService();userService.setUserDao(userDao());return userService;}@Beanpublic UserDao userDao() {UserDao userDao = new UserDaoImpl();userDao.setDataSource(dataSource());return userDao;}@Beanpublic DataSource dataSource() {BasicDataSource dataSource = new BasicDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/test");dataSource.setUsername("root");dataSource.setPassword("123456");return dataSource;}}

在上面的示例中,使用了@Configuration注解来标识该类是一个配置类,并使用@Bean注解来定义Bean的实例化、配置和管理信息。
在AppConfig类中,定义了3个Bean:userService、userDao和dataSource。其中,userService和userDao之间存在依赖关系,userService依赖于userDao,而userDao又依赖于dataSource。

3)注解配置方式

在使用注解配置方式时,需要在Bean类上添加相应的注解来标识该类是一个Bean,并进行相应的配置信息。

下面是一个简单的注解配置类示例:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {@Beanpublic DataSource dataSource() {BasicDataSource dataSource = new BasicDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/test");dataSource.setUsername("root");dataSource.setPassword("123456");return dataSource;}}

BeanFactory的配置

在BeanFactory的配置中,主要包括Bean的定义、依赖和属性等方面。

1)Bean的定义

在Bean的定义中,主要包括Bean的类型、ID和作用域等方面。

下面是一个简单的Bean定义示例:

<bean id="userService" class="com.example.UserService" scope="singleton"/>

在上面的示例中,定义了一个ID为userService,类型为com.example.UserService,作用域为singleton的Bean。

2)Bean的依赖

在Bean的依赖中,主要包括Bean之间的依赖关系和依赖注入方式等方面。

下面是一个简单的Bean依赖示例:

<bean id="userService" class="com.example.UserService"><property name="userDao" ref="userDao"/>
</bean><bean id="userDao" class="com.example.UserDaoImpl"><property name="dataSource" ref="dataSource"/>
</bean><bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test"/><property name="username" value="root"/><property name="password" value="123456"/>
</bean>

在上面的示例中,userService依赖于userDao,而userDao又依赖于dataSource。在userService中,使用了标签来注入userDao的实例,而在userDao中,同样使用了标签来注入dataSource的实例。

3)Bean的属性

在Bean的属性中,主要包括Bean的各种属性信息,如普通属性、集合属性和引用属性等。

下面是一个简单的Bean属性示例:

<bean id="userService" class="com.example.UserService"><property name="name" value="John"/><property name="age" value="30"/><property name="hobbies"><list><value>reading</value><value>writing</value><value>traveling</value></list></property><property name="userDao" ref="userDao"/>
</bean>

在上面的示例中,定义了一个userService的Bean,并设置了name、age、hobbies和userDao等属性。其中,name和age是普通属性,而hobbies是集合属性,它包含了三个值:reading、writing和traveling。userDao是引用属性,它依赖于另一个Bean实例。

3 BeanFactory的初始化

在BeanFactory的初始化中,主要包括BeanFactoryAware接口、InitializingBean接口和init-method属性等方面。

1)BeanFactoryAware接口

如果一个Bean实现了BeanFactoryAware接口,那么它将能够获取到当前Bean所在的BeanFactory实例。

下面是一个简单的BeanFactoryAware接口示例:

public class MyBean implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}}

在上面的示例中,MyBean实现了BeanFactoryAware接口,并重写了setBeanFactory()方法。该方法将传入的BeanFactory实例保存到了类成员变量beanFactory中。

2)InitializingBean接口

如果一个Bean实现了InitializingBean接口,那么它将能够在Bean实例化后、依赖注入后、属性设置后进行一些初始化操作。下面是一个简单的InitializingBean接口示例:

X 参考文献

  • 【Spring】BeanFactoryPostProcessor与BeanPostProcessor - CSDN //TODO
  • BeanFactoryPostProcessor - CSDN //TODO
    • BeanFactoryPostProcessor 的典型应用
  • springbean生命周期通俗一点_spring为啥是单例模式 - 腾讯云//TODO
    • Spring核心模块
    • BeanFactory、ApplicationContext和FactoryBean的区别
      • BeanFactory:BeanFactory 是 IoC 容器的顶级接口,是IoC容器的最基础实现,也是访问Spring容器的根接口,负责对bean的创建,访问等工作。实现类功能比较单一,BeanFactory接口实现的容器,特点是在每次获取对象时才会创建对象。
      • ApplicationContext:继承了BeanFactory接口,拥有BeanFactory的全部功能,并且扩展了很多高级特性,每次容器启动时就会创建所有的对象。Spring 框架 的 默认 IOC 容器。
    • Spring IOC容器启动加载流程
    • Bean 的生命周期

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

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

相关文章

软件工程结对作业(第二次之程序实现)

这个作业属于哪个课程 首页 - 软件工程2024 - 福州大学 - 班级博客 - 博客园这个作业要求在哪里 2024秋软件工程结对作业(第二次之程序实现)这个作业的目标 站在程序员的角度,给出这个产品的核心模块的编码的原型学号 102202130、042201401github项目地址1 linye2005/042201…

[Java/Spring/Nacos] Java 获取配置的方式

1、[本地] 使用 JDK 的 System.getProperty(key) ,获取 JVM 参数(VM Options)、系统属性参见 : 系统变量与JVM参数(VM Option)/环境变量/程序启动参数args - 博客园/千千寰宇2、[本地] 使用 JDK 的 System.getenv(key) ,获取 环境变量 3、[本地] 使用 JDK 的 main(String[] a…

IDEA git忽略文件设置

安装.ignore插件创建 .gitignore文件添加忽略文件【此文件可编辑,后期可手动向里面添加忽略文件】

NZOJ 模拟赛6

T1 叉叉现在有一个字符串,每个字母出现的次数均为偶数。接下来我们把第一次出现的字母a和第二次出现的a连一条线,第三次出现的和四次出现的字母a连一条线,第五次出现的和六次出现的字母a连一条线...对其他25个字母也做同样的操作。现在我们想知道有多少对连线交叉。交叉的定…

markdown的html优雅使用语法(2024/10/10guixiang原创)

一:图片部分 第一范式图 2 全字段排序<center><img style="border-radius: 0.3125em;box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.08);" width = "500" height = "400"src="https://static001.geek…

本地项目apollo的注册中心地址写的是ECS公网地址,但是项目启动后,发现它去拉取配置的时候变成了私网地址?

代码截图报错: 配置的注册中心是公网的地址,拉取配置的时候竟然变成私网了,就很离谱,后来通过网上查找资料,很多奇怪的解决方案都试了没有解决,后来发现了一篇文章,只需要在启动参数中配上:apollo.config-service 参数即可,配置截图如下:-Ddev=DEV 用于指定apollo中对…

[笔记]数据库内核杂谈系列笔记

知识点:数据库 --> 分布式数据库 --> 数据模型/数据湖 --> 其他数据库数据库的核心就在于一条query的执行流程 从这个开始,慢慢的拆解 如何将一个普通数据库转化为分布式数据库? 数据模型/数据库 -数据的组织形式 向量数据库1.一小时实现基本功能的数据库 数据库最…

面向法律领域的大模型微调与应用

来源:论文摘要 这篇论文探讨了如何通过微调大型语言模型来实现法律领域的智能化服务。作者指出,以往的智慧法律系统需要为每个特定的任务设计专门的算法或模型,面临着研发成本高、集成难度大的困难。而现在,通过微调大型语言模型,可以同时处理多种法律任务,从而提高法律从…