介绍
BeanFactory
首先来看来自官方文档的描述:
The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object.
我们来翻译一下:
beans和context是Spring Framework的IoC容器的基础。BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。
如何理解这段话:
IoC(Inversion of Control)是Spring Framework的核心设计思想:它将对象的创建、组装、管理交给容器(container),BeanFactory提供了访问IoC的接口,使得开发者可以更方便的使用Spring框架来实现控制和依赖注入。
引用Spring Framework API文档中的一段话:
The root interface for accessing a Spring bean container.
This is the basic client view of a bean container; further interfaces such as ListableBeanFactory and ConfigurableBeanFactory are available for specific purposes. This interface is implemented by objects that hold a number of bean definitions, each uniquely identified by a String name.
我们再来翻译一下:
BeanFactory
是访问Spring bean容器的根接口。
这是bean容器的基本客户端视图;诸如ListableBeanFactory
和ConfigurableBeanFactory
之类的接口可用于特定目的。
这个接口是由包含许多bean定义的对象实现的,每个bean定义由一个String名称唯一标识。
如何理解这段话呢?
- 在Spring中,Spring bean 容器负责管理和组织JavaBean对象,
BeanFactory
接口定义了访问这个容器的基本方法。 - BeanFactory提供了最基本的访问Bean的方法,而对于更高级的功能,如列举所有Bean、配置Bean工厂等,Spring提供了其他专门的接口,如
ListableBeanFactory
和ConfigurableBeanFactory
。这些接口扩展了BeanFactory
,提供了更多的功能和配置选项。 - 在Spring中,Bean的定义包括了Bean的类、依赖关系、配置信息等。
BeanFactory
接口的实现类是Spring容器,它持有多个Bean的定义,并且每个Bean都通过一个唯一的字符串名称进行标识。通过这个名称,客户端代码可以从容器中获取相应的Bean。
ApplicationContext
来自官方对Application的一段描述:
In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory.
这段话不难理解:
一句话来说,BeanFactory
为Spring框架提供了基础的方法和配置,ApplicationContext
增加了更多企业级的方法,ApplicationContext
是BeanFactory
的超集。
继承关系
通过继承关系可以看到ApplicationContext
是BeanFactory
的子接口,通过继承的特性可知:ApplicationContext
具有BeanFactory
的所有功能,并在其基础上进行扩展。
两者的区别
两者是如何加载、获取Bean的?
准备工作:
创建类MyBean
被注入的类:
/**
* Author: 公众号:种棵代码技术树
* Date: 2023/12/23
*/
public class MyBean {
private String message;
public MyBean() {
}
public MyBean(String message) {
System.out.println("MyBean被实例化了");
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void showMessage() {
System.out.println("Message: " + message);
}
}
在resource
目录下创建目录:META-INF
,新建文件:spring-config.xml
。
classpath:/META-INF/ 是一个常用的目录,特别是在Java项目中,用于存放元信息文件,如配置文件、资源文件等。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<bean id = "myBean" class="org.thinging.in.spring.ioc.overview.bean.MyBean">
<property name="message" value="Hello, Spring!" />
</bean>
</beans>
通过BeanFactory获取Bean
/**
* Author: 公众号:种棵代码技术树
* Date: 2023/12/23
*/
public class BeanFactoryExample {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-config.xml");
MyBean myBean = (MyBean) beanFactory.getBean("myBean");
myBean.showMessage();
}
}
输出结果:
通过ApplictaionContext获取Bean
/**
* Author: 公众号:种棵代码技术树
* Date: 2023/12/23
*/
public class ApplicationContextExample {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-config.xml");
MyBean myBean = (MyBean) applicationContext.getBean("myBean");
myBean.showMessage();
}
}
输出结果:
两者都是通过配置文件加载的类,输出相同的结果,那么他们是不是同一个对象呢?
/**
* Author: 公众号:种棵代码技术树
* Date: 2023/12/23
*/
public class ApplicationContextExample {
public static void main(String[] args) {
//使用ApplicationContext
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
MyBean applicationContextBean = (MyBean) applicationContext.getBean("myBean");
applicationContextBean.showMessage();
//使用BeanFactory
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
MyBean beanFactoryBean = (MyBean) beanFactory.getBean("myBean");
beanFactoryBean.showMessage();
//比较两者的引用
boolean flag = applicationContextBean == beanFactoryBean;
System.out.println("两者是否为同一个对象:" + flag);
}
}
以上说明两者的引用不是同一个对象。
官方文档中描述的区别
在Spring Framework官方文档中指出了ApplicationContext相较于BeanFactory增加了以下特性:
- Easier integration with Spring’s AOP features:
- 通过ApplicationContext可以更好的集成AOP。
- Message resource handling (for use in internationalization)
- 更好的处理国际化
- Event publication
- 支持事件机制,Spring的事件机制允许一个组件发布事件,而其他组件可以监听并响应这些事件。
- Application-layer specific contexts such as the WebApplicationContext for use in web applications.
- Spring的上下文(ApplicationContext)是一个IoC容器,用于管理和组织应用程序中的组件(Beans)。不同类型的应用程序可能需要不同的上下文。例如,对于Web应用程序,Spring提供了WebApplicationContext,它在ApplicationContext的基础上添加了一些特定于Web的功能,如处理Web相关的Bean(例如控制器)、处理Web请求等。
总结
在Spring框架中,由Spring IoC容器管理的构成应用程序骨架的对象被称为"beans"。一个bean是由Spring IoC容器实例化、组装和管理的对象。从另一个角度看,一个bean也只是应用程序中的众多对象之一。Beans以及它们之间的依赖关系都体现在容器所使用的配置元数据中。
- Bean: 由Spring IoC容器管理的对象,通过容器进行实例化、组装和生命周期管理。Beans的配置信息被反映在Spring IoC容器的配置元数据中。
- ApplicationContext: 是BeanFactory的超集,提供了更多的企业级功能。ApplicationContext是Spring IoC容器的一种,负责加载、实例化、配置和管理beans。
后续内容文章持续更新中…
近期发布。