Spring(一) IOC核心类
Spring(二) Resource定位与载入
Spring(三) BeanDefinition解析与注册
Spring(四) 自定义标签解析
Spring(五) 其他初始化步骤
Spring(六) bean的加载01
Spring(七) bean的加载02
Spring(八) SpringBean的生命周期
Spring(九) IOC时序图
Spring(十) AOP 01
Spring(十一) AOP 02
Spring(十二) spring事务
bean的加载
Spring什么时候实例化bean,首先要分2种情况:
- 如果使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化
- 如果使用ApplicationContext作为Spring Bean的工厂类,则又分为以下几种情况:
- 如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取
- 如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
- 如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
getBean主动调用
// AbstractApplicationContext
public Object getBean(String name) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(name);
}
// AbstractBeanFactory
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
预实例化(依赖注入)
public void refresh() throws BeansException, IllegalStateException {
...
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
...
}
1 . 完成当前上下文bean factory的初始化,初始化所有剩下的单例bean(非懒加载)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 设置自定义的类型转化器ConversionService
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 如果之前没有注册过的bean后置处理器,则注册一个默认的值注入解析器,例如PropertyPlaceholderConfigurer,处理注解修饰的属性值
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 设置自定义AOP相关的类LoadTimeWeaverAware
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 清除临时的ClassLoader
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 允许缓存所有beanDefinition信息,冻结配置不期望未来更改
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 开始初始化所有剩余单例bean(非懒加载)
beanFactory.preInstantiateSingletons();
}
2 . 准备初始化单例beans
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 获取缓存的所有beanDefinitionNames,
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 依次遍历初始化
for (String beanName : beanNames) {
// 这个方法会常常看到,Bean定义公共的抽象类是AbstractBeanDefinition
// 普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
// 这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作
// 如果指定BeanName是子Bean的话,同时合并父类的相关属性
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象,单例,非懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是否是FactoryBean的实现
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
// 是否立即加载
boolean isEagerInit;
// 是否是SmartFactoryBean的实现,主要用于框架内部使用与Spring相关
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// ---> 调用AbstractBeanFactory的doGetBean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 循环所有可应用的bean调用初始化后置回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
// 是否是SmartInitializingSingleton的实现
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
doGetBean方法
最终都会进入AbstractBeanFactory的doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly)
方法,返回指定bean的实例
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// a. 获取对应的beanName,剥离指定名称中对容器的相关依赖,如果指定的是别名,将别名转换为规范的Bean名称
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// b. 从缓存中或singletonFactories中的ObjectFactory中获取
Object sharedInstance = getSingleton(beanName);
// 检查是否已有对应的实例
// 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖
// spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
// 也就是将ObjectFactory加入到缓存中,一旦下一个bean创建时候需要依赖上一个bean则直接使用ObjectFactory
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// b-2. 返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身,而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// c. 只有在单例的情况下才会尝试解决循环依赖,原型模式下,如果存在A中有B属性,B中有A属性,
// 那么当依赖注入的时候,就会产生当A还未创建完的时候因为对B的创建再次返回创建A,造成循环依赖,也就是下面的情况、
// 这时候isPrototypeCurrentlyInCreation(beanName)为true,报出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// d. 如果beanDefinitionMap中,也就是在所有已加载的类中不包括beanName则尝试从parentBeanFactory中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 解析指定Bean名称的原始名称 Not found -> check parent.
String nameToLookup = originalBeanName(name);
// AbstractBeanFactory子类,调用本方法doGetBean
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// 递归到BeanFactory中查找getBean
else if (args != null) {
// Delegation to parent with explicit args.
// 委派父级容器根据指定名称和显式的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
// 委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 如果不是仅仅做类型检查,创建bean需要打上正在创建标记
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// e. 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话,同时合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// f. Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
// 若存在依赖则需要递归实例化依赖的bean
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 缓存依赖调用
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// g. 实例化依赖的bean后,可以实例化mbd本身了
// Create bean instance.
// singleton单例模式创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// prototype原型模式创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance. 每次都会创建一个新的对象
Object prototypeInstance = null;
try {
// 回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
beforePrototypeCreation(beanName);
// 创建指定Bean对象实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 指定的scope上实例化bean
// 根据Bean定义资源中配置的生命周期范围,选择实例化Bean的合适方法,
// 这种在Web应用程序中比较常用,如:request、session、application等生命周期
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// ObjectFactory中的方法与prototype一样
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
// 获取给定Bean的实例对象
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// h. 检查需要的类型是否符合bean的实际模型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
a.转换对应beanName
传入的name可能是别名,也可能是FactoryBean,所以需要进行一系列的解析
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
// BeanFactoryUtils
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
String beanName = name;
// 去除FactoryBean的修饰符&
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
return beanName;
}
// SimpleAliasRegistry
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
// 取得alias别名所表示的最终beanName
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
b.尝试从缓存中加载单例
单例在Spring的同一个容器内只会被创建一次,后续获取bean会到单例缓存singletonObjects中尝试获取,如果获取不到,再从earlySingletonObjects里获取,如果还是获取不到,再尝试从singletonFactories中获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject方法来创建bean,并放到earlySingletonObjects中去,且从singletonFactories中删掉这个ObjectFacotry
// DefaultSingletonBeanRegistry
// Cache of singleton objects: bean name --> bean instance
// 一级缓存:用于保存beanName与创建bean实例之间的关系
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// Cache of singleton factories: bean name --> ObjectFactory
// 三级缓存:用于保存beanName与创建bean的工厂之间的关系
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// Cache of early singleton objects: bean name --> bean instance
// 二级缓存:用于保存beanName与创建bean实例之间的关系,与singletonObjects不同之处在于
// 当一个单例bean放到这里后,那么当bean还在创建的过程中,就可以通过getBean获取到了,其目的是来检测循环引用
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// Set of registered singletons, containing the bean names in registration order
// 保存当前所有已注册的bean
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 查看是否存在实例
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 锁定singletonObjects全局变量进行处理
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果此bean正在加载则不处理,否则进入判断
if (singletonObject == null && allowEarlyReference) {
// 当某些方法需要提前初始化的时候,会调用addSingletonFactory方法将对应的objectFactory初始化策略存储在singletonFactories
// 做到提前曝光自己,虽然没有初始化完全,但是能被依赖拿到
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用预先设定的getObject()方法
singletonObject = singletonFactory.getObject();
// 记录在缓存中,earlySingletonObjects与singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
b-2.bean实例化
如果从缓存中获取了bean的原始状态,则需要对bean进行实例化。因为缓存中记录的只是bean的最原始状态,并不一定是最后需要得到的bean。比如工厂bean就需要得到factory-method方法返回的bean,下一篇对此进行详细解析
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 从FactoryBean中获取bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
d.检测parentBeanFactory
如果缓存没有数据就去父工厂去加载。但是如果parentBeanFactory为空,则不会进入。另外!containsBeanDefinition(beanName)
检测如果当前加载的XML配置文件中不包含beanName所对应的的配置,就只能到parentBeanFactory尝试了,然后再递归调用getBean方法
public BeanFactory getParentBeanFactory() {
return this.parentBeanFactory;
}
// DefaultListableBeanFactory
public boolean containsBeanDefinition(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return this.beanDefinitionMap.containsKey(beanName);
}
e.转换为RootBeanDefinition
因为从XML配置文件读取到的bean信息是存储在GernericBeanDefinition中的,但所有的Bean后续处理都是针对RootBeanDefinition的,所以这里需要一个转换,转换的同时如果父类bean不为空的话,则会一并合并父类的属性
/** Map from bean name to merged RootBeanDefinition */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
f.寻找依赖
因为bean的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖其他的bean,那么这个时候就必须先加载依赖的bean,所以再Spring的加载顺序中,在初始化某一个bean的时候首先会初始化这个bean的所有依赖
public String[] getDependsOn() {
return this.dependsOn; // depends-on属性
}
g.针对不同scope创建bean
Spring中存在不同的scope,默认是singleton单例,还有比如prototype、request等。这里会根据不同的配置进行不同的初始化策略。这里是实例化bean的最重要步骤,下一篇对此进行详细解析
h.类型转换
一般创建bean后返回就结束了,但是如果传入的参数requiredType不是空,并且类型不同。就需要将返回的bean转换为requiredType所指定的类型T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType)
。这里用到了TypeConverter,有各种转换器,也可以通过自定义转换器来满足需求