Spring IOC

Spring IOC

@Autowired 和 @Resource 区别

  • @Resource 是 JSR-250 规范提供的,@Resource 默认按照 byName 自动注入。
  • @Autowired 按照 byType 自动注入。

Bean 加载过程

转化 BeanName

我们解析完 XML 配置后创建的 Map,使用的是 beanName 作为 key:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    // key: bean name
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
}

在获取 Bean 的时候,alias bean namefactory bean name 都要转化为 bean name

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		final String beanName = transformedBeanName(name);
    }

    protected String transformedBeanName(String name) {
		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
	}
}

FACTORY_BEAN_PREFIX 的值是 &,当以 & 开头的时候,代表这是一个 FactoryBean,就要逐次去掉 &,以便找到真正的 name;否则,直接使用 name。此时的这个 name 可能只是一个别名,因此随后会用这个 name 当做 key,去 aliasMap 中去寻找最终的 bean name

其中 aliasMap 的内容是 Spring 在解析阶段,将 alias namebean name 的映射关系注册到了 SimpleAliasRegistry 中。

public static String transformedBeanName(String name) {
    if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
        return name;
    }
    return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
        do {
            beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
        }
        while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
        return beanName;
    });
}

public String canonicalName(String name) {
    String canonicalName = name;

    String resolvedName;
    do {
        resolvedName = (String)this.aliasMap.get(canonicalName);
        if (resolvedName != null) {
            canonicalName = resolvedName;
        }
    } while(resolvedName != null);

    return canonicalName;
}

合并 RootBeanDefinition

某个 Bean 只有和父 Bean 的属性信息合并成 RootBeanDefinition 才是完整的,否则只是 GenericBeanDefinition

每个 GenericBeanDefinition 内部都声明了一个父 Bean 的 parentName 属性,这个属性不为空的时候,就是为了找到父类,递归合并父类信息。

public class GenericBeanDefinition extends AbstractBeanDefinition {

	@Nullable
	private String parentName;

}

合并为 RootBeanDefinition 的过程,是在 doGetBean 的时候进行的:

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
}

处理循环依赖

构造器循环依赖,本质上是无法解决的。比如我们准调用 A 的构造器,发现依赖 B,于是去调用 B 的构造器进行实例化,发现又依赖 C,于是调用 C 的构造器去初始化,结果依赖 A,整个形成一个死结,导致 A 无法创建。

如果是 Setter 循环依赖,Spring 框架只支持单例下的 Setter 循环依赖。Spring 通过对还在创建过程中的单例,缓存并提前暴露该单例,使得其他实例可以引用该依赖。

单例模式用了一个 Set 来记录正在创建中的 beanName,使用了另外一个 Map 来提前暴露未完全创建好的 Object。

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    // Cache of early singleton objects: bean name to bean instance.
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}
}

创建实例

创建实例有 4 种策略:

  • Supplier 创建
  • 工厂方法模式创建:找到 FactoryBean 进行实例化
  • 有参构造器创建
  • 无参构造器创建
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
}

最终的实例化逻辑:

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
        // ...
        // ctor.newInstance(args)
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // Must generate CGLIB subclass.
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

注入属性

// AbstractAutowireCapableBeanFactory.java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // Add property values based on autowire by name if applicable.
    if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
        autowireByName(beanName, mbd, bw, newPvs);
    }

    // Add property values based on autowire by type if applicable.
    if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
        autowireByType(beanName, mbd, bw, newPvs);
    }

    applyPropertyValues(beanName, mbd, bw, pvs);
}

初始化

见下一节

类型转换

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && !requiredType.isInstance(bean)) {
        T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
        return convertedBean;
    }

    return (T) bean;
}

Bean 生命周期 (初始化)

BeanNameAware.setBeanName
          ⬇️
BeanClassLoaderAware.setBeanClassLoader
          ⬇️
BeanFactoryAware.setBeanFactory
          ⬇️
EnvironmentAware.setEnvironment
          ⬇️
