08 Spring DI源码解析
目录
BeanFactoryUtils.isFactoryDereference
当IoC容器I完成Bean资源的定位、载入和解析注册之后,IoC容器已经包含Bean定义的相关数据,但是此时容器中还没有Bean的实例化对象以及Bean之间依赖关系,这部分依赖关系的初始化主要依赖DI(依赖注入)来完成。
依赖注入会在以下两种场景下发生:
-
用户第一次调用getBean()方法时,IoC容器触发以来注册;
-
当用户配置了lazy-init=false时,即容器在解析注册Bean定义时进行预实例化,触发依赖注册。
让我们开始DI的旅程吧,这篇篇幅比较长,整理了好几天,阅读起来可能需要花点时间。
PS.万万没想到的是,在IoC、AOP、DI和MVC中,DI是最复杂的一块。感觉逻辑跳来跳去的,很容易不知道看到哪里去了。所以要抓住主干,不要被细节缠住,如果迷失了就看看手写源码部分DI的核心在哪里。
Pt1 DI核心类库
Pt1.1 FactoryBean
Spring中,BeanFactory和FactoryBean是很容易混淆的两个概念。
-
BeanFactory:Bean的工厂类,也可以理解为Spring的IoC容器。他的作用是管理Bean,包括Bean的定位、加载、实例化、配置、依赖注入等。
-
FactoryBean:工厂Bean,他只是一个Bean,作用是产生其他Bean实例。他提供一个工厂方法,用于产生真正有用的Bean。
FactoryBean接口使你可以自定义一个复杂的逻辑来生成Bean。它本质是一个Bean,但这个Bean不是用来注入到其它地方像Service、Dao一样使用的,它是用来生成其它Bean使用的。实现了这个接口后,Spring在容器初始化时,把实现这个接口的Bean取出来,使用接口的getObject()方法来生成我们要想的Bean。
直白点说,使用FactoryBean可以在Bean对象的实例化过程中添加自定义逻辑(通过BeanPostProcessor来实现功能增强),从而可以增强创建的对象。
// 工厂Bean,用于产生其他Bean对象。
public interface FactoryBean<T> {
// 区分FactoryBean对象本身和其管理的Bean对象
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
// 获取当前FactoryBean管理的Bean对象实例
@Nullable
T getObject() throws Exception;
// 获取当前FactoryBean管理的Bean类型
@Nullable
Class<?> getObjectType();
// 当前FactoryBean创建的Bean对象是否是单例模式。
// 如果是则整个容器中只有一个实例对象,每次请求都返回同一个实例对象。
default boolean isSingleton() {
return true;
}
}
AbstractFactoryBean实现了FactoryBean的核心逻辑:
public abstract class AbstractFactoryBean<T>
implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
// 管理的Bean是否单例
private boolean singleton = true;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
// IoC容器
@Nullable
private BeanFactory beanFactory;
// 管理的Bean是否完成初始化,指完整的对象创建流程。
private boolean initialized = false;
// 成熟的Bean实例对象
@Nullable
private T singletonInstance;
// 不成熟的Bean实例对象(未完成所有对象创建流程)
@Nullable
private T earlySingletonInstance;
// 管理的Bean是否单例
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
@Override
public boolean isSingleton() {
return this.singleton;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void setBeanFactory(@Nullable BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Nullable
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
/**
* Obtain a bean type converter from the BeanFactory that this bean
* runs in. This is typically a fresh instance for each call,
* since TypeConverters are usually <i>not</i> thread-safe.
* <p>Falls back to a SimpleTypeConverter when not running in a BeanFactory.
* @see ConfigurableBeanFactory#getTypeConverter()
* @see org.springframework.beans.SimpleTypeConverter
*/
protected TypeConverter getBeanTypeConverter() {
BeanFactory beanFactory = getBeanFactory();
if (beanFactory instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) beanFactory).getTypeConverter();
}
else {
return new SimpleTypeConverter();
}
}
// 执行FactoryBean初始化操作
@Override
public void afterPropertiesSet() throws Exception {
// 如果是单例,则先创建对象(恶汉模式)
if (isSingleton()) {
this.initialized = true;
this.singletonInstance = createInstance();
this.earlySingletonInstance = null;
}
}
// 获取当前FactoryBean管理的Bean对象实例
@Override
public final T getObject() throws Exception {
// 如果是单例,判断是否已经有创建过的对象
if (isSingleton()) {
return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
}
else {
return createInstance();
}
}
// 创建一个早期Bean实例对象,解决循环依赖问题。
@SuppressWarnings("unchecked")
private T getEarlySingletonInstance() throws Exception {
Class<?>[] ifcs = getEarlySingletonInterfaces();
if (ifcs == null) {
throw new FactoryBeanNotInitializedException(
getClass().getName() + " does not support circular references");
}
if (this.earlySingletonInstance == null) {
this.earlySingletonInstance = (T) Proxy.newProxyInstance(
this.beanClassLoader, ifcs, new EarlySingletonInvocationHandler());
}
return this.earlySingletonInstance;
}
// 获取单例对象的Bean实例
@Nullable
private T getSingletonInstance() throws IllegalStateException {
Assert.state(this.initialized, "Singleton instance not initialized yet");
return this.singletonInstance;
}
// 销毁Bean
@Override
public void destroy() throws Exception {
if (isSingleton()) {
destroyInstance(this.singletonInstance);
}
}
// 获取当前FactoryBean管理的Bean类型
@Override
@Nullable
public abstract Class<?> getObjectType();
// 创建Bean实例,子类实现逻辑。
protected abstract T createInstance() throws Exception;
/**
* Return an array of interfaces that a singleton object exposed by this
* FactoryBean is supposed to implement, for use with an 'early singleton
* proxy' that will be exposed in case of a circular reference.
* <p>The default implementation returns this FactoryBean's object type,
* provided that it is an interface, or {@code null} otherwise. The latter
* indicates that early singleton access is not supported by this FactoryBean.
* This will lead to a FactoryBeanNotInitializedException getting thrown.
* @return the interfaces to use for 'early singletons',
* or {@code null} to indicate a FactoryBeanNotInitializedException
* @see org.springframework.beans.factory.FactoryBeanNotInitializedException
*/
@Nullable
protected Class<?>[] getEarlySingletonInterfaces() {
Class<?> type = getObjectType();
return (type != null && type.isInterface() ? new Class<?>[] {type} : null);
}
// 销毁Bean
protected void destroyInstance(@Nullable T instance) throws Exception {
}
// 动态代理处理
private class EarlySingletonInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (ReflectionUtils.isEqualsMethod(method)) {
// Only consider equal when proxies are identical.
return (proxy == args[0]);
}
else if (ReflectionUtils.isHashCodeMethod(method)) {
// Use hashCode of reference proxy.
return System.identityHashCode(proxy);
}
else if (!initialized && ReflectionUtils.isToStringMethod(method)) {
return "Early singleton proxy for interfaces " +
ObjectUtils.nullSafeToString(getEarlySingletonInterfaces());
}
try {
return method.invoke(getSingletonInstance(), args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
ObjectFactoryCreatingFactoryBean是实现类,不过生成的是ObjectFactory类型的Bean,也是用来管理Bean的工厂类。
// 生成一个管理指定BeanName的FactoryBean(ObjectFactory)
public class ObjectFactoryCreatingFactoryBean extends AbstractFactoryBean<ObjectFactory<Object>> {
// ObjectFactory管理的Bean
@Nullable
private String targetBeanName;
// 最终管理的目标Bean
public void setTargetBeanName(String targetBeanName) {
this.targetBeanName = targetBeanName;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
super.afterPropertiesSet();
}
@Override
public Class<?> getObjectType() {
return ObjectFactory.class;
}
// 创建当前FactoryBean管理的Bean实例
@Override
protected ObjectFactory<Object> createInstance() {
BeanFactory beanFactory = getBeanFactory();
Assert.state(beanFactory != null, "No BeanFactory available");
Assert.state(this.targetBeanName != null, "No target bean name specified");
return new TargetBeanObjectFactory(beanFactory, this.targetBeanName);
}
// 内部类,增加序列化能力
@SuppressWarnings("serial")
private static class TargetBeanObjectFactory implements ObjectFactory<Object>, Serializable {
// IoC容器
private final BeanFactory beanFactory;
// 目标Bean名称
private final String targetBeanName;
public TargetBeanObjectFactory(BeanFactory beanFactory, String targetBeanName) {
this.beanFactory = beanFactory;
this.targetBeanName = targetBeanName;
}
@Override
public Object getObject() throws BeansException {
return this.beanFactory.getBean(this.targetBeanName);
}
}
}
Pt1.2 ObjectFactory
ObjectFactory也是一个工厂Bean,用来生成Object对象。这个接口一般被用来,包装一个Factory,通过这个Factory来管理一个Prototype类型的Bean。
这个接口和FactoryBean有点像,但FactoryBean的实现是被当做一个SPI(Service Provider Interface)实例来使用。ObjectFactory的实现一般被用来注入到其它Bean中,作为API来使用。就像ObjectFactoryCreatingFactoryBean的例子,它的返回值就是一个ObjectFactory,这个ObjectFactory被注入到了Bean中,在Bean通过这个接口的实例,来取得我们想要的Bean。
Service Provider Interface:SPI是一种API,这种API被第三方来实现或扩展。它可以被用来扩展框架或实现组件替换功能
总的来说,FactoryBean和ObjectFactory都是用来取得Bean,但使用的方法和地方不同,FactoryBean被配置好后,Spring调用getObject()方法来取得Bean,ObjectFactory配置好后,在Bean里面可以取得ObjectFactory实例,需要我们手动来调用getObject()来取得Bean。
@FunctionalInterface
public interface ObjectFactory<T> {
// 获取管理的Bean实例
T getObject() throws BeansException;
}
Pt1.3 BeanWrapper
BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。
// BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。
public interface BeanWrapper extends ConfigurablePropertyAccessor {
// 指定数组和集合自动增长的限制。
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
// 返回数组和集合自动增长的限制。
int getAutoGrowCollectionLimit();
// 获取包装的Bean对象
Object getWrappedInstance();
// 获取包装的Bean的class
Class<?> getWrappedClass();
// 获取所有属性的属性描述符
PropertyDescriptor[] getPropertyDescriptors();
// 获取指定属性的属性描述符
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
}
Pt1.4 BeanDefinition
BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。
常用BeanDefinition类如下:
-
BeanDefinition:顶层接口,描述了一个 Bean 实例,实例包含属性值、构造方法参数值以及更多实现信息。该 BeanDefinition 只是是一个最小的接口,主要目的是允许修改属性值和其他 Bean 元数据。
-
AbstractBeanDefinition:是 BeanDefinition 的子抽象类,也是其他 BeanDefinition 类型的基类,其实现了接口中定义的一系列操作方法,并定义了一系列的常量属性,这些常量会直接影响到 Spring 实例化 Bean 时的策略。
AbstractBeanDefinition 直接实现类:RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition。
-
RootBeanDefinition:继承了 AbstractBeanDefinition,这是一个具体 BeanDefinition,有实际作用。一个 RootBeanDefinition 表示它是一个可合并的 BeanDefinition,会在 BeanFactory 解析的时候合成一个完整的 BeanDefinition。比如这个 Bean 继承了某个类或继承了某个 Bean,亦或是实现了某个接口。
-
ChildBeanDefinition:该类继承自 AbstractBeanDefinition。其相当于一个子类,不可以单独存在,必须依赖一个父 BeanDetintion(RootBeanDefinition类型),构造 ChildBeanDefinition 时,通过构造方法传入父 BeanDetintion 的名称或通过 setParentName 设置父名称。它可以从父类继承方法参数、属性值,并可以重写父类的方法,同时也可以增加新的属性或者方法。若重新定义 init 方法,destroy 方法或者静态工厂方法,ChildBeanDefinition 会重写父类的设置。
-
GenericBeanDefinition:是 Spring 2.5 以后新引入的 BeanDefinition,是 ChildBeanDefinition 更好的替代者,它同样可以通过 setParentName 方法设置父 BeanDefinition。
BeanDefinition的定义还是很复杂的,但是在IoC和DI的逻辑中,大量涉及到BeanDefinition的操作,如果不了解BeanDefinition的话,有些地方理解起来非常困难。先看看BeanDefinition的相关类的源码定义。
-
BeanDefinition
// Bean的定义用BeanDefinition对象来表示,包含以下元数据:
// 全限定类名, 通常是Bean的实际实现类;
// Bean行为配置元素,它们说明Bean在容器中的行为(作用域、生命周期回调等等);
// Bean执行工作所需要的的其他Bean的引用,这些Bean也称为协作者或依赖项;
// 其他配置信息,例如,管理连接池的bean中,限制池的大小或者使用的连接的数量。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 单例、原型标识符
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// 标识 Bean 的类别,分别对应 用户定义的 Bean、来源于配置文件的 Bean、Spring 内部的 Bean
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
// 设置、返回 Bean 的父类名称
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
// 设置、返回 Bean 的 className
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
// 设置、返回 Bean 的作用域
void setScope(@Nullable String scope);
@Nullable
String getScope();
// 设置、返回 Bean 是否懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 设置、返回当前 Bean 所依赖的其它 Bean 名称。
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
// 设置、返回 Bean 是否可以自动注入。只对 @Autowired 注解有效
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
// 设置、返回当前 Bean 是否为主要候选 Bean 。
// 当同一个接口有多个实现类时,通过该属性来配置某个 Bean 为主候选 Bean。
void setPrimary(boolean primary);
boolean isPrimary();
// 定义创建该Bean对象的工厂类
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
// 创建该Bean对象的工厂方法
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
// 返回此bean的构造函数参数值。
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
// 获取普通属性集合
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
// 定义初始化Bean的方法名称
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
// 定义销毁Bean的方法名称
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
// 设置和获取这个bean的应用
void setRole(int role);
int getRole();
// 设置和获取对bean定义的可读描述。
void setDescription(@Nullable String description);
@Nullable
String getDescription();
// Read-only attributes
// Bean类型
ResolvableType getResolvableType();
// 是否为单例、原型和抽象类
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
// 返回该bean定义来自的资源的描述(用于在出现错误时显示上下文)
@Nullable
String getResourceDescription();
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
-
AbstractBeanDefinition
// AbstractBeanDefinition 是 BeanDefinition 的直接实现类,从类名也知道,它是一个抽象的 BeanDefinition,还不够具体。
// AbstractBeanDefinition 已经对 BeanDefinition 方法有了基本实现逻辑,增加了许多新的属性(默认属性)。
// AbstractBeanDefinition 直接实现类:RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition。
@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
/** 常量的定义 */
// 默认的SCOPE,默认是单例
public static final String SCOPE_DEFAULT = "";
// 不进行自动装配
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
// 根据Bean的名字进行自动装配,即autowired属性的值为byname
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
// 根据Bean的类型进行自动装配,调用setter函数装配属性,即autowired属性的值为byType
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
// 自动装配构造函数的形参,完成对应属性的自动装配,即autowired属性的值为byConstructor
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
// 通过Bean的class推断适当的自动装配策略(autowired=autodetect),如果Bean定义有有参构造函数,则通过自动装配构造函数形参,
// 完成对应属性的自动装配(AUTOWIRE_CONSTRUCTOR),否则,使用setter函数(AUTOWIRE_BY_TYPE)
@Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
// 不进行依赖检查
public static final int DEPENDENCY_CHECK_NONE = 0;
// 如果依赖类型为对象引用,则需要检查
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
// 对简单属性的依赖进行检查
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
// 对所有属性的依赖进行检查
public static final int DEPENDENCY_CHECK_ALL = 3;
// 若Bean未指定销毁方法,容器应该尝试推断Bean的销毁方法的名字,目前来说,推断的销毁方法的名字一般为close或是shutdown
// (即未指定Bean的销毁方法,但是内部定义了名为close或是shutdown的方法,则容器推断其为销毁方法)
public static final String INFER_METHOD = "(inferred)";
/** 定义的变量 */
// Bean的class对象或是类的全限定名
@Nullable
private volatile Object beanClass;
// 默认的scope是单例
@Nullable
private String scope = SCOPE_DEFAULT;
// 默认不为抽象类
private boolean abstractFlag = false;
// 是否是懒加载
@Nullable
private Boolean lazyInit;
// 默认不进行自动装配
private int autowireMode = AUTOWIRE_NO;
// 默认不进行依赖检查
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
// 当前Bean依赖的Bean对象。是指使用@DependsOn标注,用来控制Bean初始化状态的注解,当前Bean必须等到所有dependsOn的Bean全部初始化之后才能进行初始化。
// 这里只会存放<bean/>标签的depends-on属性或是@DependsOn注解的值
@Nullable
private String[] dependsOn;
// 是自动装配的候选者,意味着可以自动装配到其他Bean的某个属性
private boolean autowireCandidate = true;
// 当某个Bean的某个属性自动装配有多个候选者(包括自己)时,是否优先注入,即@Primary注解
private boolean primary = false;
// Bean的限定符
private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
// 用于初始化Bean的回调函数,一旦指定,这个方法会覆盖工厂方法以及构造函数中的元数据
@Nullable
private Supplier<?> instanceSupplier;
// 是否允许访问非public方法和属性,应用于构造函数、工厂方法、init、destroy方法的解析
private boolean nonPublicAccessAllowed = true;
// 指定解析构造函数的模式,是宽松还是严格
private boolean lenientConstructorResolution = true;
// 工厂类名
@Nullable
private String factoryBeanName;
// 工厂方法名
@Nullable
private String factoryMethodName;
// 存储构造函数形参的值
@Nullable
private ConstructorArgumentValues constructorArgumentValues;
// Bean属性的名称以及对应的值,这里不会存放构造函数相关的参数值,只会存放通过setter注入的依赖。
@Nullable
private MutablePropertyValues propertyValues;
// 存储被IOC容器覆盖的方法的相关信息(例如replace-method属性指定的函数)
private MethodOverrides methodOverrides = new MethodOverrides();
// init函数的名字
@Nullable
private String initMethodName;
// destory函数的名字
@Nullable
private String destroyMethodName;
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
// 是否是合成类(不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,这些辅助类不是应用自定义的,这个就是合成类)
private boolean synthetic = false;
// Bean的角色,默认为用户自定义Bean
private int role = BeanDefinition.ROLE_APPLICATION;
// Bean的描述
@Nullable
private String description;
@Nullable
private Resource resource;
// 构造器
protected AbstractBeanDefinition() {
this(null, null);
}
protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) {
this.constructorArgumentValues = cargs;
this.propertyValues = pvs;
}
protected AbstractBeanDefinition(BeanDefinition original) {
setParentName(original.getParentName());
setBeanClassName(original.getBeanClassName());
setScope(original.getScope());
setAbstract(original.isAbstract());
setFactoryBeanName(original.getFactoryBeanName());
setFactoryMethodName(original.getFactoryMethodName());
setRole(original.getRole());
setSource(original.getSource());
copyAttributesFrom(original);
if (original instanceof AbstractBeanDefinition) {
AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original;
if (originalAbd.hasBeanClass()) {
setBeanClass(originalAbd.getBeanClass());
}
if (originalAbd.hasConstructorArgumentValues()) {
setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
}
if (originalAbd.hasPropertyValues()) {
setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
}
if (originalAbd.hasMethodOverrides()) {
setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
}
Boolean lazyInit = originalAbd.getLazyInit();
if (lazyInit != null) {
setLazyInit(lazyInit);
}
setAutowireMode(originalAbd.getAutowireMode());
setDependencyCheck(originalAbd.getDependencyCheck());
setDependsOn(originalAbd.getDependsOn());
setAutowireCandidate(originalAbd.isAutowireCandidate());
setPrimary(originalAbd.isPrimary());
copyQualifiersFrom(originalAbd);
setInstanceSupplier(originalAbd.getInstanceSupplier());
setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
setInitMethodName(originalAbd.getInitMethodName());
setEnforceInitMethod(originalAbd.isEnforceInitMethod());
setDestroyMethodName(originalAbd.getDestroyMethodName());
setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
setSynthetic(originalAbd.isSynthetic());
setResource(originalAbd.getResource());
}
else {
setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
setLazyInit(original.isLazyInit());
setResourceDescription(original.getResourceDescription());
}
}
// 使用传参other覆盖bean定义
public void overrideFrom(BeanDefinition other) {
if (StringUtils.hasLength(other.getBeanClassName())) {
setBeanClassName(other.getBeanClassName());
}
if (StringUtils.hasLength(other.getScope())) {
setScope(other.getScope());
}
setAbstract(other.isAbstract());
if (StringUtils.hasLength(other.getFactoryBeanName())) {
setFactoryBeanName(other.getFactoryBeanName());
}
if (StringUtils.hasLength(other.getFactoryMethodName())) {
setFactoryMethodName(other.getFactoryMethodName());
}
setRole(other.getRole());
setSource(other.getSource());
copyAttributesFrom(other);
if (other instanceof AbstractBeanDefinition) {
AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
if (otherAbd.hasBeanClass()) {
setBeanClass(otherAbd.getBeanClass());
}
if (otherAbd.hasConstructorArgumentValues()) {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
}
if (otherAbd.hasPropertyValues()) {
getPropertyValues().addPropertyValues(other.getPropertyValues());
}
if (otherAbd.hasMethodOverrides()) {
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
}
Boolean lazyInit = otherAbd.getLazyInit();
if (lazyInit != null) {
setLazyInit(lazyInit);
}
setAutowireMode(otherAbd.getAutowireMode());
setDependencyCheck(otherAbd.getDependencyCheck());
setDependsOn(otherAbd.getDependsOn());
setAutowireCandidate(otherAbd.isAutowireCandidate());
setPrimary(otherAbd.isPrimary());
copyQualifiersFrom(otherAbd);
setInstanceSupplier(otherAbd.getInstanceSupplier());
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
if (otherAbd.getInitMethodName() != null) {
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if (otherAbd.getDestroyMethodName() != null) {
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
setSynthetic(otherAbd.isSynthetic());
setResource(otherAbd.getResource());
}
else {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
getPropertyValues().addPropertyValues(other.getPropertyValues());
setLazyInit(other.isLazyInit());
setResourceDescription(other.getResourceDescription());
}
}
// 使用默认值
public void applyDefaults(BeanDefinitionDefaults defaults) {
Boolean lazyInit = defaults.getLazyInit();
if (lazyInit != null) {
setLazyInit(lazyInit);
}
setAutowireMode(defaults.getAutowireMode());
setDependencyCheck(defaults.getDependencyCheck());
setInitMethodName(defaults.getInitMethodName());
setEnforceInitMethod(false);
setDestroyMethodName(defaults.getDestroyMethodName());
setEnforceDestroyMethod(false);
}
// Setter & Getter
@Override
public void setBeanClassName(@Nullable String beanClassName) {
this.beanClass = beanClassName;
}
@Override
@Nullable
public String getBeanClassName() {
Object beanClassObject = this.beanClass;
if (beanClassObject instanceof Class) {
return ((Class<?>) beanClassObject).getName();
}
else {
return (String) beanClassObject;
}
}
public void setBeanClass(@Nullable Class<?> beanClass) {
this.beanClass = beanClass;
}
public Class<?> getBeanClass() throws IllegalStateException {
Object beanClassObject = this.beanClass;
if (beanClassObject == null) {
throw new IllegalStateException("No bean class specified on bean definition");
}
if (!(beanClassObject instanceof Class)) {
throw new IllegalStateException(
"Bean class name [" + beanClassObject + "] has not been resolved into an actual Class");
}
return (Class<?>) beanClassObject;
}
// 返回此定义是否指定bean类
public boolean hasBeanClass() {
return (this.beanClass instanceof Class);
}
// 返回包装好的bean的类
@Nullable
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
String className = getBeanClassName();
if (className == null) {
return null;
}
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
}
// 返回
@Override
public ResolvableType getResolvableType() {
return (hasBeanClass() ? ResolvableType.forClass(getBeanClass()) : ResolvableType.NONE);
}
// Scope的setter&getter
@Override
public void setScope(@Nullable String scope) {
this.scope = scope;
}
@Override
@Nullable
public String getScope() {
return this.scope;
}
// 判断是否单例Bean
@Override
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
}
// 判断是否原型Bean
@Override
public boolean isPrototype() {
return SCOPE_PROTOTYPE.equals(this.scope);
}
// abstractFlag的setter & getter
public void setAbstract(boolean abstractFlag) {
this.abstractFlag = abstractFlag;
}
@Override
public boolean isAbstract() {
return this.abstractFlag;
}
// 是否延迟加载setter & getter
@Override
public void setLazyInit(boolean lazyInit) {
this.lazyInit = lazyInit;
}
@Override
public boolean isLazyInit() {
return (this.lazyInit != null && this.lazyInit.booleanValue());
}
@Nullable
public Boolean getLazyInit() {
return this.lazyInit;
}
// autowireMode的setter & getter
public void setAutowireMode(int autowireMode) {
this.autowireMode = autowireMode;
}
public int getAutowireMode() {
return this.autowireMode;
}
// 获取自动注入的模式
public int getResolvedAutowireMode() {
if (this.autowireMode == AUTOWIRE_AUTODETECT) {
// Work out whether to apply setter autowiring or constructor autowiring.
// If it has a no-arg constructor it's deemed to be setter autowiring,
// otherwise we'll try constructor autowiring.
Constructor<?>[] constructors = getBeanClass().getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterCount() == 0) {
return AUTOWIRE_BY_TYPE;
}
}
return AUTOWIRE_CONSTRUCTOR;
}
else {
return this.autowireMode;
}
}
// dependencyCheck的setter & getter
public void setDependencyCheck(int dependencyCheck) {
this.dependencyCheck = dependencyCheck;
}
public int getDependencyCheck() {
return this.dependencyCheck;
}
// dependsOn的setter and getter
@Override
public void setDependsOn(@Nullable String... dependsOn) {
this.dependsOn = dependsOn;
}
// 获取当前Bean依赖的所有Bean
@Override
@Nullable
public String[] getDependsOn() {
return this.dependsOn;
}
@Override
public void setAutowireCandidate(boolean autowireCandidate) {
this.autowireCandidate = autowireCandidate;
}
@Override
public boolean isAutowireCandidate() {
return this.autowireCandidate;
}
@Override
public void setPrimary(boolean primary) {
this.primary = primary;
}
@Override
public boolean isPrimary() {
return this.primary;
}
// 限定符处理
public void addQualifier(AutowireCandidateQualifier qualifier) {
this.qualifiers.put(qualifier.getTypeName(), qualifier);
}
public boolean hasQualifier(String typeName) {
return this.qualifiers.containsKey(typeName);
}
@Nullable
public AutowireCandidateQualifier getQualifier(String typeName) {
return this.qualifiers.get(typeName);
}
public Set<AutowireCandidateQualifier> getQualifiers() {
return new LinkedHashSet<>(this.qualifiers.values());
}
public void copyQualifiersFrom(AbstractBeanDefinition source) {
Assert.notNull(source, "Source must not be null");
this.qualifiers.putAll(source.qualifiers);
}
/**
* Specify a callback for creating an instance of the bean,
* as an alternative to a declaratively specified factory method.
* <p>If such a callback is set, it will override any other constructor
* or factory method metadata. However, bean property population and
* potential annotation-driven injection will still apply as usual.
* @since 5.0
* @see #setConstructorArgumentValues(ConstructorArgumentValues)
* @see #setPropertyValues(MutablePropertyValues)
*/
public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
/**
* Return a callback for creating an instance of the bean, if any.
* @since 5.0
*/
@Nullable
public Supplier<?> getInstanceSupplier() {
return this.instanceSupplier;
}
/**
* Specify whether to allow access to non-public constructors and methods,
* for the case of externalized metadata pointing to those. The default is
* {@code true}; switch this to {@code false} for public access only.
* <p>This applies to constructor resolution, factory method resolution,
* and also init/destroy methods. Bean property accessors have to be public
* in any case and are not affected by this setting.
* <p>Note that annotation-driven configuration will still access non-public
* members as far as they have been annotated. This setting applies to
* externalized metadata in this bean definition only.
*/
public void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed) {
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
}
/**
* Return whether to allow access to non-public constructors and methods.
*/
public boolean isNonPublicAccessAllowed() {
return this.nonPublicAccessAllowed;
}
/**
* Specify whether to resolve constructors in lenient mode ({@code true},
* which is the default) or to switch to strict resolution (throwing an exception
* in case of ambiguous constructors that all match when converting the arguments,
* whereas lenient mode would use the one with the 'closest' type matches).
*/
public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
this.lenientConstructorResolution = lenientConstructorResolution;
}
/**
* Return whether to resolve constructors in lenient mode or in strict mode.
*/
public boolean isLenientConstructorResolution() {
return this.lenientConstructorResolution;
}
/**
* Specify the factory bean to use, if any.
* This the name of the bean to call the specified factory method on.
* @see #setFactoryMethodName
*/
@Override
public void setFactoryBeanName(@Nullable String factoryBeanName) {
this.factoryBeanName = factoryBeanName;
}
/**
* Return the factory bean name, if any.
*/
@Override
@Nullable
public String getFactoryBeanName() {
return this.factoryBeanName;
}
/**
* Specify a factory method, if any. This method will be invoked with
* constructor arguments, or with no arguments if none are specified.
* The method will be invoked on the specified factory bean, if any,
* or otherwise as a static method on the local bean class.
* @see #setFactoryBeanName
* @see #setBeanClassName
*/
@Override
public void setFactoryMethodName(@Nullable String factoryMethodName) {
this.factoryMethodName = factoryMethodName;
}
/**
* Return a factory method, if any.
*/
@Override
@Nullable
public String getFactoryMethodName() {
return this.factoryMethodName;
}
/**
* Specify constructor argument values for this bean.
*/
public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) {
this.constructorArgumentValues = constructorArgumentValues;
}
/**
* Return constructor argument values for this bean (never {@code null}).
*/
@Override
public ConstructorArgumentValues getConstructorArgumentValues() {
if (this.constructorArgumentValues == null) {
this.constructorArgumentValues = new ConstructorArgumentValues();
}
return this.constructorArgumentValues;
}
/**
* Return if there are constructor argument values defined for this bean.
*/
@Override
public boolean hasConstructorArgumentValues() {
return (this.constructorArgumentValues != null && !this.constructorArgumentValues.isEmpty());
}
/**
* Specify property values for this bean, if any.
*/
public void setPropertyValues(MutablePropertyValues propertyValues) {
this.propertyValues = propertyValues;
}
/**
* Return property values for this bean (never {@code null}).
*/
@Override
public MutablePropertyValues getPropertyValues() {
if (this.propertyValues == null) {
this.propertyValues = new MutablePropertyValues();
}
return this.propertyValues;
}
/**
* Return if there are property values values defined for this bean.
* @since 5.0.2
*/
@Override
public boolean hasPropertyValues() {
return (this.propertyValues != null && !this.propertyValues.isEmpty());
}
/**
* Specify method overrides for the bean, if any.
*/
public void setMethodOverrides(MethodOverrides methodOverrides) {
this.methodOverrides = methodOverrides;
}
/**
* Return information about methods to be overridden by the IoC
* container. This will be empty if there are no method overrides.
* <p>Never returns {@code null}.
*/
public MethodOverrides getMethodOverrides() {
return this.methodOverrides;
}
/**
* Return if there are method overrides defined for this bean.
* @since 5.0.2
*/
public boolean hasMethodOverrides() {
return !this.methodOverrides.isEmpty();
}
/**
* Set the name of the initializer method.
* <p>The default is {@code null} in which case there is no initializer method.
*/
@Override
public void setInitMethodName(@Nullable String initMethodName) {
this.initMethodName = initMethodName;
}
/**
* Return the name of the initializer method.
*/
@Override
@Nullable
public String getInitMethodName() {
return this.initMethodName;
}
/**
* Specify whether or not the configured initializer method is the default.
* <p>The default value is {@code true} for a locally specified init method
* but switched to {@code false} for a shared setting in a defaults section
* (e.g. {@code bean init-method} versus {@code beans default-init-method}
* level in XML) which might not apply to all contained bean definitions.
* @see #setInitMethodName
* @see #applyDefaults
*/
public void setEnforceInitMethod(boolean enforceInitMethod) {
this.enforceInitMethod = enforceInitMethod;
}
/**
* Indicate whether the configured initializer method is the default.
* @see #getInitMethodName()
*/
public boolean isEnforceInitMethod() {
return this.enforceInitMethod;
}
/**
* Set the name of the destroy method.
* <p>The default is {@code null} in which case there is no destroy method.
*/
@Override
public void setDestroyMethodName(@Nullable String destroyMethodName) {
this.destroyMethodName = destroyMethodName;
}
/**
* Return the name of the destroy method.
*/
@Override
@Nullable
public String getDestroyMethodName() {
return this.destroyMethodName;
}
/**
* Specify whether or not the configured destroy method is the default.
* <p>The default value is {@code true} for a locally specified destroy method
* but switched to {@code false} for a shared setting in a defaults section
* (e.g. {@code bean destroy-method} versus {@code beans default-destroy-method}
* level in XML) which might not apply to all contained bean definitions.
* @see #setDestroyMethodName
* @see #applyDefaults
*/
public void setEnforceDestroyMethod(boolean enforceDestroyMethod) {
this.enforceDestroyMethod = enforceDestroyMethod;
}
/**
* Indicate whether the configured destroy method is the default.
* @see #getDestroyMethodName()
*/
public boolean isEnforceDestroyMethod() {
return this.enforceDestroyMethod;
}
/**
* Set whether this bean definition is 'synthetic', that is, not defined
* by the application itself (for example, an infrastructure bean such
* as a helper for auto-proxying, created through {@code <aop:config>}).
*/
public void setSynthetic(boolean synthetic) {
this.synthetic = synthetic;
}
/**
* Return whether this bean definition is 'synthetic', that is,
* not defined by the application itself.
*/
public boolean isSynthetic() {
return this.synthetic;
}
/**
* Set the role hint for this {@code BeanDefinition}.
*/
@Override
public void setRole(int role) {
this.role = role;
}
/**
* Return the role hint for this {@code BeanDefinition}.
*/
@Override
public int getRole() {
return this.role;
}
/**
* Set a human-readable description of this bean definition.
*/
@Override
public void setDescription(@Nullable String description) {
this.description = description;
}
/**
* Return a human-readable description of this bean definition.
*/
@Override
@Nullable
public String getDescription() {
return this.description;
}
/**
* Set the resource that this bean definition came from
* (for the purpose of showing context in case of errors).
*/
public void setResource(@Nullable Resource resource) {
this.resource = resource;
}
/**
* Return the resource that this bean definition came from.
*/
@Nullable
public Resource getResource() {
return this.resource;
}
/**
* Set a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors).
*/
public void setResourceDescription(@Nullable String resourceDescription) {
this.resource = (resourceDescription != null ? new DescriptiveResource(resourceDescription) : null);
}
/**
* Return a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors).
*/
@Override
@Nullable
public String getResourceDescription() {
return (this.resource != null ? this.resource.getDescription() : null);
}
/**
* Set the originating (e.g. decorated) BeanDefinition, if any.
*/
public void setOriginatingBeanDefinition(BeanDefinition originatingBd) {
this.resource = new BeanDefinitionResource(originatingBd);
}
/**
* Return the originating BeanDefinition, or {@code null} if none.
* Allows for retrieving the decorated bean definition, if any.
* <p>Note that this method returns the immediate originator. Iterate through the
* originator chain to find the original BeanDefinition as defined by the user.
*/
@Override
@Nullable
public BeanDefinition getOriginatingBeanDefinition() {
return (this.resource instanceof BeanDefinitionResource ?
((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
}
// 验证当前Bean定义
public void validate() throws BeanDefinitionValidationException {
if (hasMethodOverrides() && getFactoryMethodName() != null) {
throw new BeanDefinitionValidationException(
"Cannot combine factory method with container-generated method overrides: " +
"the factory method must create the concrete bean instance.");
}
if (hasBeanClass()) {
prepareMethodOverrides();
}
}
// 处理BeanDefinition中Override父类的方法。
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// BeanDefinition是否有Override父类的方法。
if (hasMethodOverrides()) {
// 循环处理所有的Override方法进行校验
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
// 验证并准备为此bean定义的方法替代
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
// 方法不存在
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
// 方法只有一个实现
else if (count == 1) {
// Mark override as not overloaded, to avoid the overhead of arg type checking.
mo.setOverloaded(false);
}
}
// 基于当前BeanDefinition克隆一个bean
@Override
public Object clone() {
return cloneBeanDefinition();
}
// 基于当前BeanDefinition克隆一个bean
public abstract AbstractBeanDefinition cloneBeanDefinition();
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AbstractBeanDefinition)) {
return false;
}
AbstractBeanDefinition that = (AbstractBeanDefinition) other;
return (ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName()) &&
ObjectUtils.nullSafeEquals(this.scope, that.scope) &&
this.abstractFlag == that.abstractFlag &&
this.lazyInit == that.lazyInit &&
this.autowireMode == that.autowireMode &&
this.dependencyCheck == that.dependencyCheck &&
Arrays.equals(this.dependsOn, that.dependsOn) &&
this.autowireCandidate == that.autowireCandidate &&
ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers) &&
this.primary == that.primary &&
this.nonPublicAccessAllowed == that.nonPublicAccessAllowed &&
this.lenientConstructorResolution == that.lenientConstructorResolution &&
ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues) &&
ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues) &&
ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides) &&
ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName) &&
ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName) &&
ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName) &&
this.enforceInitMethod == that.enforceInitMethod &&
ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName) &&
this.enforceDestroyMethod == that.enforceDestroyMethod &&
this.synthetic == that.synthetic &&
this.role == that.role &&
super.equals(other));
}
@Override
public int hashCode() {
int hashCode = ObjectUtils.nullSafeHashCode(getBeanClassName());
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.scope);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.constructorArgumentValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryBeanName);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryMethodName);
hashCode = 29 * hashCode + super.hashCode();
return hashCode;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("class [");
sb.append(getBeanClassName()).append("]");
sb.append("; scope=").append(this.scope);
sb.append("; abstract=").append(this.abstractFlag);
sb.append("; lazyInit=").append(this.lazyInit);
sb.append("; autowireMode=").append(this.autowireMode);
sb.append("; dependencyCheck=").append(this.dependencyCheck);
sb.append("; autowireCandidate=").append(this.autowireCandidate);
sb.append("; primary=").append(this.primary);
sb.append("; factoryBeanName=").append(this.factoryBeanName);
sb.append("; factoryMethodName=").append(this.factoryMethodName);
sb.append("; initMethodName=").append(this.initMethodName);
sb.append("; destroyMethodName=").append(this.destroyMethodName);
if (this.resource != null) {
sb.append("; defined in ").append(this.resource.getDescription());
}
return sb.toString();
}
}
-
RootBeanDefinition
// RootBeanDefinition 继承了 AbstractBeanDefinition,这是一个具体 BeanDefinition,有实际作用。
// 一个 RootBeanDefinition 表示它是一个可合并的 BeanDefinition,会在 BeanFactory 解析的时候合成一个完整的 BeanDefinition。比如
// 这个 Bean 继承了某个类或继承了某个 Bean,亦或是实现了某个接口。
@SuppressWarnings("serial")
public class RootBeanDefinition extends AbstractBeanDefinition {
// BeanDefinitionHolder 封装了 Bean 的名称、别名、BeanDefinition
@Nullable
private BeanDefinitionHolder decoratedDefinition;
// AnnotatedElement 是java反射包的接口,通过它可以查看 Bean 的注解信息
@Nullable
private AnnotatedElement qualifiedElement;
/** Determines if the definition needs to be re-merged. */
volatile boolean stale;
// 是否允许缓存
boolean allowCaching = true;
// 工厂方法是否唯一
boolean isFactoryMethodUnique;
// 封装了 java.lang.reflect.Type,提供了泛型相关的操作
@Nullable
volatile ResolvableType targetType;
// 缓存 Class,表示 RootBeanDefinition 存储哪个类的信息
@Nullable
volatile Class<?> resolvedTargetType;
// 当前RootBeanDefinition是否是FactoryBean类型
@Nullable
volatile Boolean isFactoryBean;
// 缓存工厂方法的返回类型
@Nullable
volatile ResolvableType factoryMethodReturnType;
/** Package-visible field for caching a unique factory method candidate for introspection. */
@Nullable
volatile Method factoryMethodToIntrospect;
// 这是以下四个构造方法字段的通用锁
final Object constructorArgumentLock = new Object();
// 用于缓存已解析的构造方法或工厂方法
@Nullable
Executable resolvedConstructorOrFactoryMethod;
// 将构造方法参数标记为已解析
boolean constructorArgumentsResolved = false;
// 用于缓存完全解析的构造方法参数
@Nullable
Object[] resolvedConstructorArguments;
// 缓存待解析的构造方法参数
@Nullable
Object[] preparedConstructorArguments;
// 这是以下两个后处理字段的通用锁
final Object postProcessingLock = new Object();
// 表明是否被 MergedBeanDefinitionPostProcessor 处理过
boolean postProcessed = false;
// 在生成代理的时候会使用,表明是否已经生成代理
@Nullable
volatile Boolean beforeInstantiationResolved;
// 实际缓存的类型是 Constructor、Field、Method 类型
@Nullable
private Set<Member> externallyManagedConfigMembers;
// InitializingBean中 的 init 回调函数名,afterPropertiesSet 会在这里记录,以便进行生命周期回调
@Nullable
private Set<String> externallyManagedInitMethods;
// DisposableBean 的 destroy 回调函数名,destroy 会在这里记录,以便进生命周期回调
@Nullable
private Set<String> externallyManagedDestroyMethods;
// 以下是各种类型构造器的定义
/**
* Create a new RootBeanDefinition, to be configured through its bean
* properties and configuration methods.
* @see #setBeanClass
* @see #setScope
* @see #setConstructorArgumentValues
* @see #setPropertyValues
*/
public RootBeanDefinition() {
super();
}
/**
* Create a new RootBeanDefinition for a singleton.
* @param beanClass the class of the bean to instantiate
* @see #setBeanClass
*/
public RootBeanDefinition(@Nullable Class<?> beanClass) {
super();
setBeanClass(beanClass);
}
/**
* Create a new RootBeanDefinition for a singleton bean, constructing each instance
* through calling the given supplier (possibly a lambda or method reference).
* @param beanClass the class of the bean to instantiate
* @param instanceSupplier the supplier to construct a bean instance,
* as an alternative to a declaratively specified factory method
* @since 5.0
* @see #setInstanceSupplier
*/
public <T> RootBeanDefinition(@Nullable Class<T> beanClass, @Nullable Supplier<T> instanceSupplier) {
super();
setBeanClass(beanClass);
setInstanceSupplier(instanceSupplier);
}
/**
* Create a new RootBeanDefinition for a scoped bean, constructing each instance
* through calling the given supplier (possibly a lambda or method reference).
* @param beanClass the class of the bean to instantiate
* @param scope the name of the corresponding scope
* @param instanceSupplier the supplier to construct a bean instance,
* as an alternative to a declaratively specified factory method
* @since 5.0
* @see #setInstanceSupplier
*/
public <T> RootBeanDefinition(@Nullable Class<T> beanClass, String scope, @Nullable Supplier<T> instanceSupplier) {
super();
setBeanClass(beanClass);
setScope(scope);
setInstanceSupplier(instanceSupplier);
}
/**
* Create a new RootBeanDefinition for a singleton,
* using the given autowire mode.
* @param beanClass the class of the bean to instantiate
* @param autowireMode by name or type, using the constants in this interface
* @param dependencyCheck whether to perform a dependency check for objects
* (not applicable to autowiring a constructor, thus ignored there)
*/
public RootBeanDefinition(@Nullable Class<?> beanClass, int autowireMode, boolean dependencyCheck) {
super();
setBeanClass(beanClass);
setAutowireMode(autowireMode);
if (dependencyCheck && getResolvedAutowireMode() != AUTOWIRE_CONSTRUCTOR) {
setDependencyCheck(DEPENDENCY_CHECK_OBJECTS);
}
}
/**
* Create a new RootBeanDefinition for a singleton,
* providing constructor arguments and property values.
* @param beanClass the class of the bean to instantiate
* @param cargs the constructor argument values to apply
* @param pvs the property values to apply
*/
public RootBeanDefinition(@Nullable Class<?> beanClass, @Nullable ConstructorArgumentValues cargs,
@Nullable MutablePropertyValues pvs) {
super(cargs, pvs);
setBeanClass(beanClass);
}
/**
* Create a new RootBeanDefinition for a singleton,
* providing constructor arguments and property values.
* <p>Takes a bean class name to avoid eager loading of the bean class.
* @param beanClassName the name of the class to instantiate
*/
public RootBeanDefinition(String beanClassName) {
setBeanClassName(beanClassName);
}
/**
* Create a new RootBeanDefinition for a singleton,
* providing constructor arguments and property values.
* <p>Takes a bean class name to avoid eager loading of the bean class.
* @param beanClassName the name of the class to instantiate
* @param cargs the constructor argument values to apply
* @param pvs the property values to apply
*/
public RootBeanDefinition(String beanClassName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
super(cargs, pvs);
setBeanClassName(beanClassName);
}
/**
* Create a new RootBeanDefinition as deep copy of the given
* bean definition.
* @param original the original bean definition to copy from
*/
public RootBeanDefinition(RootBeanDefinition original) {
super(original);
this.decoratedDefinition = original.decoratedDefinition;
this.qualifiedElement = original.qualifiedElement;
this.allowCaching = original.allowCaching;
this.isFactoryMethodUnique = original.isFactoryMethodUnique;
this.targetType = original.targetType;
this.factoryMethodToIntrospect = original.factoryMethodToIntrospect;
}
/**
* Create a new RootBeanDefinition as deep copy of the given
* bean definition.
* @param original the original bean definition to copy from
*/
RootBeanDefinition(BeanDefinition original) {
super(original);
}
// 以下是setter & getter定义
@Override
public String getParentName() {
return null;
}
@Override
public void setParentName(@Nullable String parentName) {
if (parentName != null) {
throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
}
}
/**
* Register a target definition that is being decorated by this bean definition.
*/
public void setDecoratedDefinition(@Nullable BeanDefinitionHolder decoratedDefinition) {
this.decoratedDefinition = decoratedDefinition;
}
/**
* Return the target definition that is being decorated by this bean definition, if any.
*/
@Nullable
public BeanDefinitionHolder getDecoratedDefinition() {
return this.decoratedDefinition;
}
/**
* Specify the {@link AnnotatedElement} defining qualifiers,
* to be used instead of the target class or factory method.
* @since 4.3.3
* @see #setTargetType(ResolvableType)
* @see #getResolvedFactoryMethod()
*/
public void setQualifiedElement(@Nullable AnnotatedElement qualifiedElement) {
this.qualifiedElement = qualifiedElement;
}
/**
* Return the {@link AnnotatedElement} defining qualifiers, if any.
* Otherwise, the factory method and target class will be checked.
* @since 4.3.3
*/
@Nullable
public AnnotatedElement getQualifiedElement() {
return this.qualifiedElement;
}
/**
* Specify a generics-containing target type of this bean definition, if known in advance.
* @since 4.3.3
*/
public void setTargetType(ResolvableType targetType) {
this.targetType = targetType;
}
/**
* Specify the target type of this bean definition, if known in advance.
* @since 3.2.2
*/
public void setTargetType(@Nullable Class<?> targetType) {
this.targetType = (targetType != null ? ResolvableType.forClass(targetType) : null);
}
/**
* Return the target type of this bean definition, if known
* (either specified in advance or resolved on first instantiation).
* @since 3.2.2
*/
@Nullable
public Class<?> getTargetType() {
if (this.resolvedTargetType != null) {
return this.resolvedTargetType;
}
ResolvableType targetType = this.targetType;
return (targetType != null ? targetType.resolve() : null);
}
/**
* Return a {@link ResolvableType} for this bean definition,
* either from runtime-cached type information or from configuration-time
* {@link #setTargetType(ResolvableType)} or {@link #setBeanClass(Class)},
* also considering resolved factory method definitions.
* @since 5.1
* @see #setTargetType(ResolvableType)
* @see #setBeanClass(Class)
* @see #setResolvedFactoryMethod(Method)
*/
@Override
public ResolvableType getResolvableType() {
ResolvableType targetType = this.targetType;
if (targetType != null) {
return targetType;
}
ResolvableType returnType = this.factoryMethodReturnType;
if (returnType != null) {
return returnType;
}
Method factoryMethod = this.factoryMethodToIntrospect;
if (factoryMethod != null) {
return ResolvableType.forMethodReturnType(factoryMethod);
}
return super.getResolvableType();
}
/**
* Determine preferred constructors to use for default construction, if any.
* Constructor arguments will be autowired if necessary.
* @return one or more preferred constructors, or {@code null} if none
* (in which case the regular no-arg default constructor will be called)
* @since 5.1
*/
@Nullable
public Constructor<?>[] getPreferredConstructors() {
return null;
}
/**
* Specify a factory method name that refers to a non-overloaded method.
*/
public void setUniqueFactoryMethodName(String name) {
Assert.hasText(name, "Factory method name must not be empty");
setFactoryMethodName(name);
this.isFactoryMethodUnique = true;
}
/**
* Specify a factory method name that refers to an overloaded method.
* @since 5.2
*/
public void setNonUniqueFactoryMethodName(String name) {
Assert.hasText(name, "Factory method name must not be empty");
setFactoryMethodName(name);
this.isFactoryMethodUnique = false;
}
/**
* Check whether the given candidate qualifies as a factory method.
*/
public boolean isFactoryMethod(Method candidate) {
return candidate.getName().equals(getFactoryMethodName());
}
/**
* Set a resolved Java Method for the factory method on this bean definition.
* @param method the resolved factory method, or {@code null} to reset it
* @since 5.2
*/
public void setResolvedFactoryMethod(@Nullable Method method) {
this.factoryMethodToIntrospect = method;
}
/**
* Return the resolved factory method as a Java Method object, if available.
* @return the factory method, or {@code null} if not found or not resolved yet
*/
@Nullable
public Method getResolvedFactoryMethod() {
return this.factoryMethodToIntrospect;
}
public void registerExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedConfigMembers == null) {
this.externallyManagedConfigMembers = new HashSet<>(1);
}
this.externallyManagedConfigMembers.add(configMember);
}
}
public boolean isExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null &&
this.externallyManagedConfigMembers.contains(configMember));
}
}
public void registerExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedInitMethods == null) {
this.externallyManagedInitMethods = new HashSet<>(1);
}
this.externallyManagedInitMethods.add(initMethod);
}
}
public boolean isExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null &&
this.externallyManagedInitMethods.contains(initMethod));
}
}
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedDestroyMethods == null) {
this.externallyManagedDestroyMethods = new HashSet<>(1);
}
this.externallyManagedDestroyMethods.add(destroyMethod);
}
}
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null &&
this.externallyManagedDestroyMethods.contains(destroyMethod));
}
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
return new RootBeanDefinition(this);
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof RootBeanDefinition && super.equals(other)));
}
@Override
public String toString() {
return "Root bean: " + super.toString();
}
}
-
ChildBeanDefinition
// 该类继承自 AbstractBeanDefinition。其相当于一个子类,不可以单独存在,必须依赖一个父 BeanDetintion,构造 ChildBeanDefinition 时,
// 通过构造方法传入父 BeanDetintion 的名称或通过 setParentName 设置父名称。它可以从父类继承方法参数、属性值,并可以重写父类的方法,
// 同时也可以增加新的属性或者方法。若重新定义 init 方法,destroy 方法或者静态工厂方法,ChildBeanDefinition 会重写父类的设置。
@SuppressWarnings("serial")
public class ChildBeanDefinition extends AbstractBeanDefinition {
// 父BeanDefinition名称
@Nullable
private String parentName;
// 以下是构造器和setter getter方法
/**
* Create a new ChildBeanDefinition for the given parent, to be
* configured through its bean properties and configuration methods.
* @param parentName the name of the parent bean
* @see #setBeanClass
* @see #setScope
* @see #setConstructorArgumentValues
* @see #setPropertyValues
*/
public ChildBeanDefinition(String parentName) {
super();
this.parentName = parentName;
}
/**
* Create a new ChildBeanDefinition for the given parent.
* @param parentName the name of the parent bean
* @param pvs the additional property values of the child
*/
public ChildBeanDefinition(String parentName, MutablePropertyValues pvs) {
super(null, pvs);
this.parentName = parentName;
}
/**
* Create a new ChildBeanDefinition for the given parent.
* @param parentName the name of the parent bean
* @param cargs the constructor argument values to apply
* @param pvs the additional property values of the child
*/
public ChildBeanDefinition(
String parentName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
super(cargs, pvs);
this.parentName = parentName;
}
/**
* Create a new ChildBeanDefinition for the given parent,
* providing constructor arguments and property values.
* @param parentName the name of the parent bean
* @param beanClass the class of the bean to instantiate
* @param cargs the constructor argument values to apply
* @param pvs the property values to apply
*/
public ChildBeanDefinition(
String parentName, Class<?> beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
super(cargs, pvs);
this.parentName = parentName;
setBeanClass(beanClass);
}
/**
* Create a new ChildBeanDefinition for the given parent,
* providing constructor arguments and property values.
* Takes a bean class name to avoid eager loading of the bean class.
* @param parentName the name of the parent bean
* @param beanClassName the name of the class to instantiate
* @param cargs the constructor argument values to apply
* @param pvs the property values to apply
*/
public ChildBeanDefinition(
String parentName, String beanClassName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
super(cargs, pvs);
this.parentName = parentName;
setBeanClassName(beanClassName);
}
/**
* Create a new ChildBeanDefinition as deep copy of the given
* bean definition.
* @param original the original bean definition to copy from
*/
public ChildBeanDefinition(ChildBeanDefinition original) {
super(original);
}
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}
@Override
@Nullable
public String getParentName() {
return this.parentName;
}
@Override
public void validate() throws BeanDefinitionValidationException {
super.validate();
if (this.parentName == null) {
throw new BeanDefinitionValidationException("'parentName' must be set in ChildBeanDefinition");
}
}
@Override
public AbstractBeanDefinition cloneBeanDefinition() {
return new ChildBeanDefinition(this);
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof ChildBeanDefinition)) {
return false;
}
ChildBeanDefinition that = (ChildBeanDefinition) other;
return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
}
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.parentName) * 29 + super.hashCode();
}
@Override
public String toString() {
return "Child bean with parent '" + this.parentName + "': " + super.toString();
}
}
-
GenericBeanDefinition
// GenericBeanDefinition同样继承了 AbstractBeanDefinition。它用来表示一个普通的 Bean,没特别的作用。
// GenericBeanDefinition 是 Spring 2.5 以后新引入的 BeanDefinition,是 ChildBeanDefinition 更好的替代者,它同样可以
// 通过 setParentName 方法设置父 BeanDefinition。
// 和ChildBeanDefinition一样,他其相当于一个子类,不可以单独存在,必须依赖一个父 BeanDetintion,构造 ChildBeanDefinition 时,
// 通过构造方法传入父 BeanDetintion 的名称或通过 setParentName 设置父名称。
@SuppressWarnings("serial")
public class GenericBeanDefinition extends AbstractBeanDefinition {
// 父BeanDefinition名称
@Nullable
private String parentName;
// 以下是构造器和setter getter方法定义
/**
* Create a new GenericBeanDefinition, to be configured through its bean
* properties and configuration methods.
* @see #setBeanClass
* @see #setScope
* @see #setConstructorArgumentValues
* @see #setPropertyValues
*/
public GenericBeanDefinition() {
super();
}
/**
* Create a new GenericBeanDefinition as deep copy of the given
* bean definition.
* @param original the original bean definition to copy from
*/
public GenericBeanDefinition(BeanDefinition original) {
super(original);
}
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}
@Override
@Nullable
public String getParentName() {
return this.parentName;
}
@Override
public AbstractBeanDefinition cloneBeanDefinition() {
return new GenericBeanDefinition(this);
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof GenericBeanDefinition)) {
return false;
}
GenericBeanDefinition that = (GenericBeanDefinition) other;
return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
}
@Override
public String toString() {
if (this.parentName != null) {
return "Generic bean with parent '" + this.parentName + "': " + super.toString();
}
return "Generic bean: " + super.toString();
}
}
Pt2 循环依赖
Pt2.1 什么是循环依赖
循环依赖是指,A 依赖 B,B 又依赖 A,它们之间形成了循环依赖。或者是 A 依赖 B,B 依赖 C,C 又依 赖 A。
它们之间的依赖关系如下:
伪代码形式如下:
public class ClassA {
// ClassA中依赖ClassB
@Autowired
private ClassB classB;
}
public class ClassB {
// ClassB中依赖ClassA
@Autowired
private ClassA classA;
}
这就像在并发中,两个线程都拿到了对方需要的锁,互相等待形成死循环是同样道理。死锁是在编码期通过代码申请来预防互相等待的场景,但是Bean的循环依赖确实不可避免的场景,不能因为已经有了A依赖B,就不允许B使用A对象。
那如何解决循环依赖的问题呢?我们从Bean对象的初始化过程开始分析。
Pt2.2 Bean的初始化过程
在解决Singleton Bean的循环依赖前,我们先来看看Singleton Bean的初始化过程。
通常单例Bean的初始化过程,可以分为三个步骤:
-
createBeanInstance:实例化,也就是调用对象的构造器实例化对象。实例化就完成内存地址的分配,有了固定的“身份证”;
-
populateBean:填充属性,这一步主要是多bean的依赖属性进行填充,也就是DI的核心;
-
initializeBean:调用spring xml中的init 方法,也包括BeanPostProcessor中自定义的逻辑。
Bean的创建过程中,初始化完成才能被缓存到容器中,导致循环依赖无法解决。那如果提前暴露Bean对象呢?
Pt2.3 二级缓存
我们知道,对象间依赖是持有其它对象的内存地址,而当对象实例化完成(即第一步,完成构造器执行)后就获得了内存对象地址,并且在后续的创建过程中不会改变内存地址,那我们可以提前暴露对象(内存地址)到容器中,来解决循环依赖的死循环问题。
但是,此时的对象还没有完全完成创建过程,属于不完整的对象,无法像真正的对象一样执行相关逻辑,所以要有所区分,要用不同的容器来缓存两种对象。
// 一级缓存,缓存已经真正完成创建过程的单例对象,该缓存key = beanName, value = bean;
// 这里的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各类的后置处理。因此,一旦需要获取bean时,我们第一时间就会寻找一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
// 二级缓存,对象没有完成所有创建流程,可能只执行了构造器逻辑。被提前暴露是为了解决循环依赖问题。该缓存key = beanName, value = bean;
// 跟一级缓存的区别在于,该缓存所获取到的bean是提前曝光出来的,是还没创建完成的。也就是说获取到的bean只能确保已经进行了实例化,但是属性填充跟初始化肯定还没有做完,因此该bean还没创建完成,仅仅能作为指针提前曝光,被其他bean所引用
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
二级缓存作用是:暴露早期对象,为了将成熟bean和纯净bean 分离。解决循环依赖问题,也防止多线程环境下,读取到了不完整的Bean去执行真正逻辑。
还有一点关于bean的Aop动态代理的问题,我们都知道Bean的aop动态代理创建是在初始化之后,但是循环依赖的Bean如果使用了AOP。 那无法等到解决完循环依赖再创建动态代理, 因为这个时候已经注入属性。 所以如果循环依赖的Bean使用了aop,需要提前创建aop。
-
如果没有循环依赖的话,在bean初始化完成后创建动态代理
-
如果有循环依赖,在bean实例化之后创建
Pt2.4 三级缓存
存在的意义?
有个很重要的问题是,既然二级缓存已经能够提交暴露Bean对象,用于解决循环依赖的问题,那为什么又衍生出三级缓存呢?意义在哪里呢?
在上面的介绍中,我们已经展示了两个对象之间互相依赖的场景的解决方案,但是忽略了Spring一个重要的特性——AOP。
A、B互相依赖,同时他们都有AOP配置,最终被容器管理的是Bean的AOP代理类对象,所以他们互相持有的也应该是对方的AOP代理类对象。假设没有三级缓存,A对象实例化,放入二级缓存,然后发现依赖B对象,触发B对象的创建流程。所以此时B对象也实例化,发现依赖A对象,从二级缓存中拿到A对象,但是此时拿到的是A的原生对象,而没有拿到AOP增强的A对象,在实际使用时丢失了AOP的能力。
那实例化之后直接生成AOP代理类不就好了吗?但是此时A对象只是实例化,并没有处理完后续的创建流程,还是不完整的对象,后面需要大量用到原生对象来完成创建过程。
所以就产生了矛盾,这也是三级缓存诞生的原因。我们既需要持有还在创建中的原生bean对象,又要拿到Bean对象被AOP增强的代理类对象。
这段描述非常拗口,我们知道,AOP代理类对象是在原生对象完成创建之后生成的。
再循环依赖的场景下,又必须要提前暴露还未完成创建的对象,如果有AOP,还需要暴露AOP增强的代理类对象。
来看看添加三级缓存的源码:
通过构造器完成Bean实例化之后,就需要判断是否需要将Bean添加到三级缓存中。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
// 5、添加Bean的三级缓存,用于处理循环依赖的场景。
// 如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。
// 这个三级缓存的对象有两种情况:如果Bean有AOP处理则生成AOP代理类对象,如果Bean没有AOP代理则生成普通Bean对象。生成的对象会被包装秤
// ObjectFactory对象类型放入三级缓存中,用于在循环依赖时提前暴露代理类对象。
// 这里最核心的还是要处理AOP代理类的情况,因为如果只是单纯的普通Bean对象,三级缓存的意义不是很大。
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 1、获取需要暴露的Bean对象;
// 2、将Bean对象包装成ObjectFactory形式;
// 3、将ObjectFactory添加到三级缓存中;
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这段代码看似比较简单,但是却有三层逻辑。
1. getEarlyBeanReference(beanName, mbd, bean) 获取Bean对象
/**
* 获取一个可以提前暴露的Bean对象,这里可能是原生bean对象,也可能是bean的代理类对象。
*
* @param beanName Bean对象名称
* @param mbd Bean对象定义(合并的)
* @param bean 原生的Bean对象
* @return 提前暴露的 包装了原生Bean对象 ObjectFactory对象
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
// 提前暴露(放入三级缓存)的对象exposedObject
Object exposedObject = bean;
// 如果有AOP配置,这里会生成Bean对象的AOP代理类对象,exposedObject = bean的AOP代理类对象
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
// 否则exposedObject只是原生的bean对象
return exposedObject;
}
生成AOP代理类部分暂时不细说,会在AOP部分有介绍,这里只要知道是创建bean的AOP增强代理类。
2. lambada表达式
一开始没有看到这个,不明白ObjectFactory的作用,其实这里就是使用无参构造器将获得的Bean对象或者AOP代理对象包装成ObjectFactory对象,然后暴露到三级缓存中。
ObjectFactory只是简单的工厂类,他是对bean对象(普通bean对象或者AOP增强代理对象)的一层代理,通过ObjectFactory可以拿到bean对象。
3. addSingletonFactory 添加缓存
// 缓存SingletonFactory信息
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 一级缓存不存在,说明没有被创建过
if (!this.singletonObjects.containsKey(beanName)) {
// 添加到三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 从二级缓存中移除
this.earlySingletonObjects.remove(beanName);
// 记录Bean注册顺序
this.registeredSingletons.add(beanName);
}
}
}
此时我们已经将代理类加入到三级缓存中,别的对象在引用时,也是直接获取代理类的对象引用。
三级缓存分别是:
-
singletonObject:一级缓存,该缓存key = beanName, value = bean;这里的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各类的后置处理。因此,一旦需要获取bean时,我们第一时间就会寻找一级缓存
-
earlySingletonObjects:二级缓存,该缓存key = beanName, value = bean;这里跟一级缓存的区别在于,该缓存所获取到的bean是提前曝光出来的,是还没创建完成的。也就是说获取到的bean只能确保已经进行了实例化,但是属性填充跟初始化肯定还没有做完,因此该bean还没创建完成,仅仅能作为指针提前曝光,被其他bean所引用
-
singletonFactories:三级缓存,不是用来存bean的实例,而是用来存函数接口、钩子函数的!该缓存key = beanName, value =beanFactory;在bean实例化完之后,属性填充以及初始化之前,如果允许提前曝光,spring会将实例化后的bean提前曝光,也就是把该bean转换成beanFactory并加入到三级缓存。在需要引用提前曝光对象时再通过singletonFactory.getObject()获取。
Pt2.5 Prototype和构造器注入无法解决循环依赖
单例Bean利用三级缓存来解决循环依赖的问题,有两个原因:
-
一是因为Bean是单例的,只需要创建一次对象,后面就可以从缓存中取出来;
-
二是字段注入(setter注入)的,可以将构造器执行和属性填充过程分开,以解决循环依赖的问题。
Prototype就意味着每次都要去创建对象,无法利用缓存,无法解决循环依赖。
构造器注入是在构造器执行时触发对象引用,无法将实例化和循环依赖的属性填充过程分开,无法解决循环依赖。
Pt3 DI初始化流程
Pt3.1 寻找DI入口
在开头已经说过,DI存在两个入口,其中一个入口就是getBean方法,我们先从getBean方法中寻找更进一步的入口。
在BeanFactory中定义了一堆getBean():
// Spring IoC容器管理Bean的工厂类
public interface BeanFactory {
// 根据Bean的名字,获取在IoC容器中得到的Bean的实例。
Object getBean(String name) throws BeansException;
// 根据Bean的名字和Class类型,获取在IoC容器中得到的Bean的实例,增加了类型安全验证机制。
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 根据Bean的名字和参数,获取在IoC容器中得到的Bean的实例。
Object getBean(String name, Object... args) throws BeansException;
// 根据Class类型获取IoC容器中的实例
<T> T getBean(Class<T> requiredType) throws BeansException;
// 根据Class类型和参数,获取在IoC容器中得到的Bean的实例。
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
......
}
核心实现在抽象子类中实现,其中doGetBean包含了完整的处理流程:
// org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Object...)
// 获取IoC容器中指定名称和参数的Bean。
@Override
public Object getBean(String name, Object... args) throws BeansException {
// 真正从IoC容器中获取被管理的Bean是通过doGetBean()来完成。
return doGetBean(name, null, args, false);
}
// 完成从IoC容器获取Bean的功能,同时会触发DI(核心功能)
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1、根据输入参数的名称获取被管理的Bean名称,剥离指定名称中对容器的相关依赖。
// 如果指定的是别名,将别名转换为规范的Bean名称。
String beanName = transformedBeanName(name);
// 返回的Bean实例
Object bean;
// 2、从缓存中读取是否已经有被创建过的单例模式的Bean。
// 对于单例模式的Bean,整个IoC容器只会初始化一次,不需要重复创建。如果在容器中已有指定名称的单例模式的Bean被创建,直接返回已经创建的Bean。
Object sharedInstance = getSingleton(beanName);
// sharedInstance不为空表示容器中已经有名称为beanName的Singleton类型的Bean。
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 指定名称的单例Bean已经存在,但未完全初始化完成。
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 获取给定Bean的实例对象,完成FactoryBean的处理。
// 注意的是,BeanFactory是管理Bean的工厂,FactoryBean是创建对象的工厂Bean,两者之间有区别。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 到此为止,前面是尝试从缓存中获取已经存在的Singleton Bean,如果不满足条件,则尝试新建该Bean。
// 3、缓存中没有正在创建的或者已经完成创建的单例模式的Bean
// 包含两种情况:一种是单例Bean还还没启动创建流程,所以缓存中不存在;另一种是Bean非单例,需要执行创建过程。
else {
// 如果存在正在被创建的prototype类型的Bean,则停止本次处理,抛出异常。
// 如果没有被创建的prototype bean,或者存在已经完成创建的prototype bean,则继续向下处理。
// 只有存在正在创建的prototype bean才会终止操作,由于循环引用会导致这种情况。
//
// 举例来说,A、B互相引用,getBean(A)在进行A实例化过程中,会触发B的实例化操作(DI)。B引用了A,而此时A对象正在creating还
// 没有结束(因为要完成B的初始化和注入操作),所以B实例化过程中再次调用getBean(A)获取注入属性时,便会触发此处的场景。
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 4、对IoC容器中是否存在指定名称的BeanDefinition进行检查。
// 首先检查是否能再当前容器中获取所需的Bean,如果不能则委托当前容器的父容器去查找,如果还是没有则一直沿着容器的继承体系继续查找下去。
BeanFactory parentBeanFactory = getParentBeanFactory();
// 当前容器中不存在指定名称的BeanDefinition,且当前容器存在父容器时
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 解析指定Bean名称的原始名称
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 通过父容器递归调用doGetBean获取对象实例
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// 委派父容器根据指定名称和参数进行查找
else if (args != null) {
// 通过父容器获取Bean实例
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
// 委派父容器根据指定名称和类型进行查找
else if (requiredType != null) {
// 通过父容器获取Bean实例
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
// 委派父容器根据指定名称进行查找
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 如果当前容器中存在指定名称的BeanDefinition时,执行如下操作。
// 创建的Bean是否需要进行类型验证
if (!typeCheckOnly) {
// 5、向容器标记指定的Bean已经被创建。
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
// 根据指定Bean名称获取其父级Bean定义,主要解决Bean继承时子类和父类公共属性问题。
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 6、获取当前Bean所有依赖Bean的名称,并完成关系注册和依赖Bean的实例化。
// DependsOn是@DependsOn注解所标注的,当前Bean必须等到所有DependsOn Bean全部初始化之后才能初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 循环处理当前Bean依赖的Bean对象dep
for (String dep : dependsOn) {
// dependsOnBean也依赖beanName,出现循环依赖则报错,相当于死循环。
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册两个Bean之间的依赖关系:BeanName依赖dep
registerDependentBean(dep, beanName);
try {
// 先实例化当前Bean的@DependsOn所标注的Bean
// 递归调用getBean()获取当前Bean的 依赖Bean的 实例化对象。
// 此时,只完成依赖Bean的实例化,还没有真正完成依赖注入。
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 到此为止,Bean创建的准备工作已经完成了,现在执行具体的Bean创建操作。
// 7、创建单例模式的Bean对象的场景。
if (mbd.isSingleton()) {
// 创建真正Bean实例对象
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建指定名称的Bean对象(核心逻辑)。
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 从IoC容器中清除单例模式的Bean对象
destroySingleton(beanName);
throw ex;
}
});
// 根据传参获取给定Bean的相关实例对象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 8、创建原型模式的Bean对象的场景。
else if (mbd.isPrototype()) {
// 原型模式每次都会创建一个新的对象
Object prototypeInstance = null;
try {
// 标记当前BeanName为创建中状态
beforePrototypeCreation(beanName);
// 创建指定Prototype类型Bean的实例对象
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 将当前beanName从创建中列表中移除
afterPrototypeCreation(beanName);
}
// 根据传参获取给定Bean的相关实例对象。
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 9、要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
else {
// 获取配置的生命周期scope,选择实例化Bean的合适方法,这种方式在Web应用程序中比较常用,比如request、session、application等。
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
// 如果Bean定义资源中没有配置生命周期范围,则Bean定义不合法。
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 获取指定生命周期范围的Bean实例
Object scopedInstance = scope.get(beanName, () -> {
// 标记当前BeanName为创建中状态
beforePrototypeCreation(beanName);
try {
// 创建指定Bean的对象实例
return createBean(beanName, mbd, args);
}
finally {
// 将当前beanName从创建中列表中移除
afterPrototypeCreation(beanName);
}
});
// 获取指定Bean的实例对象
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
// 至此,已经完成整个Bean对象的创建过程,包括实例化、属性设置和初始化(#init),也包括了FactoryBean的处理,获得了真正定义的Bean对象。
// 10、对创建的Bean实例对象进行类型检查
// 指定的Bean类型不为空,且和当前获得的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.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
doGetBean就是完成DI核心逻辑的方法,里面包含了对多种场景的判断,接下来我们逐步分析doGetBean都在做些什么。
Pt3.2 Bean名称解析
分析的代码段:
// 1、根据输入参数的名称获取被管理的Bean名称,剥离指定名称中对容器的相关依赖。 // 如果指定的是别名,将别名转换为规范的Bean名称。 String beanName = transformedBeanName(name);
getBean()参数中传入的name可能不是标准的容器管理的Bean名称,也可能是定义的别名,需要解析出Bean在容器中被管理时所对应的规范的Bean名称。
// org.springframework.beans.factory.support.AbstractBeanFactory#transformedBeanName
// 根据指定的名称,转换为被IoC容器管理的Bean的名称,剥离指定名称中跟容器相关的前后缀依赖。
// 如果是别名,则转换为对应的Bean的名称。
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
去除FactoryBean前缀:
// org.springframework.beans.factory.BeanFactoryUtils#transformedBeanName
// 剥离Bean名称对容器的依赖,获取真正被管理的Bean名称
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
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;
});
}
Spring中可以为Bean定义别名,并且可以嵌套定义多层,比如下面的形式:
<bean id="aliasBean" name="aliasBean1,aliasBean2" class="AliasBean.AliasBean"/>
<alias name="aliasBean" alias="aliasBean1"/>
<alias name="aliasBean1" alias="aliasBean2"/>
<alias name="aliasBean2" alias="aliasBean3"/>
canonicalName的作用就是解析出别名对应的名称,并且能够嵌套处理:
// org.springframework.core.SimpleAliasRegistry#canonicalName
// 根据别名获取被管理的Bean名称
public String canonicalName(String name) {
// 1、如果当前Bean名称就是标准名称,则不做任何处理。
String canonicalName = name;
// 2、根据传入name从别名映射缓存中查询标准名称。
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
} while (resolvedName != null);
return canonicalName;
}
Pt3.3 获取缓存的单例Bean
分析的代码段:
// 2、从缓存中读取是否已经有被创建过的单例模式的Bean。 // 对于单例模式的Bean,整个IoC容器只会初始化一次,不需要重复创建。如果在容器中已有指定名称的单例模式的Bean被创建,直接返回已经创建的Bean。 Object sharedInstance = getSingleton(beanName);
IoC容器会缓存Singleton类型的Bean,防止重复构建的场景,prototype类型则不会。所以先从缓存中获取Bean对象,如果已经有创建好的或者创建中的对象,则可以直接拿来用(主要针对Singleton类型)而不用重复创建。
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
// 一级缓存
// 缓存已经真正完成创建过程的单例对象,该缓存key = beanName, value = bean;
// 这里的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各类的后置处理。
// 因此,一旦需要获取bean时,我们第一时间就会寻找一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存
// 对象没有完成所有创建流程,可能只执行了构造器逻辑。被提前暴露是为了解决循环依赖问题。该缓存key = beanName, value = bean;
// 跟一级缓存的区别在于,该缓存所获取到的bean是提前曝光出来的,是还没创建完成的。也就是说获取到的bean只能确保已经进行了实例化,但是属性填充
// 跟初始化肯定还没有做完,因此该bean还没创建完成,仅仅能作为指针提前曝光,被其他bean所引用
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三级缓存
// 不是用来存bean的实例,而是用来存函数接口、钩子函数的!该缓存key = beanName, value =beanFactory;在bean实例化完
// 之后,属性填充以及初始化之前,如果允许提前曝光,spring会将实例化后的bean提前曝光,也就是把该bean转换成beanFactory并加入到三级缓存。
// 在需要引用提前曝光对象时再通过singletonFactory.getObject()获取。
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 获取指定名称的单例Bean
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
// 尝试从多级缓存中获取原生的单例Bean对象。
// allowEarlyReference:是否开启三级缓存
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1、尝试从一级缓存(已完成对象创建)获取singleton对象
Object singletonObject = this.singletonObjects.get(beanName);
// 2、单例对象创建中,但还未完成创建过程,尝试从二级缓存中获取对象。
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 3、如果一级缓存和二级缓存都没有,并且启用了三级缓存,则从三级缓存获取。
if (singletonObject == null && allowEarlyReference) {
// 再次尝试从一级缓存和二级缓存获取,防止并发的情况。
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 4、 尝试从三级缓存获取对象。
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 5、将对象从三级缓存移除,并加入到二级缓存中。
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
多级缓存在前面[循环依赖]部分介绍过。
Pt3.4 从FactoryBean获取Bean对象
分析的代码段:
// 获取给定Bean的实例对象,完成FactoryBean的处理。 // 注意的是,BeanFactory是管理Bean的工厂,FactoryBean是创建对象的工厂Bean,两者之间有区别。 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
如果从缓存中获取了不为空的BeanInstance,则说明Singleton Bean已经被实例化处理过。此时需要根据getBean()传入name的类型,解析出客户端真正需要的目标类型的Bean对象。
// org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
// Spring管理的bean实例分为两类,一类是实现FactoryBean接口的Bean,一类是真正类型的Bean。容器已经得到Bean实例对象,
// 这个对象可能是普通Bean,也可能是FactoryBean。、
// #getObjectForBeanInstance()目的就是获得对应类型的Bean对象,可能是从FactoryBean解析出来的对象,也可能直接是真正的Bean类型。
// beanInstance:已经获取的对象实例
// name:客户端传入需要获取的Bean名称
// beanName:根据name解析的规范化Bean名称
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 1、希望获得FactoryBean类型对象的场景。
// 如果指定name是FactoryBean类型,说明调用本身是想获得FactoryBean容器的引用,则只需要判断实例beanInstance是否是FactoryBean类型的对象,然后返回即可。
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 但获取的Bean实例不是FactoryBean类型则抛出异常。
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
// 返回已经获得的FactoryBean类型的实例对象
return beanInstance;
}
// 2、希望获得普通Bean对象的,且已经获得的场景。
// 如果指定名称name不是FactoryBean的类型,说明调用是想获得真正的Bean实例对象,只需要判定实例beanInstance本身是否是普通Bean对象,然后返回即可。
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 3、从FactoryBean获取普通Bean对象。
// 指定名称name不是FactoryBean的类型,说明调用是想获得真正的Bean实例对象,而传入实例beanInstance本身又是FactoryBean类型对象,
// 则需要从FactoryBean中获得真正的Bean对象。
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
// 从BeanFactory缓存中获取指定名称的Bean实例对象
object = getCachedObjectForFactoryBean(beanName);
}
// 4、基于FactoryBean生成普通Bean。
// FactoryBean缓存中没有数据,表明还没有生成过的记录,则通过FactoryBean生成Bean实例。
if (object == null) {
// 将beanInstance转换为FactoryBean
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// IoC容器中包含指定beanName的定义,则尝试获取该beanName的完整定义mbd(包含基类的属性)
if (mbd == null && containsBeanDefinition(beanName)) {
// 从容器中获取指定名称的Bean定义,如果继承了相关类,则合并基类属性
mbd = getMergedLocalBeanDefinition(beanName);
}
// 如果从容器中得到了Bean定义信息,并且BeanDefinition不是虚构的,则让FactoryBean生成Bean实例对象
// 关于synthetic的意义:是否是合成类(不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,这些辅助类不是应用自定义的,这个就是合成类)。
// 一般应用程序定义的Bean都是返回false,由Spring合成的返回true。
// 下面代码:若取到的Bean是自定义的返回false,若是应用自己合成的返回true。
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 基于FactoryBean生成Bean(核心逻辑)
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
其中涉及如下处理:
-
BeanFactoryUtils.isFactoryDereference:判断name对应的目标类型;
-
getCachedObjectForFactoryBean:从BeanFactory缓存中获取指定名称的Bean实例对象;
-
getObjectFromFactoryBean:基于FactoryBean生成Bean
BeanFactoryUtils.isFactoryDereference
判断客户端想要的目标类型
// 判读name是否是FactoryBean对象
public static boolean isFactoryDereference(@Nullable String name) {
// FACTORY_BEAN_PREFIX开头说明是FactoryBean类型对象。
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
getCachedObjectForFactoryBean
从BeanFactory缓存中获取指定名称的Bean实例对象
// org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getCachedObjectForFactoryBean
// 缓存所有通过FactoryBean创建的Bean对象
// Key:Bean对象的名称
// Value:Bean对象实例
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
// 从FactoryBean缓存中获取指定名称的Bean对象
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}
getObjectFromFactoryBean
基于FactoryBean实例生成对应的普通Bean对象
// org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
// 基于FactoryBean实例生成对应的普通Bean对象
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// BeanFactory管理的是单例Bean,且一级缓存中已经包含对应beanName的实例对象。
if (factory.isSingleton() && containsSingleton(beanName)) {
// 多线程同步处理
synchronized (getSingletonMutex()) {
// 尝试直接从FactoryBean缓存中获取指定名称的Bean对象
Object object = this.factoryBeanObjectCache.get(beanName);
// 缓存中没有则生产该对象
if (object == null) {
// 通过调用FactoryBean获取对象的方法生成Bean对象
object = doGetObjectFromFactoryBean(factory, beanName);
// 有可能当执行doGetObjectFromFactoryBean函数时,别的线程已经正在创建Bean,所以再次从缓存中获取看看有没有其他线程创建的可用实例。
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 如果有值,代表已经经过后处理了,可以直接使用
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 没有经过后处理,首如果是用户自己创建的
if (shouldPostProcess) {
// 如果对象还在创建中,没有完成初始化设置,则返回Bean对象,但是不缓存他。
if (isSingletonCurrentlyInCreation(beanName)) {
return object;
}
// 单例Bean创建前回调处理,标记为创建中
beforeSingletonCreation(beanName);
try {
// 执行Bean创建逻辑的后处理逻辑
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// 单例Bean创建后回调处理,移除创建中状态
afterSingletonCreation(beanName);
}
}
// 如果是单例对象则添加到FactoryBean的缓存中。
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
// 非单例对象,直接创建Bean实例
else {
// 从FactoryBean中生成Bean对象
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
// 执行Bean创建的后置处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
1. doGetObjectFromFactoryBean通过FactoryBean获取管理的Bean对象实例
// org.springframework.beans.factory.support.FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
// 通过FactoryBean获取管理的Bean对象实例
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
// 调用factory::getObject,生成被管理的Bean对象
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 真正的获取bean实例对象的代码
// 里面使用动态代理Proxy.newProxyInstance来进行bean实例对象的获取
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// 创建出来实例对象为null,也可能因为Singleton对象正在创建而返回null
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
2. Bean创建状态管理
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation
// 单例对象创建前处理,将Bean加入到单例对象创建中的列表
protected void beforeSingletonCreation(String beanName) {
// this.inCreationCheckExclusions.contains(beanName):beanName不需要检查是否创建中状态,说明不用考虑指定Beanname的创建状态。
// this.singletonsCurrentlyInCreation.add(beanName):将beanName标记为正在创建中
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
// 单例对象创建后处理, 将Bean从单例对象创建中的列表移除
protected void afterSingletonCreation(String beanName) {
// this.inCreationCheckExclusions.contains(beanName):beanName不需要检查是否创建中状态,说明不用考虑指定Beanname的创建状态。
// this.singletonsCurrentlyInCreation.remove(beanName):将BeanName移除创建中状态
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
3. 执行Bean创建的后置处理器
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean
// 在完成Bean的初始化操作后,执行后置回调处理BeanPostProcessors。
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
// 调用BeanPostProcessor的回调方法,执行Bean初始化之后的操作。
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器。
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 调用Bean实例所有定义的BeanPostProcessor初始化之后回调操作,完成初始化后的自定义操作。
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
到此为止,前面是尝试从缓存中获取已经存在的Singleton Bean,如果不满足条件,下面的处理逻辑则尝试新建该Bean。
Pt3.5 检查容器中的BeanDefinition
如果没有从缓存中获取BeanInstance,则可能存在两种情况:
-
Bean非单例类型;
-
单例Bean还未开始创建过程。
这两种情况都是需要执行Bean的创建过程:
-
检查负责创建Bean的容器。因为指定名称的Bean可能不是在当前容器中,而是在父容器或者父容器的父容器中,则需要将创建Bean的工作交给具体归属的容器。
-
标记Bean的创建状态。防止多线程并发或者循环依赖时多次创建Bean。
-
获取MergedBeanDefinition。
检查负责创建Bean的容器。因为指定名称的Bean可能不是在当前容器中,而是在父容器或者父容器的父容器中,则需要将创建Bean的工作交给具体归属的容器。
// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
// 4、对IoC容器中是否存在指定名称的BeanDefinition进行检查。
// 首先检查是否能再当前容器中获取所需的Bean,如果不能则委托当前容器的父容器去查找,如果还是没有则一直沿着容器的继承体系继续查找下去。
BeanFactory parentBeanFactory = getParentBeanFactory();
// 当前容器中不存在指定名称的BeanDefinition,且当前容器存在父容器时
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 解析指定Bean名称的原始名称
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 通过父容器递归调用doGetBean获取对象实例
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// 委派父容器根据指定名称和参数进行查找
else if (args != null) {
// 通过父容器获取Bean实例
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
// 委派父容器根据指定名称和类型进行查找
else if (requiredType != null) {
// 通过父容器获取Bean实例
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
// 委派父容器根据指定名称进行查找
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
标记Bean的创建状态。防止多线程并发或者循环依赖时多次创建Bean。
// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
// 缓存已经至少完成一次实例化的Bean名称
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
// 如果当前容器中存在指定名称的BeanDefinition时,执行如下操作。
// 创建的Bean是否需要进行类型验证
if (!typeCheckOnly) {
// 5、向容器标记指定的Bean已经被创建。
markBeanAsCreated(beanName);
}
// 将指定名称bean标记为已创建
protected void markBeanAsCreated(String beanName) {
// 通过两次判断,既能够做到线程安全,又可以最大限度减少触发同步代码段执行锁,提升执行效率。
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
获取MergedBeanDefinition。
// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
// 根据指定Bean名称获取其父级Bean定义,主要解决Bean继承时子类和父类公共属性问题。
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
Pt3.6 检查DependsOn关系
分析的代码段:
// 6、 ,并完成关系注册和依赖Bean的实例化。 // DependsOn是@DependsOn注解所标注的,当前Bean必须等到所有DependsOn Bean全部初始化之后才能初始化。 String[] dependsOn = mbd.getDependsOn();
目标Bean初始化之前,可能存在依赖的Bean,那需要找到依赖的Bean先进行初始化,并且记录两个Bean的依赖关系。
// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
// 6、 ,并完成关系注册和依赖Bean的实例化。
// DependsOn是@DependsOn注解所标注的,当前Bean必须等到所有DependsOn Bean全部初始化之后才能初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 循环处理当前Bean依赖的Bean对象dep
for (String dep : dependsOn) {
// dependsOnBean也依赖beanName,出现循环依赖则报错,相当于死循环。
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册两个Bean之间的依赖关系:BeanName依赖dep
registerDependentBean(dep, beanName);
try {
// 先实例化当前Bean的@DependsOn所标注的Bean
// 递归调用getBean()获取当前Bean的 依赖Bean的 实例化对象。
// 此时,只完成依赖Bean的实例化,还没有真正完成依赖注入。
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
依赖关系判断:
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#isDependent(java.lang.String, java.lang.String)
// 指定的bean与目前已经注册的依赖这个指定的bean的所有bean的依赖关系的缓存(依赖我的)
// Key:当前Bean名称
// Value:依赖当前Bean的所有其他Bean名称集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
// 判断dependentBeanName是否依赖beanName
protected boolean isDependent(String beanName, String dependentBeanName) {
synchronized (this.dependentBeanMap) {
return isDependent(beanName, dependentBeanName, null);
}
}
注册两个Bean之间的依赖关系:
// 注册两个Bean之间的依赖关系
// beanName 被别人依赖的Bean名称
// dependentBeanName 依赖别人的Bean名称
public void registerDependentBean(String beanName, String dependentBeanName) {
// 获取beanName对应的被容器管理的名称
String canonicalName = canonicalName(beanName);
// 将dependentBeanName标记为是依赖beanName的关系
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
// 将beanName标记为是dependentBeanName依赖的关系
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
到此为止,Bean创建的准备工作已经完成了,下面执行具体的Bean创建操作。
Pt3.7 创建单例Bean对象
代码处理核心是createBean(),这部分逻辑非常复杂,后面会单独拿出来分析,这里主要是了解Singleton Bean的创建过程:
-
判断是否是Singleton Bean;
-
基于createBean逻辑生成BeanInstance;
-
getSingleton从缓存中获取创建的BeanInstance;
-
如果发生异常则需要销毁Singleton。因为Singleton Bean在容器中是共享的,没有被完整创建的Bean如果被其他线程拿去操作会出问题;
-
从BeanInstance获取目标Bean对象;
源码如下:
// 7、创建单例模式的Bean对象的场景。
if (mbd.isSingleton()) {
// 创建真正Bean实例对象
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建指定名称的Bean对象(核心逻辑)。
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 从IoC容器中清除单例模式的Bean对象
destroySingleton(beanName);
throw ex;
}
});
// 根据传参获取给定Bean的相关实例对象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
mbd.isSingleton():判断是否是单例Bean
没有指定scope或者scope=singleton时,当做单例Bean处理。
// org.springframework.beans.factory.support.AbstractBeanDefinition#isSingleton
public static final String SCOPE_DEFAULT = "";
@Override
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
}
createBean():创建Bean对象
后面会重点分析,这里只要知道createBean是完成创建Bean的核心逻辑。
getSingleton:获取Bean对象
// 从FactoryBean中获取普通Bean对象
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 1、先从一级缓存获取查找Bean对象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 容器正在销毁,异常情况
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 2、标记当前Bean正在创建中
beforeSingletonCreation(beanName);
// newSingleton为true,会将当前Bean加入缓存中
boolean newSingleton = false;
// 记录被抑制的异常信息
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 通过FactoryBean创建Bean对象
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 将Bean从单例对象创建中的列表移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 将完成实例化的Bean加入到缓存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
获取指定名称的Bean对象,同时将获取的Bean对象添加到缓存中(只有Singleton 类型)。
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
// 将完成实例化的单例Bean加入到缓存中
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 添加到一级缓存
this.singletonObjects.put(beanName, singletonObject);
// 从二级缓存和三级缓存移除
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// 添加到已注册的单例列表中
this.registeredSingletons.add(beanName);
}
}
getObjectForBeanInstance
getObjectForBeanInstance核心逻辑在[Pt3.4]中介绍过。
Pt3.8 创建原型Bean对象
原型Bean相对比单例要简单,不需要考虑缓存的问题,也是通过createBean完成Bean创建。
核心createBean会在后面介绍,getObjectForBeanInstance在[Pt3.4]已经介绍过。先来看看原型Bean创建过程:
// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
// 8、创建原型模式的Bean对象的场景。
else if (mbd.isPrototype()) {
// 原型模式每次都会创建一个新的对象
Object prototypeInstance = null;
try {
// 标记当前BeanName为创建中状态
beforePrototypeCreation(beanName);
// 创建指定Prototype类型Bean的实例对象
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 将当前beanName从创建中列表中移除
afterPrototypeCreation(beanName);
}
// 根据传参获取给定Bean的相关实例对象。
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// org.springframework.beans.factory.support.AbstractBeanFactory#beforePrototypeCreation
// 在Prototype类型Bean被创建前,将Bean标记为创建中
@SuppressWarnings("unchecked")
protected void beforePrototypeCreation(String beanName) {
// 标记当前BeanName正在被创建
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
// 将所有正在被创建的Prototype类型的BeanName拼接成Set对象缓存起来
else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
}
// 将当前beanName从创建中列表中移除
@SuppressWarnings("unchecked")
protected void afterPrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.remove();
}
else if (curVal instanceof Set) {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
}
Pt3.9 创建其他Scope类型Bean对象
和上面两个没有太大的区别,核心逻辑都是在createBean和getObjectForBeanInstance完成的。
// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
// 9、要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
// 获取配置的生命周期scope,选择实例化Bean的合适方法,这种方式在Web应用程序中比较常用,比如request、session、application等。
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
// 如果Bean定义资源中没有配置生命周期范围,则Bean定义不合法。
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 获取指定生命周期范围的Bean实例
Object scopedInstance = scope.get(beanName, () -> {
// 标记当前BeanName为创建中状态
beforePrototypeCreation(beanName);
try {
// 创建指定Bean的对象实例
return createBean(beanName, mbd, args);
}
finally {
// 将当前beanName从创建中列表中移除
afterPrototypeCreation(beanName);
}
});
// 获取指定Bean的实例对象
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
Pt3.10 Bean对象类型检查
创建流程的最后一步是对Bean对象的类型进行检查,比较简单。
// 10、对创建的Bean实例对象进行类型检查
// 指定的Bean类型不为空,且和当前获得的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.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
到此为止,整个Bean对象的创建过程(创建对象、填充属性和对象初始化)都已经完成了,且根据不同类型Scope都有针对性的处理。
接下来回过头,从createBean()中分析Bean对象创建的过程。
Pt4 Bean的创建流程
Pt4.1 Bean创建入口
Bean真正创建的入口是从createBean开始的,直接看源码吧,还是比较清晰的。
// DI的核心方法,完成Bean对象创建的整个流程,包括实例化、属性设置、初始化(#init),返回完成可以被使用的对象。
// String beanName:要创建的Bean名称
// RootBeanDefinition mbd:合并基类属性后的Bean定义信息
// @Nullable Object[] args:Bean初始化参数设置
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Debug日志处理,应用中可以参考这种模式,从而在异常时改变logger级别就可以输出更加详细的日志信息。
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
// mbd是合并了基类属性的完整BeanDefinition。
// mbdToUse克隆mbd,因为mbd是共享的合并基类信息的BeanDefinition,为了防止程序中存在动态解析改变了原有共享的BeanDefinition。
RootBeanDefinition mbdToUse = mbd;
// 1、解析获得Bean对应的BeanClass和BeanDefinition。
// BeanClass是在xml标签上定义<bean/>是标记的class属性,配置了类的包名和类名。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 2、验证以及准备BeanDefinition中需要覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 3、如果Bean配置了BeanPostProcessor处理器,则返回一个真实Bean对象的代理。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 4、创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
Pt4.2 获取BeanClass
从BeanDefinition中解析得到BeanClass。
// org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
// 为指定的BeanDefinition解析获得BeanClass,将获得的BeanClass解析为Class引用。
// BeanClass是在xml标签上定义<bean/>是标记的class属性,配置了类的包名和类名。
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
// BeanDefinition制定了BeanClass类型,则直接返回。
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
// 获取mbd配置的BeanClass,将BeanClass解析为Class对象,并将解析后的Class对象缓存在mdb中以备将来使用
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
// 获取mbd配置的BeanClass,将BeanClass解析为Class对象,并将解析后的Class对象缓存在mdb中以备将来使用
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
//获取该工厂的加载bean用的类加载器
ClassLoader beanClassLoader = getBeanClassLoader();
// 初始化动态类加载器为该工厂的加载bean用的类加载器,如果该工厂有临时类加载器器时,该动态类加载器就是该工厂的临时类加载器
ClassLoader dynamicLoader = beanClassLoader;
// 表示mdb的配置的bean类名需要重新被dynameicLoader加载的标记,默认不需要
boolean freshResolve = false;
//如果有传入要匹配的类型
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
String className = mbd.getBeanClassName();
if (className != null) {
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (dynamicLoader != null) {
try {
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
return ClassUtils.forName(className, dynamicLoader);
}
}
// Resolve regularly, caching the result in the BeanDefinition...
return mbd.resolveBeanClass(beanClassLoader);
}
Pt4.3 Override方法处理
mbdToUse.prepareMethodOverrides()
// org.springframework.beans.factory.support.AbstractBeanDefinition#prepareMethodOverrides
// 处理BeanDefinition中Override父类的方法。
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// BeanDefinition是否有Override父类的方法。
if (hasMethodOverrides()) {
// 循环处理所有的Override方法进行校验
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
// Override方法校验
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
// 方法不存在
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
// 方法只有一个实现
else if (count == 1) {
// Mark override as not overloaded, to avoid the overhead of arg type checking.
mo.setOverloaded(false);
}
}
Pt4.4 创建Bean对象
分析的代码段:
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
doCreateBean负责完成对象创建过程:
// 真正完成Bean对象创建的方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 1、创建BeanWrapper对象,用于封装被创建的Bean对象。
// BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。
BeanWrapper instanceWrapper = null;
// 2、如果是单例对象,先查看缓存中是否已经有初始化中的对象信息。
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 3、缓存没有数据,直接创建新的BeanWrapper实例
// 包装为BeanWrapper只是为了封装更多的信息,实际上这里的核心是利用带参或无参构造器创建Bean实例,这是Bean创建第一步。
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4、获取BeanWrapper中Bean的实例和BeanClass
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
// 如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 执行后置处理器BeanPostProcessor
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 5、添加Bean的三级缓存,用于处理循环依赖的场景。
// 如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。
// 这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean,getEarlyBeanReference可以对返回的bean进行修改。
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 需要注意的是,earlySingletonExposure为是在有循环依赖时为true,才会触发生成AOP代理类对象。如果没有循环依赖,或者不允许循环依赖时,
// 不会走到这里的逻辑,exposedObject还只是原生的Bean对象。所以AOP代理类会在两个时机触发:
// 1. 包含循环依赖时,会在Bean的构造器执行后触发;
// 2. 不包含循环依赖时,会在bean执行完创建流程后触发;
// 6、Bean的属性填充。
// 这是Bean对象实例化第二步,也是DI的核心。
Object exposedObject = bean;
try {
// 对Bean进行依赖注入
populateBean(beanName, mbd, instanceWrapper);
// 7、执行Bean对象的init方法,完成对象初始化。
// 这是Bean对象实例化第三步,也是最后一步,执行Bean的init方法。
// Bean实例对象依赖注入完成后,开始对Bean实例对象进行初始化(执行init方法),为Bean实例对象应用BeanPostProcessor后置回调处理
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 8、循环依赖校验
if (earlySingletonExposure) {
// earlySingletonReference 只有在检测到有循环依赖的情况下才会非空
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 如果exposedObject 没有在初始化方法中被改变,也就是没有被增强
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
// 检测依赖
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
// bean创建后其所依赖的bean一定是已经创建的,actualDependentBeans非空则表示当前bean创建后其依赖的bean却没有
// 全部创建完,也就是说存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 9、根据Scope注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
接下来具体分析里面的细节。
Pt4.5 缓存中获取BeanWrapper
首先还是要检查缓存中是否已经有创建好的BeanWrapper对象,如果有就不用重复创建了。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
// 1、创建BeanWrapper对象,用于封装被创建的Bean对象。
// BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。
BeanWrapper instanceWrapper = null;
// 2、如果是单例对象,先查看缓存中是否已经有初始化中的对象信息。
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
Pt4.6 构造器实例化Bean对象
如果缓存中没有BeanWrapper,则通过构造器执行创建Bean操作,并封装成BeanWrapper对象。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
// 3、缓存没有数据,直接创建新的BeanWrapper实例
// 包装为BeanWrapper只是为了封装更多的信息,实际上这里的核心是利用带参或无参构造器创建Bean实例,这是Bean创建第一步。
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4、获取BeanWrapper中Bean的实例和BeanClass
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
// 如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 执行后置处理器BeanPostProcessor
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
createBeanInstance就是通过执行构造器生成Bean的类对象:
// 创建Bean实例BeanWrapper。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 1、解析获取BeanClass,保证Bean已经真正被解析。
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 如果beanclass为空,且beanclass不是public 且没有权限访问构造函数和方法则抛出异常
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 2、从BeanSupplier中获取Bean对象,并封装成BeanWrapper。
// Supplier类似于factoryBean,从Supplier.get()获取bean的对象,并包装成BeanWrapper,然后初始化BeanWrapper。
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 3、如果工厂方法不为空,则通过工厂方法构建 bean 对象。
// 通常是在 xml 中配置 bean 的 factory-method的场景,例如:
// <bean id="staticStu" class="com.dragon.study.study20190618.spring.springFactoryMethod.StuFactory" factory-method="getStaticStu">
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 4、判断是否曾经解析过Bean的。
// 这里是一个shortcut,当重复构建同一个Bean时,可以复用此处的处理结果。
// resolved 和 mbd.constructorArgumentsResolved 将会在 bean 第一次实例化的过程中被设置
boolean resolved = false;// Bean是否已经被解析过
boolean autowireNecessary = false;// 如果autowireNecessary为true说明是采用构造器注入
// 传入参数为空,说明使用默认无参构造器
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 说明曾经解析过构造函数或者factoryMethod
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 说明mbd已经被解析过
resolved = true;
// 如果已经解析了构造方法的参数,则必须要通过一个带参构造方法来实例
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 5、如果Bean已经被解析过,则按照原有逻辑进行解析。
if (resolved) {
// 通过构造方法自动装配的方式构造 bean 对象
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
// 通过默认的无参构造方法进行
else {
return instantiateBean(beanName, mbd);
}
}
// 6、由后置处理器决定返回哪些构造方法, 当出现多个构造函数时, 返回为 null
// 到此处说明是第一次创建该bean,根据SmartInstantiationAwareBeanPostProcessor获取构造函数。
// 目前看基本上都是空的实现,除了AutowiredAnnotationBeanPostProcessor
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 需要对构造函数的参数进行注入, 可以通过 ImportBeanDefinitionRegistrar 来修改 bd 的自动装配模式:
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 使用默认的无参构造方法进行初始化
return instantiateBean(beanName, mbd);
}
// 从Supplier实例中获取Bean对象,并包装成BeanWrapper返回。
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
// 获得原当前线程正在创建的 Bean 的名称
String outerBean = this.currentlyCreatedBean.get();
// 设置当前线程正在创建的 Bean 的名称
this.currentlyCreatedBean.set(beanName);
try {
// 调用 Supplier 的 get(),获得Bean的实例对象
instance = instanceSupplier.get();
}
finally {
// 恢复原有值
if (outerBean != null) {
this.currentlyCreatedBean.set(outerBean);
}
else {
this.currentlyCreatedBean.remove();
}
}
if (instance == null) {
instance = new NullBean();
}
// 创建BeanWrapper,封装Bean对象
BeanWrapper bw = new BeanWrapperImpl(instance);
// 初始化BeanWrapper
initBeanWrapper(bw);
return bw;
}
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
instantiateBean是最常用的基于默认无参构造器的对象创建:
// 基于默认构造器创建Bean实例对象
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
Pt4.7 生成代理对象放入三级缓存
如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean,getEarlyBeanReference可以对返回的bean进行修改。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
private boolean allowCircularReferences = true;
// 5、添加Bean的三级缓存,用于处理循环依赖的场景。
// 如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。
// 这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean,getEarlyBeanReference可以对返回的bean进行修改。
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
getEarlyBeanReference判断是否需要生成AOP代理类:
/**
* 获取一个可以提前暴露的Bean对象,这里可能是原生bean对象,也可能是bean的代理类对象。
*
* @param beanName Bean对象名称
* @param mbd Bean对象定义(合并的)
* @param bean 原生的Bean对象
* @return 提前暴露的 包装了原生Bean对象 ObjectFactory对象
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
// 提前暴露(放入三级缓存)的对象exposedObject
Object exposedObject = bean;
// 如果有AOP配置,这里会生成Bean对象的AOP代理类对象,exposedObject = bean的AOP代理类对象
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
// 否则exposedObject只是原生的bean对象
return exposedObject;
}
添加到三级缓存:
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
// 缓存SingletonFactory信息
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 一级缓存不存在,说明没有被创建过
if (!this.singletonObjects.containsKey(beanName)) {
// 添加到三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 从二级缓存中移除
this.earlySingletonObjects.remove(beanName);
// 记录Bean注册顺序
this.registeredSingletons.add(beanName);
}
}
}
Pt4.8 属性填充
然后就是最重要的属性填充,构造Bean对象之间的相互依赖关系。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
// 对Bean进行依赖注入
populateBean(beanName, mbd, instanceWrapper);
// DI核心: 为生成的Bean对象设置属性值
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 1、如果BeanWrapper实例为空,但BeanDefinition中的属性不为空,则抛出异常。
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// 2、执行Bean后置处理器BeanPostProcessor。
// 根据InstantiationAwareBeanPostProcessor 判断是否继续给该bean配置属性
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
// 3、获取容器在解析Bean定义时获得的属性
// propertyValues存放的是Bean属性的名称以及对应的值,这里不会存放构造函数相关的参数值,只会存放通过setter注入的依赖。
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 4、根据自动注入的类型,查找属性对应的容器中对象。
// 如果对象不存在,则通过getBean创建对象。
// 自动注入的模式是按照名称或者按照类型
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 是否有后置处理器
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否需要执行依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// 属性填充:使用已经获取的属性值,填充BeanWrapper中定义的依赖属性。
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
根据类型完成属性的自动注入,如果依赖的对象未创建,则会触发对象创建的过程getBean()。
// 根据Name完成自动注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 当前Bean定义的属性中 非基本类型的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 处理属性对应的Bean实例
for (String propertyName : propertyNames) {
// 容器中是否存在属性名称对应的Bean定义
if (containsBean(propertyName)) {
// 获取属性名称对应的Bean对象,这里又会触发该对象的实例化过程
Object bean = getBean(propertyName);
// 已经获得属性对应的实例对象,后面主要看这个pvs怎么用
pvs.add(propertyName, bean);
// 注册Bean之间依赖关系
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
// 根据Type获取自动注入对象
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 当前Bean定义的属性中 非基本类型的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
applyPropertyValues将解析的属性填充信息注册到BeanWrapper中。
// 属性填充:使用已经获取的属性值,填充BeanWrapper中定义的依赖属性。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 解析获取的属性值为空,直接结束。
if (pvs.isEmpty()) {
return;
}
// 权限控制
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// mpvs已经完成解析,直接注入,在方法解析后会缓存已经解析的PropertyValue
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
// 属性注入BeanWrapper中的Bean对象的属性
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
// 获取Bean定义的属性列表
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
// TypeConverter用于类型转换。
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// BeanDefinitionValueResolver用于解析PropertyValue,如间接引用替换成直接对象
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
// 深拷贝的PropertyValue列表,用于存放完成解析的PropertyValue
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 逐个解析PropertyValue
for (PropertyValue pv : original) {
// 当前PropertyValue已经被解析,放入deepCopy
if (pv.isConverted()) {
deepCopy.add(pv);
}
// 否则,解析这个对象,然后再放入deepCopy
else {
String propertyName = pv.getName();// 属性的名称
Object originalValue = pv.getValue();// 属性未经类型转换的值
// AutowiredPropertyMarker.INSTANCE 类型表示使用 beanFactory#resolveDependency 进行依赖查找。
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 解析获取真正的对象
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 属性可写 && 不是嵌套(如foo.bar,java中用getFoo().getBar()表示)或者索引(如person.addresses[0])属性
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
// 用类型转换器进行转换
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// 缓存处理结果,后续可复用。
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
// 不缓存处理结果,每次都需要重新解析。
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
// 标记mpvs已经完成解析,后续可直接使用。
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
try {
// 将解析后的属性值放入BeanWrapper中
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
Pt4.9 执行init处理
执行Bean对象的init方法,完成对象初始化。这是Bean对象实例化第三步,也是最后一步,执行Bean的init方法。
Bean实例对象依赖注入完成后,开始对Bean实例对象进行初始化(执行init方法),为Bean实例对象应用BeanPostProcessor后置回调处理
// 初始化容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// JDK安全机制验证权限
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 为Bean实例对象包装相关属性:类名称、类加载器、所属容器等。
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 1、调用BeanPostProcessor的回调方法,执行Bean初始化之前的操作。
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 2、调用Bean的Init-Method方法,完成Bean的初始化操作。
// 这个Bean的初始化方法是在Spring Bean定义配置文件中通过init-method属性指定的。
// 这里不是新建Bean的实例操作,此时的Bean已经完成实例化处理,生成了Bean的实例对象,也完成了属性的设置。
// 如果Bean定义中配置了init-method,这里将执行该方法完成Bean配置中所有init动作。
invokeInitMethods(beanName, wrappedBean, mbd);
// 到此为止,Bean实例的初始化操作已经完成,创建了Bean对象,完成了属性的依赖注入,执行了自定义的init-method方法。
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 3、调用BeanPostProcessor的回调方法,执行Bean初始化之后的操作。
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
到此为止,就完成了对象创建的核心3个步骤:创建对象、填充属性和初始化方法。我们已经创建出完成的Bean对象,可以使用。
Pt4.10 循环依赖检查
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
// 8、循环依赖校验
if (earlySingletonExposure) {
// earlySingletonReference 只有在检测到有循环依赖的情况下才会非空
// getSingleton会将bean对象从三级缓存移动到二级缓存
Object earlySingletonReference = getSingleton(beanName, false);
在下面的代码,调用了getSingleton方法,这里会将Bean对象从二级缓存移动到一级缓存;
// 尝试从多级缓存中获取原生的单例Bean对象。
// allowEarlyReference:是否开启三级缓存
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1、尝试从一级缓存(已完成对象创建)获取singleton对象
Object singletonObject = this.singletonObjects.get(beanName);
// 2、单例对象创建中,但还未完成创建过程,尝试从二级缓存中获取对象。
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 3、如果一级缓存和二级缓存都没有,并且启用了三级缓存,则从三级缓存获取。
if (singletonObject == null && allowEarlyReference) {
// 再次尝试从一级缓存和二级缓存获取,防止并发的情况。
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 4、 尝试从三级缓存获取对象。
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 5、将对象从三级缓存移除,并加入到二级缓存中。
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
Pt4.11 添加到一级缓存
添加到一级缓存的对象,说明已经完成了整个对象创建过程,可以被应用程序所使用。
// 7、创建单例模式的Bean对象的场景。
if (mbd.isSingleton()) {
// 创建真正Bean实例对象
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 创建指定名称的Bean对象(核心逻辑)。
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException ex) {
// 从IoC容器中清除单例模式的Bean对象
AbstractBeanFactory.this.destroySingleton(beanName);
throw ex;
}
}
});
// 从FactoryBean中获取普通Bean对象
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 1、先从一级缓存获取查找Bean对象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 容器正在销毁,异常情况
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 2、标记当前Bean正在创建中
beforeSingletonCreation(beanName);
// newSingleton为true,会将当前Bean加入缓存中
boolean newSingleton = false;
// 记录被抑制的异常信息
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 通过FactoryBean创建Bean对象
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 将Bean从单例对象创建中的列表移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 将完成实例化的Bean加入到缓存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
添加到一级缓存
// 将完成实例化的单例Bean加入到缓存中
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 添加到一级缓存
this.singletonObjects.put(beanName, singletonObject);
// 从二级缓存和三级缓存移除
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// 添加到已注册的单例列表中
this.registeredSingletons.add(beanName);
}
}
从现在起,Bean就是一个完整的、可以被应用程序使用的Bean对象。
Pt4.12 获取Bean对象
实际上,这里还有一步,就是获取已经生成的Bean对象来使用。这就是Pt3.4部分的内容:从FactoryBean中获取Bean对象。
Pt5 源码分析
Pt5.1 单例模式双重检查
下面是我写得一个简单的代理对象,不知道大家看下来有没有什么问题。
public class Singleton {
private static Singleton singleton = null;
private Singleton(){}
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
// TODO:单例创建过程逻辑
}
}
return singleton;
}
}
私有化属性和构造器,通过getInstance()暴露对象的获取路径,通过synchronized保证只有一个线程可以执行singleton初始化过程,好像没什么问题。
其实核心是TODO的部分,每次调用getInstance都有锁竞争,并发性能大大降低。
那怎么改?
非常简单,冗余一个判断。
public class Singleton {
private static Singleton singleton = null;
private Singleton(){}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
// TODO:单例创建过程逻辑
}
}
}
return singleton;
}
}
两次判空处理if (singleton == null),简单高效的提升了并发的性能。此类写法在Spring源码中大量存在,用来提升多线程并发的性能。
参考资料
参考学习资料和相关文章列表,请参照如下链接:
https://blog.csdn.net/moonlight821/article/details/116463513