做过不少项目,用到最多的框架当属
Spring
了,但是至今都没有去整理过任何一篇关于
Spring
学习的文档:一是因为
Reference
比较详细,平时项目中基本上都能查到;二是因为有很多关于
Spring
的文章都写的相当好,觉得没有必要自己再写。今天我鼓起勇气整理一篇关于
BeanFactory
相关的文章,算是自己对
Spring Ioc
学习的一归纳,学习笔记嘛,否则,读过代码在记忆停留的时间总是那么有限。
BeanFactory
,作为
Spring
基础的
IoC
容器,从名字上看就是
Spring
的一个
Bean
工厂。如果单从工厂模式的角度思考,它就是用来“生产
Bean
”,然后提供给客户端。但是它到底是如何生产
Bean
的呢?生产
Bean
的“原料”获取、解析、以及
Bean
之间的依赖是如何完成的呢?这并不没有想象中的那么简单。直接来看最基础的
BeanFactory
类图吧:
在细看类图之前,先弄清
IOC
的流程。回想我们平时使用,大多数时候只是配置一下,就可以直接使用
Spring IOC
了,这其中必然需要读取配置、解析配置、生产
Bean
、将
Bean
注册到一个统一的地方提供客户端获取使用。暂不考虑配置的读取和解析,来看
spring
的接口功能的定义:
1.
首先是顶层的
BeanFactory
,从他定义的方法看,主要提供获
Bean
对象,判断给定的
Bean
对象是否被当前的
BeanFactory
加载过、是否是
Singleton/Prototype
、类型是否匹配,等等最最基本,也是客户端最最需要使用的功能
(
如果不是为了学习,客户端才不会关心你的
bean
是怎么来的,反正我只要能调用完成自己的功能就
ok
啦
)
。
2.
左边分支:也就是
ListableBeanfactory
,此接口继承了
BeanFactory
的同时,提供了列举
Bean
的功能,他能够列举当前
BeanFactory
加载的所有
Bean
:列举所有
Bean
的名字或者满足某种类型的
Bean
的名字,根据类型返回所有
Bean
对象
,
等。但是它无法获取上层
BeanFactory
加载的单例
Bean
。
3.
看中间分支:
HierachicalBeanFactory
和
ConfigurableBeanFactory
。
HierarchicalBeanFactory
比较简单,它主要是提供父
BeanFactory
的功能,通过它能够获取当前
BeanFactory
的父工厂(
PS:
若在
A
工厂启动并加载
Bean
之前,
B
工厂先启动并加载了,那
B
就是
A
的父工厂),这样就能让当前的
BeanFactory
加载父工厂加载的
Bean
了,弥补了
ListableBeanfactory
欠缺的功能。
ConfigurableBeanFactory
就是在
HierarchicalBeanFactory
的基础上增加了可配置的功能,包括注册别名、注册单例等,设置
Classloader
、是否缓存
Bean Metadata
、设置
TypeConverter
、
BeanPostProcessor
、配置
Bean
依赖等。
PS:ConfigurableBeanFactory
还继承了
SingletonBeanRegistry
接口主要是用来定义为用来共享的
bean
实例的注册表,通过它可以使得
BeanFactory
实现统一的方式暴露其单例
bean
管理。
4.
再看右边分支:该分支分两块――
首先是
AutowireCapableBeanFactory
,主要是提供自动
Bean
自动绑定
(
或者说自动装配
)
功能。例如根据自动装配策略
new
一个
bean
,为已有的
bean
装配属性依赖;还有创建
bean
之后的回调功能,为
bean
设置
name
、
bean factory
、
bean post processor
等;将
bean post processor
应用到
bean
的初始化,等等。 其次
SingletonBeanRegistry/DefaultSingletonBeanRegistry/FactoryBeanRegistrySupport
,
SingletonBeanRegistry
在前面已提到,
DefaultSingletonBeanRegistry
是它的默认实现类,它不仅支持
Singleton Bean
的注册,也支持
DisposableBean
的注册管理用来清理要丢弃的
bean
以及他们依赖的资源。如果去大概看一下代码的话,它主要维护了这些资源:
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>();
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>();
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(16);
/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation = Collections.synchronizedSet(new HashSet<String>());
/** List of suppressed Exceptions, available for associating related causes */
private Set<Exception> suppressedExceptions;
/** Flag that indicates whether we're currently within destroySingletons */
private boolean singletonsCurrentlyInDestruction = false;
/** Disposable bean instances: bean name --> disposable instance */
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
/** Map between containing bean names: bean name --> Set of bean names that the bean contains */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>();
/** Map between dependent bean names: bean name --> Set of dependent bean names */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>();
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>();
仔细读一下代码的话,可以看到
Spring
对这些容器的并发、同步的控制,这些都依赖与
Spring Core
以及
JDK
。
再说
FactoryBeanRegistrySupport
,主要是对
FactoryBean
的支持,
获取
FactoryBean
、
FactoryBean
的类型、获取
FactoryBean
曝露的目标对象等,而这些功能都是基于附接口对
Bean
的注册功能的。
FactoryBean
是
Spring
提供的一种扩展容器实例化
Bean
逻辑的接口,相信大家都用过类似
ProxyFactoryBean
、
TransactionProxyFactoryBean
、
LocalSessionFactoryBean
等,其实
Spring
和其框架整合的时候都会针对具体框架提供一个
***FactoryBean
。而
AbstractBeanFactory
既实现了
ConfigurableBeanFactory
,又继承了
FactoryBeanRegistrySupport
的功能。
最后
AbstractAutoWireCapableBeanFactory
,实现
AutowireCapableBeanFactory
接口的
Bean
装配功能,可参见其实现的
createBean/autowireBean/configureBean
方法,这里就包含了
bean
创建装配的逻辑。以最完整的
createBean
方法为例,来窥探下整个流程:概括的讲先根据
Class
类型包装成
RootBeanDefinition
并设置
SCOPE
,然后调用重载方法
createBean(beanClass.getName(), bd, null)
就完事了。
看这个重载方法:
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
AccessControlContext acc = AccessController.getContext();
return AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
// Make sure bean class is actually resolved at this point.
resolveBeanClass(mbd, beanName);
// Prepare method overrides.
try {
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}, acc);
}
参考代码,可将这个过程分为
4
步:
1)
解决
Bean Class
类型
主要用于保证
RootBeanDefinition
具有
Class
信息
2)
处理重写的方法
用来验证重写的方法是否合法,防止将来反射调用报错
3)
resolveBeforeInstantiation
在
Bean
实例
之前,
容器级别生命周期接口方法调用
InstantiationAwareBeanPostProcessor.
postProcessBeforeInstantiation(beanClass, beanName)
4)
调用
doCreateBean(beanName,rbd,args)
方法
这个方法就复杂一点了,首先它会包装
BeanWrapper
对象,将
bean
对象包装到一个
BeanWrapper
对象中,然后对
MergedBeanDefinitionPostProcessor
接口的
Bean
进行回调,接着会标识
Singleton Factory(
如果需要的话
)
,接下来是
populateBean
和
initializeBean
。最后根据
Bean
的
Scope
决定让
Spring
来继续管理其生命周期还是交给客户端来管理,
Spring
会为其注册
DisposableBean
,具体参见
registerDisposableBeanIfNecessary(beanName, bean, mbd)
。
populateBean
可以简单认为是设置
Bean
的
properties
,具体:
Ø
从
BeanDefinition
中获取
Properties’ Values
Ø
调用
InstantiationAwareBeanPostProcessor
.
postProcessAfterInstantiation
方法
Ø
Bean
自动装配处理
Ø
调用
InstantiationAwareBeanPostProcessor
.
postProcessProperty
Values
方法
Ø
依赖检查
(
如果需要的话
)
Ø
使
Properties Values
生效
initializeBean
方法在
Bean
的
properties
生效后执行,具体:
Ø
实现
BeanNameAware
的
bean
设置
beanName
Ø
实现
BeanClassLoaderAware
的
bean
设置
beanClassLoader
Ø
实现
BeanFactoryAware
的
bean
设置
beanFactory
Ø
调用
BeanPostProcessor
.
postProcess
BeforeInitialization
方法,我们在这一步可以对
Bean
对象进行修改
Ø
Invoke init method
,调用
afterPropertiesSet()
或指定的初始化方法
Ø
调用
BeanPostProcessor
.
postProcess
AfterInitialization
方法
到此,核心的
Bean
生产装配功能都在
AbstractAutowireCapableBeanFactory
实现了,下层的
DefaultListableBeanFactory
继承这些功能的同时再实现可配置的功能
from ConfigurableListableBeanFactory
。另外,它还实现了
BeanDefinitionRegistry
。做为
full
-
fledged
的
BeanFactory
,
DefaultListableBeanFactory
已经可以为客户端使用了,但是需要自己编程使用:
//测试Bean
public class Person {
String name;
Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return name + "@" + address.getName();
}
}
public class Address {
String name;
public Address(String name){
this.name = name;
}
}
//客户端
public class DefaultListableBeanFactoryTest {
public static void main(String[] args){
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
wireBeans(beanFactory);
//使用
Person p = (Person) beanFactory.getBean("newHier");
System.out.println(p.toString());
}
private static BeanFactory wireBeans(BeanDefinitionRegistry registry) {
RootBeanDefinition personBean = new RootBeanDefinition(Person.class);
RootBeanDefinition addressBean = new RootBeanDefinition(Address.class);
//将Bean注册到容器
registry.registerBeanDefinition("newHier", personBean);
registry.registerBeanDefinition("newHierAddress", addressBean);
//通过构造方法为addressBean注入属性
ConstructorArgumentValues argValues = new ConstructorArgumentValues();
argValues.addIndexedArgumentValue(0, "Shilong Road");
addressBean.setConstructorArgumentValues(argValues);
//通过setter为personBean注入属性
MutablePropertyValues propertiesValues = new MutablePropertyValues();
propertiesValues.addPropertyValue(new PropertyValue("name","Wilson"));
propertiesValues.addPropertyValue(new PropertyValue("address",addressBean));
personBean.setPropertyValues(propertiesValues);
//完成bean注册,返回BeanFactory
return (BeanFactory)registry;
}
}
执行客户端测试,输入Wilson@Shilong
Road
作为本文的结尾,简单说两句类图中最底层的XmlBeanFactory,其实就是方便我们用Xml文件来配置,这样就不用那么麻烦的使用DefaultListableBeanFactory编程了。我们可以看到XmlBeanFactory依赖于XmlBeanDefinitionReader,这个Reader就是用来读取并解析Xml配置文件的。
- 大小: 72.7 KB
分享到:
相关推荐
SpringIOC是Spring Framework中的核心组件之一,负责管理应用程序中的对象、依赖关系和生命周期。 在 Spring IOC 中,对象的创建和管理是通过 BeanFactory 或 ApplicationContext 实现的。BeanFactory 是 Spring ...
Spring IoC 加载流程讲解 在本节中,我们将对 Spring IoC 加载流程进行详细的讲解,并探讨 IoC 思想和依赖倒置原则的应用。 IoC 控制反转 IoC(Inversion of Control)是指在软件设计中,将对象实例的控制权从...
Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性之一,它允许开发者将对象的创建和管理交给Spring容器来处理,从而使代码更加松耦合,更易于测试和维护。下面将详细介绍Spring IOC的基本概念、...
Spring 是一个广泛应用的 Java 应用开发框架,其核心特性之一就是IOC,它极大地简化了软件组件之间的依赖管理。在本文中,我们将深入探讨 Spring IOC 的概念、工作原理以及如何在实际项目中应用。 首先,理解 IOC ...
- `BeanFactory` 是Spring IoC容器的顶层接口,代表了IoC容器的基础原则和能力。其不能被实例化,提供了一套IoC容器必须遵循的基本原则。 - `ApplicationContext` 是在 `BeanFactory` 的基础上,添加了更多功能的...
Spring IOC,即Spring控制反转,是Spring框架的核心特性之一。控制反转(Inversion of Control,简称IoC)是一种设计原则,用于减少代码间的耦合,提高系统模块化和代码的重用性。在Spring框架中,IOC具体体现在对...
在Java开发领域,Spring框架无疑是使用最为广泛的轻量级框架之一,其中的核心组件就是IOC(Inversion of Control)容器。本文将深入剖析Spring的IOC容器,理解其工作原理和重要功能,以帮助开发者更好地利用这一强大...
Spring的IoC容器是其核心特性之一,它通过BeanFactory和ApplicationContext两个主要接口来实现控制反转(Inversion of Control,IoC)的概念。BeanFactory作为基础的IoC容器,提供了全面的IoC服务,包括对象的注册、...
Spring IOC,即Inversion of Control(控制反转),是Spring框架的核心特性之一,它负责管理和装配应用程序中的对象。在传统的编程模式中,对象通常自行创建和管理它们所依赖的其他对象,这导致了代码间的高耦合。而...
Spring框架的核心功能之一便是依赖注入(Dependency Injection, DI),而这一功能主要通过IoC容器来实现。在Spring框架中,IoC容器负责管理应用对象的生命周期、配置和装配。简单来说,IoC容器就是一个工厂,它可以...
在本资源"手写spring ioc(三) 资源org.zip"中,我们主要关注的是如何实现一个简易版的Spring IOC(Inversion of Control)容器,它涵盖了ioc的基本功能,包括解决循环依赖、使用构造器注入以及自动注入等核心特性。...
Spring IOC,全称为Inversion of Control,中文常被称为“控制反转”,是Spring框架的核心特性之一。这个概念在软件设计中引入了一种新的依赖管理方式,它将对象的创建和管理权交给了容器,使得开发者可以更专注于...
`BeanFactory`接口和它的实现类如`DefaultListableBeanFactory`都在这个包中,它们是IOC容器的基础。 3. `org.springframework.core-3.0.6.RELEASE.jar`: 核心模块,提供了Spring框架的基础工具类和基本数据类型,...
Spring IoC提供了BeanFactory和ApplicationContext两种容器类型,其中BeanFactory是基础的IoC容器,而ApplicationContext则提供了更多高级功能,如资源加载、事件发布等。 Spring IoC的配置主要通过XML或注解的方式...
2. **创建BeanFactory实例**:接着,创建一个`DefaultListableBeanFactory`实例,它继承自`AbstractAutowireCapableBeanFactory`,是Spring IoC容器的核心实现之一。 ```java DefaultListableBeanFactory factory ...
Spring注解驱动开发第41讲——Spring IOC容器创建源码解析(一)之BeanFactory的创建以及预准备工作(合起来整个过程)
在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色与地位。对于Spring的使用者而言,IOC容器不仅是管理Bean(即应用中的对象实例)生命周期的...
### Spring IoC容器的核心概念与应用 #### 一、IoC基本定义 IoC(Inversion of Control,控制反转)是一种设计思想,在Spring框架中主要体现在这样一种方式:原本在程序代码中由开发者自己控制的对象的创建过程以及...