EmbeddedValueResolverAware.setEmbeddedValueResolver
          ⬇️
ResourceLoaderAware.setResourceLoader (only applicable when running in an application context)
          ⬇️
ApplicationEventPublisherAware.setApplicationEventPublisher (only applicable when running in an application context)
          ⬇️
MessageSourceAware.setMessageSource (only applicable when running in an application context)
          ⬇️
ApplicationContextAware.setApplicationContext (only applicable when running in an application context)
          ⬇️
ServletContextAware.setServletContext (only applicable when running in a web application context)
          ⬇️
postProcessBeforeInitialization methods of BeanPostProcessors
          ⬇️
InitializingBean.afterPropertiesSet
          ⬇️
a custom init-method definition
          ⬇️
postProcessAfterInitialization methods of BeanPostProcessors

BeanFactory 销毁时候的生命周期:

postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
          ⬇️
DisposableBean.destroy
          ⬇️
a custom destroy-method definition

invokeAwareMethods

Bean 初始化整个生命周期的方法如下:

// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    // 第一部分
    invokeAwareMethods(beanName, bean);

    // 第二部分
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    // 第三部分
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }

    // 第四部分
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
}

第一部分,Bean 初始化生命周期的前三个方法

// AbstractAutowireCapableBeanFactory.java
private void invokeAwareMethods(final String beanName, final Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

BeanPostProcessorsBeforeInitialization

第二部分,开始调用 Bean 的后处理器

// AbstractAutowireCapableBeanFactory.java
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

而其中之一就有 ApplicationContextAwareProcessor,这里面调用了 Bean 初始化生命周期的中间 6 个方法:

@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    // ...
    invokeAwareInterfaces(bean);
    // ...
    return bean;
}

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }
}

invokeInitMethods

第三部分调用初始化函数:

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {

    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        ((InitializingBean) bean).afterPropertiesSet();
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        invokeCustomInitMethod(beanName, bean, mbd);
    }
}

BeanPostProcessorsAfterInitialization

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

destroy

Bean 的销毁的周期主要在如下函数中:

// DisposableBeanAdapter.java
@Override
public void destroy() {
    // 第一部分
    for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
        processor.postProcessBeforeDestruction(this.bean, this.beanName);
    }

    // 第二部分
    if (this.invokeDisposableBean) {
        ((DisposableBean) this.bean).destroy();
    }

    // 第三部分
    invokeCustomDestroyMethod(methodToCall);
}

注册 Bean 到 IoC 容器

BeanFactory

BeanFactory 的实现类,存储了 Bean 的定义,根据 BeanFactory 配置的不同,可以返回单例 BeanPrototype Bean。它为 IOC 容器的实现提供了模板、框架、雏形、规范,BeanFactory 是 IOC 容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

public interface BeanFactory {

    Object getBean(String name) throws BeansException;

}

BeanFactory 的实现,需要尽可能地去支持 Bean 的生命周期

FactoryBean

FactoryBeanBean 结尾,表示它是一个 Bean。某个 Bean 如果实现了这个接口,那么根据该 Bean 的 ID 从 BeanFactory 中获取的实际上是 FactoryBeangetObject() 返回的对象,而不是 FactoryBean 本身,如果要获取 FactoryBean 对象,请在 id 前面加一个 & 符号来获取。

public interface FactoryBean<T> {

    @Nullable
	T getObject() throws Exception;

}

Mybatis 用法示例

Mybatis 的 Mapper 是从 SqlSession 中去获取的,因此它实现了 FactoryBean

public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {

    private Class<T> mapperInterface;

    public MapperFactoryBean(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    @Override
    public T getObject() throws Exception {
        return getSqlSession().getMapper(this.mapperInterface);
    }

}

对于 SqlSessionFactoryBean 也是一样的:

public class SqlSessionFactoryBean
    implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
    @Override
    public SqlSessionFactory getObject() throws Exception {
        if (this.sqlSessionFactory == null) {
            afterPropertiesSet();
        }

        return this.sqlSessionFactory;
    }
}

参考