SpringBean详解
文章目录
- 概述
- Spring获取Bean的流程
- 依赖注入
- bean的作用域
- Spring 中的 Bean 是线程安全的吗
- Spring如何处理线程并发问题
- bean 的自动装配和方式
- @Resource和@Autowired的区别
- bean的自动装配
- bean的生命周期
- BeanFactory
- BeanFactory 常用的实现类有哪些
- BeanFactory与FactoryBean的不同
- ApplicationContextAware常用的IOC容器
概述
Spring Bean 是 Spring 框架中的核心概念之一,它表示由 Spring 容器管理的对象。Spring Bean 可以是任何 Java 类的实例,包括简单的 JavaBean、业务逻辑对象、数据访问对象、甚至是整合了第三方库或框架的对象。以下是关于 Spring Bean 的详细解释:
- Bean 定义(Bean Definition):Spring Bean 通过 Bean 定义来描述。Bean 定义是一个配置元数据,它包含了创建和配置 Bean 的信息,包括 Bean 的类名、依赖关系、初始化方法、销毁方法等。
- Bean 的生命周期:Spring 容器负责管理 Bean 的生命周期,包括 Bean 的创建、初始化、使用和销毁等阶段。可以通过配置初始化方法和销毁方法来控制 Bean 的生命周期。
- 依赖注入(Dependency Injection):Spring 容器负责管理 Bean 之间的依赖关系,可以通过依赖注入将一个 Bean 注入到另一个 Bean 中。依赖注入可以通过构造函数、Setter 方法或字段注入的方式来实现。
- 作用域(Scope):Spring 提供了多种作用域来管理 Bean 的生命周期,包括单例(Singleton)、原型(Prototype)、会话(Session)、请求(Request)等。默认情况下,Bean 的作用域是单例。
- 初始化和销毁方法:可以通过配置初始化方法和销毁方法来控制 Bean 的初始化和销毁过程。初始化方法在 Bean 创建后立即执行,销毁方法在容器关闭时执行。
- Bean 的装配方式:Spring 提供了多种装配 Bean 的方式,包括 XML 配置、注解(Annotation)和 Java 配置(Java Config)等。可以根据实际需求选择合适的装配方式。
- Bean 的自动装配(Autowiring):Spring 提供了自动装配的功能,可以根据类型、名称等条件自动将 Bean 注入到目标 Bean 中,减少了手动配置的工作量。
- Bean 的后置处理器(BeanPostProcessor):Spring 允许开发者在 Bean 初始化前后执行自定义逻辑,可以通过 Bean 后置处理器来实现对 Bean 的定制化处理。
总的来说,Spring Bean 是 Spring 框架的核心组件之一,它通过依赖注入、作用域管理等功能,实现了松耦合、灵活性和可测试性,是 Spring 应用程序的基础构建块之一。
Spring获取Bean的流程
1、加载配置,可以是xml配置或者是配置类,Spring提供了统一的抽象接口BeanDefinitionReader,对于不同的配置有不同的实现类,xml配置是使用XmlBeanDefinitionReader,然后将Bean解析成BeanDefinition对象,然后注册到beanDefinitionMap中,key就是bean的id,value就是BeanDefinition对象,如果有别名的话,在map额外保存一个key是别名,value是id,获取Bean的时候会重定向一次
1、扫描 ----> 创建BeanDefinition对象 ———>放到beanDefinitionMap中
xml配置或者注解
BeanDefinition
实例化Bean
属性注入
初始化
Bean被调用
销毁
Spring中的bean的生命周期主要包含四个阶段:实例化Bean --> Bean属性填充 --> 初始化Bean -->销毁Bean
依赖注入
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配, 和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中 的形式定义
依赖注入
构造函数注入
setter 注入
接口注入
在 Spring Framework 中,仅使用构造函数和 setter 注入。
依赖注入是时下最流行的IOC实现方式,依赖注入分为接口注入(Interface Injection),Setter方
法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式。其中接口注入由于
在灵活性和易用性比较差,现在从Spring4开始已被废弃。
构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每
个参数代表一个对其他类的依赖。
Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之
后,调用该bean的setter方法,即实现了基于setter的依赖注入。
Spring基于xml注入bean的几种方式
- Set方法注入
- 构造器注入:
- 通过index设置参数的位置;
- 通过type设置参数类型;
- 静态工厂注入;
- 实例工厂;
将Bean注入到Spring的容器中的方式
● @Configuration + @Bean
● @ComponentScan + @Component
● @Import 配合接口进行导入
● 使用FactoryBean。
● 实现BeanDefinitionRegistryPostProcessor进行后置处理。
1、@Configuration + @Bean
2、@Component + @ComponentScan
3、@Import注解导入
3.1 Import直接导入类
3.2@Import + ImportSelector
3.3@Import + ImportBeanDefinitionRegistrar
3.4@Import + DeferredImportSelector
4、使用FactoryBean接口
5、使用 BeanDefinitionRegistryPostProcessor
SpringBean配置方式有哪些
1.基于 xml 配置
2.java api方式
3.注解的的方式
bean的作用域
Spring容器中的bean可以分为5个范围:
(1)singleton:默认,容器初始化时创建bean实例,在整个容器的生命周期内只创建这个bean,单例的,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。
(2)prototype:为每一个bean请求提供一个实例,翻译成原型,意味着每次从IOC容器去获取指定Bean的时候,都会返回一个新的实例对象。原型的, 容器初始化时不创建bean实例,而在每次请求时都创建一个新的bean实例,并返回
(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
(5)global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。
bean对象的作用范围(掌握) scope
- singleton: 单例 代表在SpringIOC容器中只有一个Bean实例 (默认的scope)
- prototype多例 每一次从Spring容器中获取时,都会返回一个新的实例
- request 用在web开发中,将bean对象request.setAttribute()存储到request域中
- session 用在web开发中,将bean对象session.setAttribute()存储到session域中
关于Bean生命周期:
Spring 根据 Bean 的作用域来选择管理方式。对于 singleton 作用域的 Bean,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁;而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。
验证了:对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。
Spring 只负责创建,所以它调用了初始而不会调用销毁方法,又同时验证了原型模式每次通过 Spring 容器获取 Bean 时,容器都会创建一个 Bean 实例,所以会调用两次初始化方法。
Spring 中的 Bean 是线程安全的吗
在 Spring 框架中,Bean 的线程安全性不是由 Spring 自身保证的,而是取决于 Bean 的实现方式。Spring 容器负责管理 Bean 的生命周期,包括创建、初始化、销毁等过程,但它并不会对 Bean 的线程安全性进行特殊处理。
Bean 的线程安全性取决于以下几个方面:
- Bean 的作用域(Scope):Spring 支持多种作用域,如单例(Singleton)、原型(Prototype)、请求(Request)和会话(Session)等。其中,单例作用域的 Bean 在整个 Spring 容器中只有一个实例,多个线程可能同时访问该实例,因此需要特别注意线程安全问题。对于原型作用域的 Bean,每次请求都会创建一个新的实例,因此不存在线程安全问题。
- Bean 的状态:无状态(Stateless)的 Bean 通常是线程安全的,因为它们不保存任何与特定请求相关的状态信息。而有状态(Stateful)的 Bean 可能需要在多线程环境下进行同步处理,以确保线程安全。
- 线程安全类库和同步机制:如果 Bean 依赖于线程安全类库(如 java.util.concurrent 包中的类)或者使用了同步机制(如 synchronized 关键字),那么这些 Bean 可能具有更好的线程安全性。
总之,要确保 Spring 中的 Bean 在多线程环境下的线程安全性,需要关注 Bean 的作用域、状态以及所使用的线程安全类库和同步机制。在实际开发中,如果 Bean 是有状态的且作用域为单例,建议使用同步机制来确保线程安全。如果可能的话,尽量将 Bean 设计为无状态的,以降低线程安全问题的风险。
不是,Spring框架中的单例bean不是线程安全的。
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。
实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全
的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,
最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于
new Bean()了,所以就可以保证线程安全了。
有状态就是有数据存储功能。 无状态就是不会保存数据。
Prototype的Bean是线程安全的,无状态的Singleton的Bean是线程安全的。有状态的Singleton的Bean是非线程安全的。
在Spring框架中,Bean的线程安全性取决于具体的Bean定义和作用域。
默认情况下,Spring中的Bean是单例模式的,也就是说容器中只有一个实例,多个线程共享该实例。在这种情况下,如果Bean没有状态并且不依赖于外部资源,那么它是线程安全的。例如,一个只提供读取操作而没有写入操作的工具类。
然而,如果Bean具有可变的状态或者依赖于外部资源(如数据库连接、文件等),那么它可能是线程不安全的。在这种情况下,你需要采取适当的措施来确保线程安全性,比如使用同步机制(synchronization)或者使用线程安全的数据结构。
此外,Spring还提供了其他作用域以支持多例模式和原型模式的Bean。如果将Bean定义为多例或原型作用域,那么每次请求Bean时都会创建一个新的实例,因此它们可以更好地支持并发环境。
总之,Spring中的Bean的线程安全性是由具体的实现和作用域决定的。对于有状态的Bean,你需要根据实际情况采取适当的线程安全措施来确保其正确性。
Spring如何处理线程并发问题
在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可
以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了
“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要
排队。而ThreadLocal采用了“空间换时间”的方式。
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。
因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提
供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal
bean 的自动装配和方式
无须在 Spring 配置文件中描述 javaBean 之间的依赖关系(如配置、)。IOC容器会自动建立 javabean 之间的关联关系。Spring 装配包括手动装配和自动装配,手动装配是有基于 xml 装配、构造方法、setter 方法等自动装配有五种自动装配的方式,可以用来指导 Spring 容器用自动装配方式来进行依赖注入 解释不同方式的自动装配五种自动装配的方式
可以用来指导 Spring 容器用自动装配方式来进行依赖注入。
1)no:默认的方式是不进行自动装配,通过显式设置 ref 属性来进行装配。
2)byName:通过参数名自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被设置成 byname,
之后容器试图匹配、装配和该 bean 的属性具有相同名字的 bean。
3)byType::通过参数类型自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被设置成 byType,之后容器试图匹配、装配和该 bean 的属性具有相同类型的 bean。如果有多个 bean 符合条件,则抛出错误。
4)constructor:这个方式类似于 byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类
型,将会抛出异常。
5)autodetect:首先尝试使用 constructor 来自动装配,如果无法工作,则使用 byType 方式
@Resource和@Autowired的区别
1.注解内部定义的参数不同
@Autowired只包含一个required参数,默认为true,表示开启自动注入
而@Resource 包含七个参数,其中最重要的两个是name和type。
2、装配方式的默认值不同
@Autowired默认按type自动装配,而@Resource默认按name自动装配。当然,@Resource注解可以自
定义选择,如果指定了name,则根据name自动装配,如果指定了type,则用type自动装配。
3、注解应用的范围不同
@Autowired能够用在构造方法、成员变量、方法参数以及注解上,而@Resource能用在类、成员变量和
方法参数上,这点从源码也能看得出来。
4.出处不同
@Autowired是Spring定义的注解,而@Resource是遵循JSR-250规范,定义在JDK中。所以
@Autowired只能在Spring框架下使用,而@Resource则可以与其他框架一起使用。
5.装载顺序不同
@Autowired默认先按byType进行匹配,如果发现找到多个bean,则又按照byName方式进行匹配,如
果还有多个,则报出异常。
@Resource 先按 byName 再按byType
在日常开发中,我建议使用@Autowired,有以下三个理由:
第1:@Autowired功能略强大。支持优先注入、可以配置允许bean不存在。
第2:若使用了Spring框架,使用其特有的注解个人感觉更好一点。
第3:有人会认为@Resource更加通用,因为它是个规范,其他框架也会支持。但我认为,目前后端都是在用Spring了,没有必要考虑其他框架。
byName和byType的区别
● byName的时候,需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
● byType的时候,需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
@Autowired(required=false)注入注意的问题
@Autowired(required=false):表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错。
bean的自动装配
- 在xml中显示的配置
- 在Java中显示配置
- 隐式的自动装配bean
bean的生命周期
1.实例化Bean对象:反射的方式生成对象
2.填充bean的属性:populateBean(),循环依赖的问题(三级缓存)
3.调用Aware接口相关的方法:invokeAwareMethod(完成BeanName,BeanFactory,BeanClassLoder对象的属性设置)
4.调用BeanPostProcessor中的前置处理方法:使用比较多的有(ApplicationContextPostProcessor,设置ApplicationContext,Environment,ResourceLoader,EmbeddValueResolver等对象)
5.调用initmethod方法:invokeInitmethod(),判断是否实现了initializingBean接口,如果有,调用afterPropertiesSet方法,没有就不调用
6.调用BeanPostProcess的后置处理方法:spring的aop就是在此处实现的,AbstractAutoProxyCreator
注册Destuction相关的回调接口:钩子函数
7.获取到完整的对象,可以通过getBean的方式来进行对象的获取
8.销毁流程: 1.判断是否实现了DispoableBean接口,2.调用destroyMethod方法
1.创建前准备阶段
这个阶段主要是在开始Bean加载之前,从Spring上下文和相关配置中解析并查找Bean有关的配置内容,
比如init-method
-容器在初始化bean时调用的方法、destory-method
,容器在销毁Bean时调用的方
法。以及,BeanFactoryPostProcessor这类的bean加载过程中的前置和后置处理。这些类或者配置其实是Spring提供给开发者,用来实现Bean加载过程中的扩展机制,在很多和Spring集成的中间件经常使用,比如Dubbo。
2.创建实例阶段
这个阶段主要是通过反射来创建Bean的实例对象,并且扫描和解析Bean声明的一些属性。
3、依赖注入阶段
在这个阶段,会检测被实例化的Bean是否存在其他依赖,如果存在其他依赖,1就需要对这些被依赖Bean进行
注入。比如通过读取@Autowired`、@Setter等依赖注入的配置。在这个阶段还会触发一些扩展的调用,比如常见的扩展类:BeanPostProcessors
(用来实现Bean初始化前后的回调)、InitializingBean类(这个类有一个afterPropertiesSet()方法,给属性赋值)、还BeanFactoryAware等等。
4.容器缓存阶
容器缓存阶段主要是把Bean保存到IoC容器中缓存起来,到了这个阶段,Bean就可以被开发者使用了。
这个阶段涉及到的操作,常见的有,init-method
这个属性配置的方法,会在这个阶段调用。在比如BeanPostProcessors方法中的后置处理器方法如:postProcessAfterInitialization,也是在这个阶段触
发的。
5.销毁实例阶段
这个阶段,是完成Spring应用上下文关闭时,将销毁Spring上下文中所有的Bean。
如果Bean实现了DisposableBean接口,或者配置了destory-method
属 性,将会在这个阶段被调用。
Spring 中的 bean 生命周期
Bean的生命周期是由容器来管理的。主要在创建和销毁两个时期。
spring bean 容器的生命周期流程如下:
1)Spring 容器根据配置中的 bean 定义中实例化 bean。
2)Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
3)如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来 调用 setBeanName()。
4)如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用setBeanFactory()。
5)如果存在与 bean 关联的任何 BeanPostProcessors,则调用 preProcessBeforeInitialization() 方法。
6)如果为 bean 指定了 init 方法( 的 init-method 属性),那么将调用它。
7)最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
8)如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
9)如果为 bean 指定了 destroy 方法( 的 destroy-method 属 性),那么将 调用它
BeanFactory
Spring里面的核心功能是IOC容器,所谓IOC容器呢,本质上就是一个Bean的容器或者是一个Bean的工厂。它能够根据xml里面声明的Bean配置进行bean的加载和初始化,然后BeanFactory来生产我们需要的各种各样的Bean。
BeanFactory是所有Spring Bean容器的顶级接口,它为Spring的容器定义了一套规范,并提供像getBean这样的方法从容器中获取指定的Bean实例。BeanFactory在产生Bean的同时,还提供了解决Bean之间的依赖注入的能力,也就是所谓的DI。
FactoryBean是一个工厂Bean,它是一个接口,主要的功能是动态生成某一个类型的Bean的实例,也就是说,我们可以自定义一个Bean并且加载到IOC容器里面。它里面有一个重要的方法叫getObject(),这个方法里面就是用来实现动态构建Bean的过程。
Spring Cloud里面的OpenFeign组件,客户端的代理类,就是使用了FactoryBean来实现的
BeanFactory 常用的实现类有哪些
Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离。常
用的 BeanFactory 实现有 DefaultListableBeanFactory 、 XmlBeanFactory 、 ApplicationContext 等。
XMLBeanFactory,最常用的就是 org.springframework.beans.factory.xml.XmlBeanFactory ,它根据 XML 文件中的定义加载 beans。该容器从 XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用。
ApplicationContext 的实现类有哪些
FileSystemXmlApplicationContext :此容器从一个 XML 文件中加载 beans 的定义,XML Bean 配置文件的全
路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个 XML 文件中加载 beans 的定义,这里,你需要正确设置
classpath 因为这个容器将在 classpath 里找 bean 配置。
WebXmlApplicationContext:此容器加载一个 XML 文件,此文件定义了一个 WEB 应用的所有 bean。
BeanFactory与FactoryBean的不同
1、BeanFactory和FactoryBean都是接口
2、BeanFactory就是Spring的Bean工厂,创建并保存了我们的Bean对象,
3、而FactoryBean是Spring提供的专门创建那些复杂对象的,复杂对象即不能直接使用new关键字创建的对象,比如说Connection对象,SqlSessionFactory对象,我们需要实现FactoryBean接口,主要是重写getObject()方法,写创建对象的代码,然后将这个实现类配置在配置文件或者使用配置类的形式,我们获取工厂后使用getBean(“id”)的方式获取的就是这个实现类为我们创建的复杂对象,如果想要获取这个实现类对象,在getBean()获取Bean时id前加入&即可
ApplicationContextAware常用的IOC容器
ApplicationContext是我们常用的IOC容器,而他的顶层接口便是BeanFactory,ApplicationContext对BeanFactory做了拓展,功能更加强大
2、ApplicationContextAware作用
在Spring/SpringMVC中,我们拿到IOC容器无非有三种方式,那就是使用ApplicationContext接口下的三个实现类:ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext(我的思维导图有对IOC核心容器的介绍:Spring知识点)。
SpringMVC中还好,虽然可以自动初始化容器,但是我们依旧可以通过那三个实现类获取ApplicationContext对象,但是在SpringBoot中,因为没有了ioc配置文件,全都成自动化的了,我们无法通过上述方式拿到ApplicationContext对象,但有时候遇到的需求是必须要通过Spring容器才能实现的,例如动态获取三方渠道的代理类,所以,简单地说,ApplicationContextAware接口是用来获取框架自动初始化的ioc容器对象的。
ApplicationContextAware如何使用
注解方式当下用的比较多,所以我就不提xml方式的了,写个类实现ApplicationContextAware接口,实现方法,再提供几个ioc容器常用方法,将这个类当工具类用,描述不如看代码:
package com.wangxs.springcloud.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class AppContextUtil implements ApplicationContextAware {// 定义静态ApplicationContextprivate static ApplicationContext applicationContext = null;/*** 重写接口的方法,该方法的参数为框架自动加载的IOC容器对象* 该方法在启动项目的时候会自动执行,前提是该类上有IOC相关注解,例如@Component* @param applicationContext ioc容器* @throws BeansException e*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// 将框架加载的ioc赋值给全局静态iocAppContextUtil.applicationContext = applicationContext;log.info("==================ApplicationContext加载成功==================");}// 获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}// 通过name获取 Bean.public static Object getBean(String name) {return getApplicationContext().getBean(name);}// 通过class获取Bean.public static <T> T getBean(Class<T> clazz) {return getApplicationContext().getBean(clazz);}// 通过name,以及Clazz返回指定的Beanpublic static <T> T getBean(String name, Class<T> clazz) {return getApplicationContext().getBean(name, clazz);}
}
SpringContextUtil.getBean(ConfigCache.class);
知识点拓展
Spring中ioc容器是在我们通过上述三个类拿到ApplicationContext对象时进行初始化的,属于手动初始化,而在SpringMvc中,我们不再需要手动初始化,项目启动即加载了IOC容器,本质上是利用了JavaWeb的监听技术。
ServletContextListener是对JavaWeb域对象ServletContext的监听,而ServletContext对象整个服务器仅一份且在服务器启动便加载,而SpringMvc也设定了监听ContextLoaderListener,这个类实现了ServletContextListener接口,如此一来,SpringMvc便能感知到ServletContext对象要创建了,服务器要启动了,此时该加载IOC容器了。
1、ApplicationContext是BeanFactory的子接口
2、 BeanFactory是工厂接口,负责创建Bean的实例,并保存这些单实例的bean在Map中
3、ApplicatonContext是容器的接口,比BeanFactory功能更加强大,更多的负责容器功能的实现,可以基于BeanFactory创建好的对象之上完成强大的容器,AOP DI都是ApplicatonContext接口下的这些类里,
BeanFactory是最底层的接口,ApplicatonContext是留给我们使用的ioc容器接口。
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
1.BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。 相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
BeanFacotry延迟加载,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext则在初始化自身是检验,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用 ApplicationContext。应用上下文则会在上下文启动后预载入所有的单实例Bean。通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。(Applicationcontext比 beanFactory 加入了一些更好使用的功能。而且 beanFactory 的许多功能需要通过编程实现而 Applicationcontext 可以通过配置实现。比如后处理 bean , Applicationcontext 直接配置在配置文件即可而 beanFactory 这要在代码中显示的写出来才可以被容器识别。 )
3.beanFactory主要是面对与 spring 框架的基础设施,面对 spring 自己。而 Applicationcontex 主要面对与 spring 使用的开发者。基本都会使用 Applicationcontex 并非 beanFactory 。
因此,在实际开发中,通常都选择使用 ApplicationContext,而只有在系统资源较少时,才考虑使用 BeanFactory。
除了提供BeanFactory所具有的功能外,还提 供了更完整的框架功能:
继承MessageSource,因此支持国际化
统一的资源文件访问方式
提供在监听器中注册bean的事件
同时加载多个配置文件
载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的 web层
BeanFactory和ApplicationContext区别
applicationcontext对BeanFactory实现额外增强
applicationcontext主动添加Bean(工厂)处理器 来完成扫包
applicationcontext主动添加bean处理器 ----依赖注入@Autowired
applicationcontext主动初始化单例对象
BeanFactory----bean定义信息、单例池
- BeanFactory是ApplicationContext的顶层接口
- BeanFactory是采用延迟加载策略.只有真正使用getBean时才会实例化Bean.适用于多例模式
- ApplicationContext配置文件加载时就会立即初始化Bean,适用于单例模式,实际开发时一般采用这种.
常用的三个实现类(熟悉) - ClassPathXmlApplicationContext:加载类路径下的配置文件,要求配置文件必须在类路径下(常用)
- FileSystemXmlApplicationContext:加载磁盘任意路径下的配置文件(必须有访问权限)
- AnnotationConfigApplicationContext:读取注解配置容器
BeanFactory基础类型的 IOC 容器,提供完成的 IOC 服务支持。如果没有特殊指定,默认采用延迟初始化策略。相对来说,容器启动初期速度较快,所需资源有限
BeanFactory是Spring里面最底层的接口,是Ioc的核心,定义了Ioc的基本功能,包含了各种Bean的定义、加载、实例化,依赖注入和生命周期管理;
ApplicationContext 是在 BeanFactory 的基础上构建,是相对比较高级的容器实现,除了 BeanFactory 的所有
支持外,ApplicationContext 还提供了事件发布、国际化支持等功能。ApplicationContext 管理的对象,在容器启动后默认全部初始化并且绑定完成。
ApplicationContext接口作为BeanFactory的子类,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能
①继承MessageSource,因此支持国际化
②资源文件访问,如URL和文件(ResourceLoader)
③载入多个(有继承关系)上下文(及同时加载多个配置文件),使得每一个上下文都专注于一个特定的层次
④提供在监听器中注册bean的事件;
相关文章:

SpringBean详解
文章目录 概述Spring获取Bean的流程依赖注入bean的作用域Spring 中的 Bean 是线程安全的吗Spring如何处理线程并发问题bean 的自动装配和方式Resource和Autowired的区别bean的自动装配bean的生命周期BeanFactoryBeanFactory 常用的实现类有哪些BeanFactory与FactoryBean的不同A…...

hive获取这周五到下周四的区间,周一到周日的区间
-- 获取每个日期所在周期的开始和结束时间 SELECTcreated_date AS date_in_period,CASEWHEN date_format(created_date, u) < 5 THEN date_sub(created_date, cast(date_format(created_date, u) AS INT) 2)ELSE date_sub(created_date, cast(date_format(created_date, u)…...

Iterable与Iterator
Iterator public interface Iterator<E> {} terator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。Iterator提供的API接口如下: forEachRemaining(Consumer<? super E> action):为每个剩余元素执行给…...

免费Premiere模板,几何图形元素动画视频幻灯片模板素材下载
Premiere Pro模板,几何图形元素动画视频幻灯片模板 ,组织良好,易于自定义。包括PDF教程。 项目特点: 使用Adobe Premiere Pro 2021及以上版本。 19201080全高清。 不需要插件。 包括帮助视频。 免费下载:https://prmu…...

数据结构与算法学习笔记九---循环队列的表示和实现(C++)
目录 前言 1.为什么要使用循环队列 2.队列的顺序存储方式的实现 1.定义 2.队列初始化 3.销毁 4.清空队列 5.队列是否为空 6.队列长度 7.队头 8.入队 9.出队 10.遍历队列 11.完整代码 3.参考资料 前言 这篇文章介绍循环队列的表示和用法。 1.为什么要使用循环队…...

Mysql获取当前时间
1、今天开始时间和结束时间 SELECT DATE_FORMAT(NOW(),’%Y-%m-%d 00:00:00’) AS ‘今天开始’; SELECT DATE_FORMAT(NOW(),’%Y-%m-%d 23:59:59’) AS ‘今天结束’;2、昨天的开始时间和结束时间 SELECT DATE_FORMAT( DATE_SUB(CURDATE(), INTERVAL 1 DAY), ‘%Y-%m-%d 00:…...

计算机服务器中了locked勒索病毒怎么解决,locked勒索病毒解密恢复工具
在网络技术飞速发展的时代,通过网络开展各项工作业务成为众多企业的首选,网络也为企业的生产运营提供了极大便利,大大提升了企业办公效率,但是利用网络避免不了网络威胁的存在,数据安全问题一直是企业关心的主要话题。…...

基于springboot实现的在线动漫信息平台
开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven…...

C# Winform+Halcon结合标准视觉工具
介绍 winform与halcon结合标准化工具实例 软件架构 软件架构说明 基于NET6 WINFORMHALCON 实现标准化视觉检测工具 集成相机通讯 集成PLC通讯 TCP等常见通讯 支持常见halcon算子 图形采集blob分析高精度匹配颜色提取找几何体二维码提取OCR识别等等 。。。 安装教程 …...

英语单词量测试
网址:https://preply.com/en/learn/english/test-your-vocab 测试结果: 细节:英语母语者有20000-35000个单词的词汇量,8岁孩子的词汇量在8000个左右。而不是我们教育系统里说的,6000个单词足够用了。足够用࿰…...

三、安装node_exporter
目录 一、简介 二、下载安装 一、简介 Exporter是Prometheus的指标数据收集组件。它负责从目标Jobs收集数据,并把收集到的数据转换为Prometheus支持的时序数据格式。 和传统的指标数据收集组件不同的是,他只负责收集,并不向Server端发送数据…...

kafka基础知识
kafka架构 producer -> kafka cluster(broker>topic>partition) -> consumer -> zookeeper kafka压测 kafka-producer-perf-test.sh kafka-consumer-perf-test.sh kafka日志保存位置及消息保存时间 /tpdata/client/Kafka/kafka/config/server.properties log.…...

华为昇腾310B1平台视频解码失败[ERROR] Send frame to vdec failed, errorno:507018
目录 1 [ERROR] Send frame to vdec failed, errorno:507018 2 bug解决尝试1 3 bug解决尝试2 4 最终解决方法 参考文献: 1 [ERROR] Send frame to vdec failed, errorno:507018 某项目中的代码运行报错 [ERROR] Send frame to vdec failed, errorno:507018 Ac…...

Flutter 中的 SwitchListTile 小部件:全面指南
Flutter 中的 SwitchListTile 小部件:全面指南 在Flutter的Material组件库中,SwitchListTile是一个包含开关(Switch)的列表项,非常适合用来创建带有标题、副标题以及开关的列表项,常用于设置界面ÿ…...

详细分析Vue3中的defineExpose(附Demo)
目录 前言1. 基本知识2. Demo3. 实战 前言 其基本知识可参考官网:Vue3中的defineExpose 1. 基本知识 defineExpose 是 Vue 3 的 Composition API 中一个新的实用函数,用于在 <script setup> 语法下显式暴露组件的公共属性和方法 这在处理子组件…...

合合信息:TextIn文档解析技术与高精度文本向量化模型再加速
文章目录 前言现有大模型文档解析问题表格无法解析无法按照阅读顺序解析文档编码错误 诉求文档解析技术技术难点技术架构关键技术回根溯源 文本向量化模型结语 前言 随着人工智能技术的持续演进,大语言模型在我们日常生活中正逐渐占据举足轻重的地位。大模型语言通…...

Git与Gitlab
第1章Git概述 Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。 代码托管中心,记录每个版本的代码,从项目创建到现在使用的代码,中间所有的修改都有记录。 1. 何为版本控制 版本控制是…...

MySQL数据库从入门到精通(下)
对表做了修改之后,记得点击对应图标按钮重新执行一下。 1.创建角色表 数据库一开始就要设计好,轻易不要改动。一个账号下可能有多个角色,所以我们单独再创建另一个表role用来存储所有的角色信息。其中idrole表示角色id,name表示名…...

从融媒到智媒,小程序框架可助力传媒企业在AI实践下的服务变现
过去5年,媒体行业一直都在进行着信息化建设向融媒体平台建设的转变。一些融媒体的建设演变总结如下: 新闻终端的端侧内容矩阵建设,如App新闻端,社交平台上的官方媒体等 新闻本地生活双旗舰客户端,兼顾主流媒体核心宣传…...

MES系统在电线电缆行业生产上的应用
MES系统在线缆行业的应用可以带来多重价值,包括提高生产效率、降低生产成本、提高产品质量、优化库存管理、改善生产环境和提高企业竞争力等方面。因此,在电线电缆行业中广泛应用MES系统可以提高企业的经济效益和社会效益,推动企业发展和行业…...

怎么把图片上的字去掉
将图片上的字去掉通常需要使用图像编辑软件或在线工具。以下是一些常用的方法和步骤: 使用Adobe Photoshop: 打开Photoshop,导入需要编辑的图片。 选择“橡皮擦工具”或“克隆图章工具”。 如果使用“橡皮擦工具”,调整橡皮擦的…...

BFS和DFS优先搜索算法
1. BFS与DFS 1.1 BFS DFS即Depth First Search,深度优先搜索。它是一种图遍历算法,它从一个起始点开始,逐层扩展搜索范围,直到找到目标节点为止。 这种算法通常用于解决“最短路径”问题,比如在迷宫中找到从起点到终…...

python将两张图片对齐
目录 需要对齐的照片如下: 源码: 结果: 需要对齐的照片如下: 源码: import cv2 import numpy as np from matplotlib import pyplot as plt# 读取两张图片 imgA cv2.imread(./out/out/3.png) imgB cv2.imread(./…...

Linux修炼之路之初识操作系统+基础指令(1)
目录 引言 一:对操作系统(OS)的简单了解 1.操作系统(OS) 是什么 2.操作系统好坏的衡量标准 3.操作系统存在的重要性 4.理解所有在计算机上的操作 二:Linux与windows操作的特点区别 三:基础指令 1.ls 指令 1.使用 2.常用选项 2.…...

Flink中基于Chandy-Lamport算法的分布式快照实现详解
Apache Flink利用了一种基于Chandy-Lamport分布式快照算法的变体——异步屏障快照(Asynchronous Barrier Snapshotting, ABS)来实现其强大的容错机制。Chandy-Lamport算法最初由K.M. Chandy和Leslie Lamport于1985年提出,是一种用于分布式系统…...

软件3班20240513
java.util.PropertyResourceBundle4554617c package com.yanyu;import java.sql.*; import java.util.ResourceBundle;public class JDBCTest01 {public static void main(String[] args) throws SQLException { // 获取属性配置文件ResourceBundle bundle Res…...

【小程序】怎么优化小程序的性能
优化小程序的性能是提高用户体验和确保应用顺畅运行的关键。以下是一些优化小程序性能的方法: 1. 代码优化2. 图片优化3. 网络请求优化4. 页面渲染优化5. 分包加载6. 使用性能分析工具7. 后端优化8. 用户体验优化 1. 代码优化 精简代码:删除不必要的代码…...

告别信用卡绑定烦恼:探索这个全功能的Azure语音替代品,包含AI视频制作!(微软Azure语音替代方案)
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 语音合成的替代方案📝 功能特色📝 使用步骤示例⚓️ 相关链接 ⚓️📖 介绍 📖 虽然微软Azure语音服务为个人用户提供了充足的免费语音合成额度,但其注册过程中的信用卡绑定要求、繁琐的API配置步骤却…...

酷开科技依托酷开系统“硬件+内容”产业布局,抢占全球机遇!
2024年3月26日,创维集团发布了2023年年度业绩报告,去年全年实现了总营业额690.31亿元较上一年的534.91亿元整体营业额增长了29.1%。然而,值得注意的是,2023年度,创维集团智能家电业务的营收306.37亿元,较上…...

从离线到实时:无锡锡商银行基于 Apache Doris 的数据仓库演进实践
作者:武基鹏,无锡锡商银行 大数据技术经理 编辑整理:SelectDB 技术团队 导读:为实现数据资产的价值转化以及全面数字化、智能化的风险管理,无锡锡商银行大数据平台经历从 Hive 离线数据仓库到 Apache Doris 实时数据仓…...