前言
Spring-Bean的实例化是发生在BeanFactory
的getBean
的方法中。其主要实现是在其子类AbstractBeanFactory
的doGetBean
方法中。
可以说,Spring中所有的对象都是通过这个方法实例化的。
doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 该方法作用:1、 如果是FactoryBean,会去掉Bean开头的&符号
// 2、能存在传入别名且别名存在多重映射的情况,这里会返回最终的名字,如存在多层别名映射A->B->C->D,传入D,最终会返回A
final String beanName = transformedBeanName(name);
Object bean;
//这里先尝试从缓存中获取,若获取不到,就走下面的创建
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 这里虽然只是一句日志,但是能说明用意。
// 若条件为true,表示这个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 + "'");
}
}
// 在getBean方法中,getObjectForBeanInstance是个频繁使用的方法。因此为了更好的知道细节,下面会详解这个方法的
// 其实简单理解就是处理FactoryBean的getObject()方法
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 原型对象不允许循环创建,如果是原型对象正在创建,那就抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 这一步也是必须要做的,若存在父容器,得看看父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准)
// 这就是为何,我们扫描controller,哪怕不加排除什么的,也不会出问题的原因~,因为Spring中的单例Bean只会被实例化一次(即使父子容器都扫描了)
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 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 {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 保证当前bean所依赖的bean的初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 从这里开始,就正式开始着手创建这个Bean的实例了~~~~
if (mbd.isSingleton()) {
// 也是一样先尝试从缓存去获取,获取失败就通过ObjectFactory的createBean方法创建
// 这个getSingleton方法和上面是重载方法,它支持通过ObjectFactory去根据Scope来创建对象,具体源码解析见下面
sharedInstance = getSingleton(beanName, () -> {
try {
// 这是创建Bean的核心方法,非常重要~~~~~~~~~~~~~~~下面会有
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 执行失败,就销毁Bean。然后执行对应的destroy方法,等等销毁Bean时候的生命周期方法们
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//。。。。。。。。
}
过程:
1、如果springBean名字以&符号开头,那么spring会将其去掉
2、判断当前单例bean是否在当前容器的单例池中。
3、如果不存在,在判断其父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准)
3、如果其父容器没有实例化过它,先判断其是否是单例或者是原型对象。在调用相应的createBean
方法创建bean对象
初始化单个单例bean的核心步骤
AbstractAutowireCapableBeanFactory的createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
//.......
try {
// 容器里所有的InstantiationAwareBeanPostProcessors实例,都会在此处生效,进行前置处理~~~~~~~~~~
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
//.......
try {
//执行bean的后置处理器和初始化方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//.......
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 然后,唯一能改变它的值的地方,是下面这仅仅一行代码而已,它的访问权限为package
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 这里hasInstantiationAwareBeanPostProcessors()方法就是看属性hasInstantiationAwareBeanPostProcessors的值。就是标记容器里是否有InstantiationAwareBeanPostProcessor的实现
// 显然,在执行addBeanPostProcessor,发现这个Bean是这个子类型的时候,就会设为true了。同理的还有hasDestructionAwareBeanPostProcessors这个属性,表示销毁的处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 拿到最终的目标类型(放置被别的包装过)显然此处是;com.fsx.service.HelloServiceImpl
// 可能依赖于AbstractBeanFactory#resolveBeanClass这个方法去解析
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 先执行执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回调方法
// 里面的逻辑也比较简单:拿到缓存好的(List装着的)所有的BeanPostProcessors,如果是InstantiationAwareBeanPostProcessor就执行吧~~
// 只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要)
//1、ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor这个内部类就是这个类型。主要还是去增强、完善处理@Configuration这种类 但是它并没有重写postProcessBeforeInstantiation这个方法,所以默认是返回null的
//2、CommonAnnotationBeanPostProcessor/Autowired。。。也没做处理(若你自己不去注册,那系统里就再没有了)
// 需要注意的是,如果我们采用了AOP、声明式事务等等,这里就会有了,后面又会回来讲解这一块
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 我们可以看到,如果bean为null,那就直接返回了 短路掉后面的After也就不执行了
if (bean != null) {
// 注意,这里是Initialization,是初始化的后置方法,是BeanPostProcessor的方法,也就是说初始化完成后的方法。
// 为何这里执行这个方法呢?是因为我们上面说了,如果返回不为null,后面都都会被短路掉。但是此处Spring还是让我们执行了初始化后的处理器方法,这点需要引起注意
// 就是说:即使Bean在实例化前已经返回了一个不为null的对象,别的方法都被短路了,但是我的【初始化】后处理器方法applyBeanPostProcessorsAfterInitializationh还是可以执行的
// 这里面可以关注一下这个类:ApplicationListenerDetector
//初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了==============
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
过程:
1、先执行InstantiationAwareBeanPostProcessor的applyBeanPostProcessorsBeforeInstantiation方法
2、如果applyBeanPostProcessorsBeforeInstantiation方法返会值不为null,就执行其applyBeanPostProcessorsAfterInitialization方法。
注意:一般情况下,这个方法返回值一定是null,除非我们要进行代理
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 用BeanWrapper来持有创建出来的Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果是单例的话,则先把缓存中的同名bean清除(同名的)
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//实际创建的交给createBeanInstance来完成,
//bean的生成,这里会使用默认的类生成器,包装成BeanWrapperImpl类,为了下面的populateBean方法的属性注入做准备
if (instanceWrapper == null) {
//调用构造器
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
//如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 此处处理这个接口的处理器:MergedBeanDefinitionPostProcessor,他在BeanPostProcessor的基础上增加了postProcessMergedBeanDefinition方法,在此处就被调用了
// 主要是处理@PostConstruct,@Autowire,@Value,@Resource,@PreDestory等这些注解。(显然对应哪去处理器,一目了然了)
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
//如果当前bean是单例,且支持循环依赖,且当前bean正在创建,通过往singletonFactories添加一个objectFactory,这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean
//getEarlyBeanReference可以对返回的bean进行修改,这边目前除了可能会返回动态代理对象 其他的都是直接返回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");
}
// 这里面主要是解决循环引用问题~~~~~~~~~借助了这个工厂
//这里主要是调用处理器:SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法去寻找到前期的Bean们(若存在这种处理器的话)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 这个Obj,就是最终要返回的对象了
Object exposedObject = bean;
try {
// 这又是非常非常重要的一步:给已经初始化的属性们赋值===================对bean进行填充,在这里面完成依赖注入的相关内容
// 啥都不说了,看下面的详解吧
populateBean(beanName, mbd, instanceWrapper);
//完成属性依赖注入后,进一步初始化Bean 具体进行了以下操作:
//若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
//遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
//如果实现了initialzingBean,调用实现的 afterPropertiesSet()
//如果配置了init-mothod,调用相应的init方法
//遍历后置处理器,调用实现的postProcessAfterInitialization
// 关于populateBean和initializeBean的详解,下贴出了博文链接参考~~~~~~
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);
}
}
//如果earlySingletonExposure为true,尝试从缓存获取该bean(一般存放在singletonFactories对象通过调用getObject 把对象存入earlySingletonObjects),
// 分别从singletonObjects和earlySingletonObjects获取对象 这里依然是处理循环依赖相关问题的
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//如果获取到对象了
if (exposedObject == bean) {
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);
}
}
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 如果有需要,就注册DisposableBean,这样Bean销毁的时候此种后置处理器也会生效了
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
Spring-Bean实例化生命周期宏观说明
注意:此处的Spring-Bean指的是我们自己创建的非后置器的单例Spring-Bean对象。
1、执行InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
方法 (其返回值为空)
2、执行Bean的构造器
3、执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
4、执行InstantiationAwareBeanPostProcessor
的postProcessAfterInitialization
方法
5、执行InstantiationAwareBeanPostProcessor
的postProcessProperties
方法
6、执行InstantiationAwareBeanPostProcessor
的postProcessPropertyValues
方法
7:执行BeanNameAware
的setBeanName
方法
8:执行BeanClassLoaderAware
的setBeanClassLoader
方法
9:执行BeanFactoryAware
的setBeanFactory
方法
10: 执行后置处理器BeanPostProcessor
的postProcessBeforeInitialization(Object bean, String beanName)
方法
11: 调用InitializingBean
接口初始化 (如果配置了method-init
,则调用其方法初始化 )
12: 执行后置处理器BeanPostProcessor
的postProcessAfterInitialization
方法
补充说明:在步骤1中如果 如果其返回值不是空,就会执行其postProcessAfterInitialization方法,如果postProcessAfterInitialization返回还不为null,那么下面的步骤就不会调用
完成此上下文bean工厂的初始化
AbstractApplicationContext
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//初始化此上下文的转换服务。
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));
}
//如果没有bean后处理器,则注册默认的嵌入式值解析器
//(例如PropertyPlaceholderConfigurer bean)在以下任何时间之前注册:
//此时,主要用于注释属性值中的分辨率。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
//尽早初始化LoadTimeWeaverAware bean,以便尽早注册其转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
//停止使用临时类加载器进行类型匹配。
beanFactory.setTempClassLoader(null);
//允许缓存所有bean定义元数据,不需要进一步更改。
beanFactory.freezeConfiguration();
//实例化所有剩余的(非延迟初始化)单例。
beanFactory.preInstantiateSingletons();
}
初始化所有剩余的单例bean
DefaultListableBeanFactory的preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
//获取所有springbean的名字
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 所有非惰性单例bean的触发器初始化。。。
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是FactoryBean方式创建的bean,进入这里
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final 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) {
getBean(beanName);
}
}
}
else {
//如果不是FactoryBean方式创建的bean,进入这里
getBean(beanName);
}
}
}
//为所有适用的bean触发初始化后回调。。。
for (String beanName : beanNames) {
//注意回调只针对单利对象
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
过程:
1、获取所有springBean的名字
2、实例化所有非惰性单例bean,底层主要方法是getBean(beanName)
,而getBean底层又是doGetBean
()方法
3、当所有非惰性单例bean实例化后,触发回调接口SmartInitializingSingleton
的afterSingletonsInstantiated
方法。
SmartInitializingSingleton
的作用:因为其方法afterSingletonsInstantiated
是所有非惰性单例bean实例化后调用的,所有我们可以利用他获取所有的非惰性单例bean对象
@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {
@Autowired
private DefaultListableBeanFactory defaultListableBeanFactory;
@Override
public void afterSingletonsInstantiated() {
System.out.println("OK.........");
Iterator<String> beanNamesIterator = defaultListableBeanFactory.getBeanNamesIterator();
while (beanNamesIterator.hasNext()){
System.out.println(beanNamesIterator.next());
}
}
}
SmartInitializingSingleton对象的创建时机和普通的非惰性单例bean一样