在经过扫描操作获取到可用的 BeanDefinition 集后,接下来会进行实例化前的操作:将单例且非懒加载的BeanDefinition进行实例化放入单例池中。
下面是Bean的生命周期表,而接下来要源码分析的阶段是扫描完得到BeanDefinition后进行单例非懒加载Bean的处理,即对应着 DefaultListableBeanFactory 下的 preInstantiateSingletons()
方法。
在扫描注册BeanDefinition时,除了把BeanDefinition注册到beanDefinitionMap
中,还把beanName放入了beanDefinitionNames
集合中。
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 获取合并后的BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 若该Bean是单例且不是懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 获取FactoryBean对象
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) {
// 创建真正的Bean对象(getObject()返回的对象)
getBean(beanName);
}
}
}
else {
// 创建Bean对象
getBean(beanName);
}
}
}
// 所有的非懒加载单例Bean都创建完了后
// Trigger post-initialization callback for all applicable beans...
// 所有非懒加载单例Bean创建完后的后置处理 SmartInitializingSingleton
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
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();
}
}
}
它是一个重载方法,其中 preInstantiateSingletons() 方法中调用的是下面这个:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
mergedBeanDefinitions.put(beanName, mbd);
放入到 mergedBeanDefinitions 缓存中。FactoryBean 示例:
@Component
public class MyFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return null;
}
}
isFactoryBean(String name) 源码分析:
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
// 首先从单例池中获取,判断单例池是否存在
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found -> check bean definition.
// 线工厂没这个Bean,父工厂判断一手
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// 判断是否实现了 FactoryBean 接口
// 然后以BeanDefinition 的 isFactoryBean 作为标志
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
transformedBeanName 源码分析:
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;
});
}
transformedBeanName 把 name 转换成普通的 beanName,即若有 FACTORY_BEAN_PREFIX
& 前缀的话,就把 & 去掉,比如 &xxx 转换成 xxx,&&&&xxx 转换成 xxx。
在获取 bean 的时候也是通过 FACTORY_BEAN_PREFIX
把 bean 分为 FactoryBean 和普通 Bean 两种。
那接下来看看 FactoryBean 是怎么获取到其对应 Bean 的呢?
下面对 getObjectForBeanInstance 方法进行源码分析:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 如果&xxx,那么就直接返回单例池中的对象
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 单例池中的对象不是FactoryBean,则直接返回
// 即就是一普通对象了
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
// 从factoryBeanObjectCache中直接拿对象
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
// synthetic为true,表示这个Bean不是正常的一个Bean,可能只是起到辅助作用的,所以这种Bean就不用去执行PostProcessor了
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 调用 FactoryBean.getObject 方法去获取对应的 Object
// 然后放入factoryBeanObjectCache缓存中
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
FACTORY_BEAN_PREFIX
前缀,判断是否需要返回 FactoryBean,如果是直接返回;factoryBeanObjectCache
缓存中。测试:
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext
context = new AnnotationConfigApplicationContext();
context.register(AppConfig.class);
context.refresh();
System.out.println(context.getBean("user", User.class));// com.powernode.User@61ca2dfa
System.out.println(context.getBean("myFactoryBean"));// com.powernode.User@4b53f538
System.out.println(context.getBean("&&&&myFactoryBean"));// com.powernode.MyFactoryBean@4b53f538
}
}
若想提前放入 factoryBeanObjectCache 缓存中,可以实现 SmartFactoryBean
接口,然后重写 isEagerInit() 若返回的是 true,即会提前调用 getBean(beanName) ,这样就放入缓存了,下次取就直接走缓存了,不会去调用 getObject 方法了。
上面有提到从单例池中获取到了对于bean的情况下进行的处理,若单例池中没有这个Bean呢?它是如何创建并放入到单例池的呢?接下来源码分析对应的逻辑:
在 getBean 中,首先是从单例池去获取对应的 Bean,若获取不到则会去尝试创建,去获取的操作上述阐述了,这里阐述一下创建的逻辑,其实现都归于 doGetBean 方法。
下面是其核心代码(含注释分析):
/**
这里只是 else 的逻辑,就是获取对应bean的时候,在单例池中找不着,需要去尝试创建的代码
**/
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 这里是去排除循环引用
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 尝试先让父 BeanFactory 去 getBean 获取对应的 Bean
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// &&&&xxx---->&xxx
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);
}
// 接下来是去操作 @DependsOn 注解的关系
// 这里是强依赖关系,若是使用@DependsOn注解产生了循环依赖的话,那是无法解决的
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查BeanDefinition是不是Abstract的
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了
for (String dep : dependsOn) {
// beanName是不是被dep依赖了,如果是则出现了循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value
registerDependentBean(dep, beanName);
// 创建所依赖的bean
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 根据 Scope 的类型去创建 Bean
if (mbd.isSingleton()) {
// getSingleton 方法很简单,就是将 Lambda 返回的bean放入到单例池中
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {// 如果是多例的话就直接创建一个Bean返回,没有后续操作
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 这个是处理其他 Scope 的,如 web 中的 request、session、application
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 { // session.getAttriute(beaName) setAttri
// 这实现很简单,就是通过 Lambda 那个返回的bean,将其创建后放到对应作用域
// 如果作用域本身就有这个 bean 的话就直接返回
// 达到web作用域的bean单一的效果
// 即通过 setAttribute和getAttribute进行实现的
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();
}
在创建 Bean 时,会对不同Bean的作用域进行逻辑处理,不同作用域的创建形式有一定的差异,在配置 Bean 的作用域的时候,除了可以配置 singleton和 protocol,还可以配置适用 Web(MVC)的Bean 的作用域,如 request(RequestScope),session(SessionScope),application(ApplicationScope)
,这些作用域。
阐述了半天,不管是哪种作用域,其核心都是要创建出bean,而创建的逻辑都归功于 createBean
方法。现对其进行源码分析:
@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;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 马上就要实例化Bean了,确保beanClass被加载了
// 加载beanClass,从而得到对应的 Class 对象
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 方法覆盖,和 @Lookup 注解有一定的关系
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.
// 实例化前
// InstantiationAwareBeanPostProcessor
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);
}
}
下面是实例化前的代码截取出来:
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 实例化前
// InstantiationAwareBeanPostProcessor
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
那下面对 resolveBeforeInstantiation 方法进行分析:
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // 如果之前没有被实例化过的话
// Make sure bean class is actually resolved at this point.
// synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // BeanPostProcessorCache 中的 instantiationAware 不能为空
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
这里涉及到一种 BeanPostProcessor,在 BeanPostProcessor 接口中定义了初始化前和初始化后的功能,那么它有一些子类,在这俩功能上提供了其他功能,这里涉及到 InstantiationAwareBeanPostPostProcessor
,它在初始化前和初始化后的功能之后还提供了实例化前和实例化后功能。
在 Spring 加载的过程中会把所有的BeanPostProcessor放入到 beanPostProcessors
集合中。
然后调用 AbstractBeanFactory#getBeanPostProcessorCache
方法后会将其进行分类,然后封装成 BeanPostProcessorCache 实例。
分成这四类不同的后置处理器都有对应的用法,在 Bean 生命周期的不同阶段会进行调用。
BeanPostProcessorCache 内部实现很简单,就是各个BeanPostProcessor的集合,AbstractBeanFactory 中的一个静态类:
把流程解读一遍:
判断是否是合成的且存在 instantiationAware;
然后遍历处理这些后置处理器:
若是实例化前返回了 Bean 则处理实例化后的后置处理器,处理完把Bean给返回。
虽然 Spring 提供了这个实例化前的可控操作,但是在实际运用中好像没啥软用。
BeanFactory#getBean
@DependsOn
注解引起的依赖,提前getBean()所依赖的;createBean
方法.createBean 方法对应流程如下: