spring bean的生命周期
spring bean的生命周期
大致流程
SpringBean创建大致流程:
1: 扫描指定包下面的Java类。
2: 根据Java类构建beanDefinition对象。
3: 据beanDefinition来创建Spring Bean。
即: 普通java类 ----> BeanDefinition ----> spring bean
BeanDefinition和Spring Bean
Bean中解析存储了额外的信息。
内容 | 描述 |
---|---|
Bean 的 Class 名称或类型 | 指定 Bean 使用的类名或接口类型 |
Bean 的作用域 | 定义 Bean 的作用域范围,如 singleton、prototype 等 |
是否是抽象的 Bean | 标识是否是抽象 Bean,不能直接实例化 |
是否是懒加载的 Bean | 指示是否延迟加载 Bean 的实例 |
Bean 的依赖信息 | 声明 Bean 的依赖关系,指定依赖的其他 Bean |
Bean 的初始化方法 | 指定 Bean 实例化后调用的初始化方法 |
Bean 的销毁方法 | 指定 Bean 销毁时调用的方法 |
是否是单例 Bean | 标识 Bean 是否是单例,即全局共享的 Bean |
是否是原型 Bean | 标识 Bean 是否是原型,每次请求都会创建一个新实例 |
Bean 的构造函数参数值 | 指定 Bean 实例化时传入构造函数的参数值 |
Bean 的属性值 | 指定 Bean 的属性值,可以在实例化后设置给 Bean 的属性 |
Bean 的自动装配模式 | 指定 Bean 的自动装配方式,如 byName、byType、constructor 等 |
Bean 的 FactoryBean 的名称 | 如果 Bean 是通过 FactoryBean 创建的,指定 FactoryBean 的名称 |
Bean 的延迟初始化设置 | 指定 Bean 是否延迟初始化 |
Bean 的描述信息 | 为 Bean 提供描述信息 |
refresh方法解析类、实例化Bean:
其核心逻辑如下:
- 调用预先刷新处理器(preRefresh): 在刷新之前,调用预先刷新处理器,允许应用程序在容器刷新之前执行特定的操作。
- 初始化 Bean 工厂: 如果上下文尚未初始化,将会初始化 Bean 工厂(
BeanFactory
)。这包括对 BeanDefinition 的加载和注册,但不会实例化 Bean。 - 准备 Bean 工厂: 对 Bean 工厂进行必要的准备工作,包括设置类加载器、属性编辑器等。
- 后处理 Bean 工厂: 调用 Bean 工厂后处理器(
BeanFactoryPostProcessor
),允许修改 Bean 工厂的配置。 - 注册 Bean Post Processors: 注册 Bean 后处理器(
BeanPostProcessor
),用于在 Bean 实例化和初始化过程中提供扩展点。 - 初始化消息源: 如果上下文支持国际化,将会初始化消息源,以便进行消息资源的处理。
- 初始化事件广播器: 初始化 Spring 事件发布机制,以支持应用程序内部事件的广播。
- 初始化其他特殊 Bean: 执行特殊的 Bean 初始化,如对事件监听器、定时任务等的处理。
- 注册监听器: 注册监听器以响应上下文中发生的事件。
- 实例化非懒加载的单例 Bean: 实例化所有非懒加载的单例 Bean,并初始化它们。
- 初始化剩余的单例 Bean: 初始化剩余的单例 Bean,包括懒加载的单例 Bean。
- 发布上下文刷新事件: 发布上下文刷新事件,通知其他组件上下文已经刷新完成。
- 调用后处理器完成刷新: 调用 Bean 工厂后处理器的
finishRefresh()
方法,完成刷新过程。 - 结束刷新过程: 结束刷新过程,应用程序上下文现在处于活动状态,可以处理客户端请求。
refresh()
方法是 Spring 应用程序上下文刷新的关键方法,涵盖了整个上下文初始化和准备的过程,确保应用程序上下文处于可用状态。
finishBeanFactoryInitialization是完成非懒加载的Spring bean的创建的工作,Spring Bean的生命周期有8个后置处理的方法4个后置处理器的类贯穿在对象的实例化、赋值、初始化、和销毁的过程中,这4个后置处理器出现的地方分别为:
BeanPostProcessor
核心的接口类型:
- SmartInstantiationAwareBeanPostProcessor
- MergedBeanDefinitionPostProcessor
- InstantiationAwareBeanPostProcessor
- BeanPostProcessor
- DestructionAwareBeanPostProcessor
每个 BeanPostProcessor 回调方法的作用:
- 实例化前。InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation如果该方法返回值不为null,不会执行后面的步骤,直接返回该对象。即:不在执行bean生命周期的构造器初始化、属性填充、初始化操作。
- 推断构造。SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors,如果返回值不为null,就会使用返回的构造器进行实例化。
- 合并beanDefinition。MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition预处理@PostConstruct、@PreDestroy、@Autowired、@Value字段信息。这里可以拿到BeanDefinition。
- 提前AOP :SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference提前暴露ObjectFactory到三级缓存。
- 实例化后。InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation可以拿到初始化后的对象。
- 属性注入。InstantiationAwareBeanPostProcessor#postProcessProperties。
- 初始化前。BeanPostProcessor#postProcessBeforeInitialization此时的bean已经完成了属性注入、Aware注入,还未执行初始化方法InitializingBean#afterPropertiesSet。
- 初始化后。BeanPostProcessor#postProcessAfterInitialization这是bean生命周期的最后一个环节了,此时完成 初始化方法的回调。afterPropertiesSet。
- 销毁bean的回调。DestructionAwareBeanPostProcessor#requiresDestruction。
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
总结
refresh
refresh方法是核心,总体分为几个步骤:
- 初始化beanFactory。
- 执行beanFactory的后置处理器,这一步会扫描bean定义。
- 注册bean的后置处理器。
- 初始化事件发布机制。
- 初始化特殊的bean(事件监听器、定时任务等)。
- 注册监听器。
- 初始化单例bean。
Bean初始化四个阶段
1: 实例化 Instantiation
2: 属性赋值 Populate
3: 初始化 Initialization
4: 销毁 Destruction
四个Bean后置处理器,八个回调(作用于所有Bean)
1: BeanPostProcessor
bean初始化前:postProcessBeforeInitialization
bean初始化后:postProcessAfterInitialization
2: InstantiationAwareBeanPostProcessor
bean实例化前:postProcessBeforeInstantiation
bean实例化后:postProcessAfterInstantiation
bean属性设置前:postProcessProperties
3: MergedBeanDefinitionPostProcessor
bean属性设置前:postProcessMergedBeanDefinition 合并bean定义、预处理@PostConstruct、@PreDestroy、@Autowired、@Value字段信息
4: SmartInstantiationAwareBeanPostProcessor
bean实例化前:determineCandidateConstructors 推断构造器
获取用于早期访问指定 Bean 的引用,通常用于解析循环引用:getEarlyBeanReference
创建代理对象
四处地方可以将对象加工厂代理对象:
- SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
- InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
- BeanPostProcessor#postProcessBeforeInitialization
- BeanPostProcessor#postProcessAfterInitialization
Aware接口(作用于特定类型的Bean)
初始化前:AbstractAutowireCapableBeanFactory#invokeInitMethods
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
初始化前:ApplicationContextAwareProcessor#postProcessBeforeInitialization
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
bean instanceof ApplicationStartupAware)) {
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
refresh:容器刷新#AbstractApplicationContext
- 这个方注是 spring 最重要的一个方法,甚至体现整个 IOC 的声明周期
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
/**
* 准备刷新上下文环境
* 1. 初始化{@link AbstractApplicationContext#environment}属性、设置属性、校验是否存在必要属性
* 2. 初始化事件监听器
* 3. 创建一个容器用于保存早期待发布的事件集合
*/
prepareRefresh();
/**
* 获取刷新bean工厂(这其实是一个模板方法,固定会执行子类的 refreshBeanFactory() 和 getBeanFactory() )
* - xml加载 spring会在这里加载 beanDefinition
* - javaConfig加载 只是刷新bean工厂,加载beanDefinition 是通过
* @see org.springframework.context.annotation.ConfigurationClassPostProcessor
*
* 这里会判断能否刷新,并且返回一个 BeanFactory,刷新不代表完全情况,主要是先执行Bean的销毁,然后重新生成一个BeanFactory
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/**
* 准备 BeanFactory(对 bean 工厂进行属性填充)
* 1. 设置 BeanFactory的类加载器、 SpringEL表达式解析器、类型转化注册器
* 2. 添加三个 BeanPostProcessor,注意是具体的 BeanPostBeanPostProcessor实例对象Processor实例对象
* 3. 记录 ignoreDependencyInterface
* 4. 记录 ResolvableDependency
* 5. 添加四个单例Bean
*/
prepareBeanFactory(beanFactory);
try {
// 4. 留给子类实现该接口(允许在上下文子类中对 bean 工厂进行后期处理)
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
/**
* 执行 bean 工厂的后置处理器。作用:修改BeanDefinition 或者 加载BeanDefinition
*
* 总体流程:
* 1. 先执行 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
* 2. 在执行BeanFactoryPostProcessor#postProcessBeanFactory(可以通过这个实现bean创建的优先级)
* @see cn.haitaoss.javaconfig.beanfactorypostprocessor.MyBeanFactoryPostProcessor2
* 注:
* 1. BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子接口
* 2. 执行是有序的可以通过:实现PriorityOrdered、实现Ordered、使用@Order
* 排序逻辑是这两个类实现的:
* @see org.springframework.core.OrderComparator
* @see AnnotationAwareOrderComparator (这个是OrderComparator 增强版 可以解析:Ordered、@Order)
*
* AnnotationConfigApplicationContext 的细节 (默认情况下):
* 此时 beanFactory的 beanDefinitionMap中有5个 BeanDefinition,4个基础BeanDefinition + AppConfig的BeanDefinition
* 而这5个中只有一个 BeanFactoryPostProcessor: ConfigurationClassPostProcessor
* 这里会执行 ConfigurationClassPostProcessor进行 @Component的扫描,扫描得到 BeanDefinition,并注册到 beanFactory
* 注意:扫描的过程中可能又会扫描出其他的 BeanFactoryPostProcessor,那么这些 BeanFactoryPostProcessor 也会被执行(使用while循环做兜底操作)
*/
invokeBeanFactoryPostProcessors(beanFactory);
/**
* 调用我们bean的后置处理器
* 将扫描到的 BeanPostProcessors实例化并排序,并添加到 BeanFactory的 beanPostProcessors属性中去
*/
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 设置 ApplicationContext的 MessageSource,要么是用户设置的,要么是 DelegatingMessageSource(初始化国际化资源处理器)
initMessageSource();
/**
* 创建事件多播器
* 设置 ApplicationContext的 applicationEventMulticaster,要么是用户设置的(注入name:applicationEventMulticaster 的bean),要么是默认值 SimpleApplicationEventMulticaster
*/
initApplicationEventMulticaster();
// 给子类的模板方法(springboot 是从这个方法启动 tomcat的)
onRefresh();
/**
* 把我们的事件监听器注册到 多播器上
* 把定义的 ApplicationListener的Bean对象,设置到 ApplicationContext中去,并执行在此之前所发布的事件
*
* 注意:
* - ApplicationListener 只是定义在 ApplicationEventMulticaster 中,并没有实例化,实例化是 待事件发布的时候才会实例化(或者在单例bean 的时候实例化)
* @see SimpleApplicationEventMulticaster#multicastEvent(ApplicationEvent, ResolvableType)
* - 这是是最早发布事件的地方,但是默认实现中没有提供发布早期事件的方式(可以下方demo的方式来发布早期事件 来实现一些骚操作)
* @see cn.haitaoss.javaconfig.applicationlistener.MyAnnotationConfigApplicationContext#onRefresh()
*/
registerListeners();
/**
* 完成bean工厂初始化
* 初始化单实例bean,在这里面体现了 bean 的声明周期(实例化、初始化、初始化后等)
*/
finishBeanFactoryInitialization(beanFactory);
// 最后容器刷新 发布刷新事件(Spring Cloud 也是从这里启动的)
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn(
"Exception encountered during context initialization - " + "cancelling refresh attempt: "
+ ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
/**
* 完成此上下文的 Bean 工厂的初始化,
* 初始化所有剩余的单例 bean。
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
/**
* 为BeanFactory设置ConversionService。
* 在依赖注入时,要对注入值进行类型转换会使用这个东西
* */
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)
&& beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
/**
* BeanFactory 没有设置嵌入值解析器,那就设置一个默认的,特点是可以访问 Environment 中加载的所有属性
*
* 比如 当我们使用 <context:property-placeholder/> 时,会设置 嵌入值解析器,看这里就知道了
* {@link PropertySourcesPlaceholderConfigurer#postProcessBeanFactory(ConfigurableListableBeanFactory)}
*
* 如果没有 BeanFactoryPostProcessor,则注册默认的嵌入值解析程序
* (例如 PropertySourcesPlaceholderConfigurer bean)之前注册的任何:
* 此时,主要用于解决注记属性值。
* */
if (!beanFactory.hasEmbeddedValueResolver()) {
/**
* 在依赖注入的时候,解析 @Value("") 时,会使用这个解析字符串,
* 所以 @Value("${name}") 的方式引用IOC容器中的属性
*
* {@link DefaultListableBeanFactory#doResolveDependency(DependencyDescriptor, String, Set, TypeConverter)}
* {@link AbstractBeanFactory#resolveEmbeddedValue(String)}
* */
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
/**
* 优先实例化 LoadTimeWeaverAware 类型的bean,从而可以更早的注册 Transformer,
* 从而保证后续 Xx.class 的加载能被拦截到
* */
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// 实例化所有剩余(非懒加载)单例bean
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons:提前实例化单例Bean#DefaultListableBeanFactory
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 获取我们容器中所有bean定义的名称
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 循环我们所有的bean定义名称
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 合并我们的bean定义: 合并父子类的beanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
/**
* 根据bean定义判断 不是抽象的 && 是单例的 && 不是懒加载的
*/
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是不是工厂bean
if (isFactoryBean(beanName)) {
/**
* FactoryBean :
* 1. 会创建两个bean。FactoryBean本身 和 getObject() 返回的值。
* 2. getObject() 返回的bean,不是在单例bean创建的时候创建的,是在获取的时候才会生成 context.getBean("myFactoryBean")
*
* 使用场景:需要所有的bean都创建了,在创建 就可以使用 FactoryBean
* 注:如果需要在 单例bean 创建阶段 就创建好两个Bean,可以使用 SmartFactoryBean
*
* context.getBean("myFactoryBean") 会发生什么:
* 1. 会先从缓存里面获取
* @see org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getCachedObjectForFactoryBean(java.lang.String)
* 2. 获取不到就执行 org.springframework.beans.factory.FactoryBean#getObject() 实例化bean,然后放入 cachedObjectForFactoryBean 缓存
* @see FactoryBeanRegistrySupport#doGetObjectFromFactoryBean(FactoryBean, String)
*
* context.getBean("&myFactoryBean") 会发生什么:
* 满足下面的条件,所以直接返回 单例池 里面的bean
* @see BeanFactoryUtils#isFactoryDereference(String)
*/
// 是 factoryBean,会先生成实际的bean &beanName是用来获取实际bean的
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean
&& ((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// Factory 允许提前创建, 就会创建 FactoryBean#getObject
getBean(beanName);
}
}
} else {
// 非工厂Bean就是普通的bean
getBean(beanName);
}
}
}
// 到这里所有的单实例的bean已经加载到单例池(singletonObjects)中了
// 遍历bean的名字,回调满足条件的单例bean
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
// 从单例缓存池中获取所有的对象
Object singletonInstance = getSingleton(beanName);
// 判断当前的bean是否实现了 SmartInitializingSingleton 接口
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup()
.start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
合并bean定义
元信息之所以需要做合并,就是因为Java的继承,子类的Bean在进行装配之前,必须把其父类的元信息合并到当前子类当中。
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null || mbd.stale) {
previous = mbd;
// 没有父类 直接返回
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
// 有父类 把父类的所有属性全部合并到字类
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
} else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
} else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName
+ "': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
处理工厂Bean
DefaultListableBeanFactory:
if (isFactoryBean(beanName)) {
/**
* FactoryBean :
* 1. 会创建两个bean。FactoryBean本身 和 getObject() 返回的值。
* 2. getObject() 返回的bean,不是在单例bean创建的时候创建的,是在获取的时候才会生成 context.getBean("myFactoryBean")
*
* 使用场景:需要所有的bean都创建了,在创建 就可以使用 FactoryBean
* 注:如果需要在 单例bean 创建阶段 就创建好两个Bean,可以使用 SmartFactoryBean
*
* context.getBean("myFactoryBean") 会发生什么:
* 1. 会先从缓存里面获取
* @see org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getCachedObjectForFactoryBean(java.lang.String)
* 2. 获取不到就执行 org.springframework.beans.factory.FactoryBean#getObject() 实例化bean,然后放入 cachedObjectForFactoryBean 缓存
* @see FactoryBeanRegistrySupport#doGetObjectFromFactoryBean(FactoryBean, String)
*
* context.getBean("&myFactoryBean") 会发生什么:
* 满足下面的条件,所以直接返回 单例池 里面的bean
* @see BeanFactoryUtils#isFactoryDereference(String)
*/
// 是 factoryBean,会先生成实际的bean &beanName是用来获取实际bean的
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean
&& ((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// Factory 允许提前创建, 就会创建 FactoryBean#getObject
getBean(beanName);
}
}
}
处理非工厂Bean
DefaultListableBeanFactory:
else {
// 非工厂Bean就是普通的bean
getBean(beanName);
}
回调SmartInitializingSingleton#afterSingletonsInstantiated
// 到这里所有的单实例的bean已经加载到单例池(singletonObjects)中了
// 遍历bean的名字,回调满足条件的单例bean
for (String beanName : beanNames) {
// 从单例缓存池中获取所有的对象
Object singletonInstance = getSingleton(beanName);
// 判断当前的bean是否实现了 SmartInitializingSingleton 接口
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup()
.start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
doGetBean:获取Bean#AbstractBeanFactory
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
/**
* 在这里传入进来的name可能是别名,也有可能是工厂bean的name,所以在这里需要转换
*/
String beanName = transformedBeanName(name);
Object beanInstance;
// 尝试去三个缓存中获取对象,这里面实现了 循环依赖问题的解决方案
Object sharedInstance = getSingleton(beanName);
// 能从单例池中获取bean
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
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 + "'");
}
}
/**
* 下面方法的三种执行情况:
* 1. isFactoryDereference: getBean($myFactoryBean) 直接返回
* 2. !(beanInstance instanceof FactoryBean):直接返回
* 3. factoryBean getBean(myFactoryBean) :
* - 从 cachedObjectForFactoryBean 获取得到就返回
* - 使用 FactoryBean#getObject() 返回的对象,存到缓存,然后返回该对象
* */
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
/**
* spring只能解决单例对象的循环依赖,不能解决多例bean和scope bean的循环依赖
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
/**
* 判断 AbstractBeanFactory工厂是否有父工厂(一般情况下是没有父工厂因为 abstractBeanFactory 直接是抽象类,不存在 父类实现)
* 一般情况下,只有 Spring和 SpringMVC整合的时才会有父子容器的概念,
* 比如我们的 Controller中注入 service的时候,发现我们依赖的是一个引用对象,那么他就会调用 getBean 去获取 service
* 但是当前所在的容器是web子容器,那么就会在这里的先去父容器找
* */
BeanFactory parentBeanFactory = getParentBeanFactory();
// 若存在父工厂,且当前的bean工厂不存在当前的bean定义,那么bean定义可能是存在于父 beanFactory中
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 获取bean的原始名称
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
// 若为 AbstractBeanFactory类型,委托父类处理
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
// 委托给构造函数 getBean() 处理
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
// 有args,委托给标准的 getBean)处理
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
/**
* 方法参数 typeCheckOnly,是用来判断调用 #getBean(...) 方法时,表示是否为仅仅进行类型检查获取Bean对象
* 如果不是仅仅做类型检育,而是创建Bean对象,则需要调用 #markBeanAsCreated(String beanName)方法,进行记录
* this.alreadyCreated.add(beanName);
* */
if (!typeCheckOnly) {
// 标记这个bean已经创建了,在后面会有用
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
/**
* 从容器中获取 beanName相应的 GenericBeanDefinition对象,并将其转换为 RootBeanDefinition对象
* <bean id="parentComponent" class="cn.haitaoss.xml.TestXml" abstract="true"/>
* <bean id="songComponent" class="cn.haitaoss.xml.TestXml" parent="parentComponent"/>
* */
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查当前创建的bean定义是不是抽象的bean定义
checkMergedBeanDefinition(mbd, beanName, args);
/**
* 处理 dependsOn的依赖(这个不是我们所调的循环依赖而是bean创建前后的依赖)
@Component public class Test1 {}
@Component
@DependsOn("test1") class Test2 {}
* */
// Guarantee initialization of beans that the current bean depends on.
// 依赖bean 的名称
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
/**
* A 依赖了 B,B 依赖了 A 即循环依赖的情况,抛出 BeanCreationException异常
* 比如:
* @Component
* @DependsOn({"b1"})
* class A1 {}
*
* @Component
* @DependsOn({"a1"})
* class b1 {
*
* }
*/
for (String dep : dependsOn) {
// beanName是当前正在创建的bean,dep是正在创建的bean 依赖的bean的名称
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
/**
* 保存的是 bean 和 依赖beanName之间的映射关系
* 被依赖bean:依赖beanList
*
* 依赖bean:被依赖beanList
* */
registerDependentBean(dep, beanName);
try {
// 取 dependOn的bean,从这里体现出 依赖bean 会先创建
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 创建单例bean
// Create bean instance.
if (mbd.isSingleton()) {
// 把 beanName和一个 singletonFactory并且传入一个回调对象用于回调
sharedInstance = getSingleton(beanName, () -> {
try {
// 进入创建bean的逻辑
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// 创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
/**
* 记录创建的多例bean,用于检查多例bean的循环依赖问题。存到这里面,说明这个bean不支持循环依赖。因为上面
* 有校验代码
* */
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
// 移除记录
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
/**
* 同上
* */
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = 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();
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
createBean:创建bean#AbstractAutowireCapableBeanFactory
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd,
@Nullable Object[] args) throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
/**
* 确保此时的bean已经被解析了
* 如果获取的 class属性不为null,则克隆该 BeanDefinition
* 主要是因为该动态解析的 class无法保存到到共享的 BeanDefinition
* */
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
/**
* 验证和准备覆盖方法
* lookup-method 和 replace-method
* 这两个配置存放在 BeanDefinition中的 methodOverrides,
* 我们知道在bean实例化的过程中如果检测到存在 methodOverrides,
* 则会动态地为当前 bean 生成代理并使用对应的栏截器为 bean 做增强处理。
* 具体的实现我们后续分析,现在先看 mbdToUse.prepareMethodOverrides() 代码块
*
* */
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(
mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex);
}
try {
/**
* 实例化前后置处理器
* */
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 {
/**
* 该步骤是我们真正的创建我们的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);
}
}
实例化前处理
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 判断容器中是否有 InstantiationAwareBeanPostProcessors
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 获取当前bean的 class对象
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
/**
*
* 后置处理器的【第二次】,实例化前
* */
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 说明生成了代理对象那么我们就调用
if (bean != null) {
/**
* 返回值不会空,执行初始化后后置处理器,因为这个bean已经算是创建完了,在执行初始化后 就ok了
* */
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
/**
* 返回值不是null,说明不需要执行后面的 推断构造器、属性填充、初始化等操作。
* 也就是bean已经创建好了,可以直接返回了
* */
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/**
* 【很重要】
* 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
* 我们事务注解 @EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
* 都是实现了我们的 BeanPostProcessor 的子接口 InstantiationAwareBeanPostProcessor,
* 进行后置处理解析切面
*
* */
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
真正的创建Bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd,
@Nullable Object[] args) throws BeanCreationException {
// BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 从没有完成的 FactoryBean中移除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/**
* 创建bean实例
* 推断构造器
* 创建bean实例化使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化。
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 从 beanWrapper中获取我们的早期对象
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
/**
* 后置处理器的【第四次】MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
* 进行后置处理 @Autowired @Value的注解的预解析
*/
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex
);
}
mbd.postProcessed = true;
}
}
/**
* 该对象进行判断是否能够暴露早期对象的条件
* 单实例 this.allowCircularReferences 默认为true
* isSingletonCurrentlyInCreation(表示当前的bean对象正在创建singletonsCurrentlyInCreation包含当前正在创建的bean)
* 举例:
* class A { B b;}
* class B { A a;}
* 先实例化A --> singletonsCurrentlyInCreation = {A}
* 依赖注入B --> singletonsCurrentlyInCreation = {A,B}
* 依赖注入A --> singletonsCurrentlyInCreation = {A,B} ==> 发现 isSingletonCurrentlyInCreation(a) 满足条件,所以应该暴露A到三级缓存
*
* singletonsCurrentlyInCreation 是在单例bean 创建之前就设置的
* @see org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation(java.lang.String)
* */
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");
}
/**
* 循环依赖-添加到三级缓存中
* 把我们的早期对象包装成一个 singletonFactory 对象,该对象提供了一个 getObject方法,该方法内部调用 getEarlyBeanReference(beanName, mbd, bean)
* 实现提前AOP
* */
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
// 填充bean,就是依赖注入或者给属性设置值
populateBean(beanName, mbd, instanceWrapper); // getBean()
// 进行对象初始化操作(在这里可能生成代理对象)
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);
}
}
/**
* 这里是为了处理二级缓存中的bean 和 执行了初始化操作的 bean 不一致的校验,不一致说明可能存在
* 依赖注入的bean 和 实际存入单例池中的bean 不一致的问题。对于不一致,下面的处理是报错
*
*
* 比如 A 注入了 B,B 注入了 A
* 先是 getBean(A),然后其 populateBean 环节要注入B, 所以会 getBean(B),然后其 populateBean 环节要注入A,所以要 getBean(A)
* 此时发现A正在创建,所以会读取三级缓存的value,然后执行提前AOP得到一个 proxyBeanA ,并将 proxyBeanA 存入二级缓存,然后将 proxyBeanA 注入到 B中,
* 然后B就创建完了,然后B就会被注入到A中,所以A的 populateBean 结束了,然后会执行 initializeBean。假设在 initializeBean 生成了 proxyBeanA2 。
* 这就出现了 注入到B中的A,和实际最终生成的A不一致的问题,对于这中情况,只能直接报错了,下面的逻辑就是为了应付这种情况的,
*
* 注:当然 提前AOP 也不一定会创建代理对象,我这里只是举例了 提前AOP和初始化都创建了代理对象的场景,方便说明
*
* */
if (earlySingletonExposure) {
/**
* 去缓存中获取到我们的对象,由于传递的 allowEarlyReference 是false要求只能在一级二级缓存中去获取。
* 说白了,就尝试从二级缓存中获取bean。
*
* 注:在这里就能体会到三级缓存的好处了。因为这里是只会从一级缓存和二级缓存中获取内容(其实只可能从二级缓存中拿到,一级缓存是拿不到的,因为此时还未将单例bean存入一级缓存)
* 如果二级缓存拿到的值不为null,就校验一下 exposedObject(执行了初始化后置处理器返回的值) 和 bean(简单实例化出来的) 是否一致,
* 若不一致,就需要判断一下,这个bean是否注入给了其他bean对象,若注入给了其他bean对象,那么就只能报错了,因为已经注入给了其他bean的值 和 exposedObject 不一致。
*
* 假设我们采用二级缓存来解决循环依赖的问题。思路如下:
* 一级缓存用来缓存最终完全的bean,二级缓存一开始存入的是 ObjectFactory ,当出现了循环依赖时,读取二级缓存的值,然后回调方法 ObjectFactory#getObject 得到 提前AOP的bean。
* 将 提前AOP的bean 存入进二级缓存,也就是进行值覆盖。
*
* 一级缓存:< beanName,最终的bean >
* 二级缓存:< beanName, ObjectFactory 或者 提前AOP得到的bean >
*
* 这就会出现一个问题,很难确定二级缓存存储得值 是 ObjectFactory 还是 提前AOP得到的bean,
* 你可能会这么想 `earlySingletonReference instanceof ObjectFactory` 来检验,但这是不靠谱的,因为有可能bean的类型就是 ObjectFactory 的
* 所以呢,只能使用东西标记二级缓存的值 是 ObjectFactory 还是 提前AOP得到的bean,
* 比如 这么设计: ThreadLocal< beanName, boolean > earlyLocal : false 表示二级缓存的值是 ObjectFactory,true 表示二级缓存的值是 提前AOP得到的bean
*
* 那么下面的 判断逻辑应当改成 ` if ( earlySingletonReference != null && earlyLocal.get().get(beanName) )
*
* 所以呢肯定是需要使用东西来标记一下,是否执行了 ObjectFactory 得到 提前AOP得到的bean,Spring是采用的三级缓存来标记,
* 这就是为啥使用三级缓存
*
* */
Object earlySingletonReference = getSingleton(beanName, false);
/**
* 能够获取到,说明是在二级缓存拿到的。也就是这个 beanName 产生了循环依赖的问题,
* */
if (earlySingletonReference != null) {
/**
* 相等,说明初始化操作并没有对bean进行代理,那就没事。二级缓存的值作为最后要存入单例池中的值
* 不相等,说明对bean进行了代理。这就会导致循环依赖了bean的那些东西,注入的bean是不对的,我们需要判断一下
* 那些东西是否已经创建完了,创建完,那就没得搞了,只能报错了。
*/
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
/**
* hasDependentBean(beanName) 说明,这个bean已经注入到其他的bean对象中
* */
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
/**
* 获取依赖了 beanName 的bean。其实就是获取哪些bean注入了 beanName这个bean
*
* 在依赖注入时会记录,比如@Resource的注入逻辑 {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#autowireResource(BeanFactory, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.LookupElement, String)}
* */
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
/**
* 尝试挽救一下,如果 dependentBean 还没有创建完成,那就没问题了
*
* 创建完成的标记,是在这个地方设置的,也就是在 doGetBean 的一开始就设置了
* {@link AbstractBeanFactory#doGetBean(String, Class, Object[], boolean)}
* {@link AbstractBeanFactory#markBeanAsCreated(String)}
* */
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
/**
* 已经创建完了,就记录一下。
* */
actualDependentBeans.add(dependentBean);
}
}
// 报错
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 {
/**
* 注册一次性bean 的销毁接口
* */
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
创建bean实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 从bean定义中解析出当前bean的 class对象
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
/**
* 检测类的访问权限。默认情况下,对于非 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()
);
}
/**
* 该方法是 spring5.0 新增加的如果存在 Supplier回调,则使用给定的回调方法初始化策略
* */
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
/**
* 注:会导致@Lookup和replaced-method失效
* */
return obtainFromSupplier(instanceSupplier, beanName);
}
/**
*
* 工厂方法,我们通过配置类来进行配置的话采用的就是工厂方法,方法名称就是 user2 就是我们工厂方法的名称
* @Bean
* public User user2() {
* return new User();
* }
* */
if (mbd.getFactoryMethodName() != null) {
/**
* 就是先创建工厂bean `getBean(factoryBeanName)`
* 在通过实例化策略 实例化当前bean {@link InstantiationStrategy#instantiate(RootBeanDefinition, String, BeanFactory, Object, Method, Object...)}
* 这个策略很简单,直接反射调用 @Bean标注的方法而已。
*
* 注:会导致@Lookup和replaced-method失效
* */
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
/**
* 当多次构建同一个bean时,可以使用此处的快捷路径,即无需再次推断应该使用哪种方式构造实例,
* 以提高效率。比如在多次构建同一个 prototype 类型的bean时,就可以走此处的捷径。
* 这里的 resolved 和 mbd.constructorArgumentsResolved 将会在bean第一次实例
* 化的过程中被设置,在后面的源码中会分析到,先继续往下看。
* */
// 判断当前构造函数是否被解析过
// Shortcut when re-creating the same bean...
boolean resolved = false;
// 有没有必须进行依赖注入
boolean autowireNecessary = false;
/**
* 通过 getBean传入进来的构造函数是否来指定需要推断构造函数
* 若传递进来的args不为空,那么就可以直接选出对应的构造函数
* */
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 判断我们的bean定义信息中的 resolvedConstructorOrFactoryMethod(用来缓存我们的已经解析的构造函数或者工厂)
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 修改已经解析过的构造函数的标志
resolved = true;
// 修改标记为true标识构造函数或者工厂方法已经解析过
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 若被解析过
if (resolved) {
if (autowireNecessary) {
// 通过有参的构造函数进行反射调用
return autowireConstructor(beanName, mbd, null, null);
} else {
/**
* 会判断是否使用Cglib创建代理对象,还是反射进行实例化。
* 主要是根据这个属性是否有值{@link org.springframework.beans.factory.support.AbstractBeanDefinition#methodOverrides}来判断的。
* 而这个属性是在解析@Lookup注解或者replaced-method replaced-method 设置的:
* - @Lookup {@link AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors(Class, String)}
* - replaced-method {@link org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseReplacedMethodSubElements}
* */
return instantiateBean(beanName, mbd);
}
}
/**
* 通过bean的后置处理器进行选举出合适的构造函数对象
* */
// 自动布线的候选构造函数?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/**
* 如果自定义了 beanPostProcessor返回了构造器 或者
* 使用构造器自动装配模式 或者
* 没置了构造器参数 或者
* 有参数 或者
* 则使用自定义的构造器初始化
* */
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(
args)) {
// 通过构造函数创建对象
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
/**
* 会判断是否使用Cglib创建代理对象,还是反射进行实例化。
* 主要是根据这个属性是否有值{@link org.springframework.beans.factory.support.AbstractBeanDefinition#methodOverrides}来判断的。
* 而这个属性是在解析@Lookup注解或者replaced-method replaced-method 设置的:
* - @Lookup {@link AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors(Class, String)}
* - replaced-method {@link org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseReplacedMethodSubElements}
* */
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
推断构造函数
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass,
String beanName) throws BeansException {
// beanClass对象不为空且ioc容器中有 InstantiationAwareBeanPostProcessors 的后置处理器
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
/**
* 后置处理器的【第三次】遍历 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
*/
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
// 调用我们后置处理器的 determineCandidateConstructors 来决定我们的构造方法
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
}
@Autowired @Value的注解的预解析
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
提前暴露对象到三级缓存
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
// 同步加锁
synchronized (this.singletonObjects) {
// 单例缓存池中没有包含当前的bean
if (!this.singletonObjects.containsKey(beanName)) {
// 加入到三级缓存中,,,,,暴露早期对象的创建方式,用于解决循环依赖
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
属性填充
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 若bw为nul1的话,则说明对象没有实例化
if (bw == null) {
if (mbd.hasPropertyValues()) {
// 进入if 说明对象有属性,bw为空,不能为他设置属性,那就在下面就执行抛出异常
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
// Skip property population phase for null instance.
return;
}
}
/**
* 在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改
* bean状态的机会。官方的解释是:让用户可以自定义属性注入。比如用户实现一
* 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
* postProcessAfterInstantiation 方法向bean的成员变量注入自定义的信息
* 当时我们发现系统中的的 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 没有进行任何处理
* 若我们自己实现了这个接口可以自定义处理.... spring留给我们自已扩展接口的
* 特殊需求,直接使用配置中的信息注入即可
* */
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/**
* 后置处理器的【第五次】InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
* @see cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(Object, String)
*
* 若存在后置处理器给我们属性赋值了,那么返回fale可以来修改我们的开关变量,就不会走下面的逻辑了
* */
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
/**
* 返回值为是否继续填充bean
* postProcessAfterInstantiation:如果应该在bean上面设置属性则返回true,否则返回 false
* 一般情况下,应该是返回true。
* 返回 false的话,将会阻止在此Bean实例上调用任何后续的 InstantiationAwareBeanPostProcessor
*/
return;
}
}
}
// 获取bean定义的属性
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
/**
* 判断我们的bean的属性注入模型
* AUTOWIRE_BY_NAME 根据名称注入
* AUTOWIRE_BY_TYPE 根据类型注入
*
* 可以这样子指定:@Bean(autowire = Autowire.BY_NAME)
* */
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// 把 PropertyValues 封装成为 MutablePropertyValues
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据bean的属性名称注入
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
/**
* 这里主要是会判断 有没有 {@link BeanWrapper#getPropertyDescriptor(String)} 是要给 {@link AbstractAutowireCapableBeanFactory#ignoredDependencyInterfaces}
* 的接口方法设置值的,排除掉这些 PropertyDescriptor。
* */
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据bean的类型进行注入
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
/**
* 这里主要是会判断 有没有 {@link BeanWrapper#getPropertyDescriptor(String)} 是要给 {@link AbstractAutowireCapableBeanFactory#ignoredDependencyInterfaces}
* 的接口方法设置值的,排除掉这些 PropertyDescriptor。
* */
autowireByType(beanName, mbd, bw, newPvs);
}
// 把处理过的属性覆盖原来的
pvs = newPvs;
}
/**
* 这里又是一种后置处理,用于在 Spring 填充属性到bean对象前,对属性的值进行相应的处理
* 比如可以修改某些属性的值。这时注入到bean中的值就不是配置文件中的内容了,
* 而是经过后置处理器修改后的内容
* */
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 判断是否需要检查依赖
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
// 退出当前正在创建的 beanWrapper依赖的对象
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/**
* 后置处理器的【第六次】InstantiationAwareBeanPostProcessor#postProcessProperties
* 进行字段和方法的依赖注入{@link cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor#postProcessProperties(PropertyValues, Object, String)}
*/
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
/**
* 后置处理器的【第七次】cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor#postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String)
* 过时方法了,不建议使用
* @see cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor#postProcessPropertyValues(PropertyValues, Object, String)
*/
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);
}
/**
* 其实,上面只是完成了所有注入属性的获取,将获取的属性封装在 PropertyValues的实例对象pvs中,
* 并没有应用到已经实例化的bean中。而
* @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.BeanWrapper, org.springframework.beans.PropertyValues)
* 则是完成这一步骤的
* */
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
初始化bean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 若我们的bean实现了 XXXAware接口进行方法的回调
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用我们bean的后置处理器的 postProcessBeforeInitialization 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null), beanName,
"Invocation of init method failed", ex
);
}
// 初始化后
if (mbd == null || !mbd.isSynthetic()) {
// 调用我们bean的后置处理器的 PostProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
执行Aware方法
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
初始化前处理
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean,
String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/**
* 后置处理器的【第八次】BeanPostProcessor#postProcessBeforeInitialization
* 调用我们的bean的后置处理器的 BeanPostProcessor#postProcessBeforeInitialization @PostConstruct 注解的方法
* @see cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization(Object, String)
* */
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 若有一个返回nul1那么直接返回 上一个
if (current == null) {
return result;
}
result = current;
}
return result;
}
init方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
// 判断是否实现了 InitializingBean 接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
// 回调 InitializingBean#afterPropertiesSet() 方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
/**
* 我们 beanClass 中看是否有自已定义的init方法
* <bean id="testInit" class="cn.haitaoss.xml.TestXml" init-method="myInit"/>
*/
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(
initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
初始化后处理
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean,
String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/**
* 在这里是后置处理器的【第九次调用】
* 后置处理器的【第九次】BeanPostProcessor#postProcessAfterInitialization
* AOP 和 事务 都会在这里生存代理对象
*
* 【很重要】
* 我们 AOP @EnableAspectJAutoProxy 为我们容器中导入ア AnnotationAwareAspectJAutoProxyCreator
* 我们事务注解 @EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
* 都是实现了我们的 BeanPostProcessor 接口的子接口 InstantiationAwareBeanPostProcessor
* 在这里实现的是 BeanPostProcessor接口的 postProcessAfterInitialization 来生成我们的代理对象
* @see cn.haitaoss.javaconfig.beanpostprocessor.MyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization(Object, String)
* */
Object current = processor.postProcessAfterInitialization(result, beanName);
// 若只有有一个返回null 那么直接上一个 result
if (current == null) {
return result;
}
result = current;
}
return result;
}
判断bean与二级缓存中的bean是否一致
注册销毁接口
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
/**
* 不是原型bean 且 有符合的DestructionAwareBeanPostProcessor {@link DestructionAwareBeanPostProcessor#requiresDestruction(Object)}
* */
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// 是单例的
if (mbd.isSingleton()) {
/**
* 就是存到这个属性中 {@link DefaultSingletonBeanRegistry#disposableBeans}
* */
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
} else {
// scope 的
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
/**
* 就是存到这个属性中 {@link DefaultSingletonBeanRegistry#disposableBeans}
* */
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
}
}
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean.getClass() != NullBean.class && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (
hasDestructionAwareBeanPostProcessors()
&& DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessorCache().destructionAware))));
}
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}