上一篇Spring启动流程(二)之Spring加载Bean Definition的流程主要分析了如何从xml配置中读取Bean的配置,然后加载生成对应的Bean Definition。
主要代码为:
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
obtainFreshBeanFactory()最终返回一个存放了Bean Definition信息的Bean工厂——DefaultListableBeanFactory。
后面的几步,也都是往DefaultListableBeanFactory里加东西,让它可扩展。(如何做到可扩展可单独成篇叙述)
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
到这一步,准备工作做完了,扩展也设置好了,真正的开始实例化Bean对象了:
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
Spring默认创建的实例是单例的,代码从AbstractBeanFactory.doGetBean()开始,下面是部分代码
// Create bean instance.
if (mbd.isSingleton()) {
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;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
上面代码看createBean方法,这个方法是AbstractAutowireCapableBeanFactory中的。
看createBean的方法注释
Central method of this class: creates a bean instance,populates the bean instance, applies post-processors
可以知道,这个方法的核心方法是:创建bean实例、填充bean 实例(填充实例内部引用的其他实例)、应用扩展方法
createBean内部:
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
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 {
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);
}
上面代码是createBean的部分内容。忽略try catch,
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
上面这行是调用初始化前的扩展点。
接着看doCreateBean方法,方法注释为
Actually create the specified bean. Pre-creation processing has already happened at this point, e.g. checking postProcessBeforeInstantiation callbacks.
Differentiates between default bean instantiation, use of a factory method, and autowiring a constructor.
这里说bean实例开始真正创建了,==||
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
查看createBeanInstance方法签名和注释
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
Create a new instance for the specified bean, using an appropriate instantiation strategy: factory method, constructor autowiring, or simple instantiation.
可知,这里面做的应该就是创建bean实例的勾当了吧?!
而且这里说明了有三种初始化策略:使用工厂方法实例化、使用构造方法实例化、简单初始化(默认构造函数)。
涉及到的类和接口如下图:
最终会使用反射API来初始化或者CglibAPI来创建子类然后初始化
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
// Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
如何决定使用哪种方式来实例化呢?可以看看SimpleInstantiationStrategy类中的instantiate方法。
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
Bean definition中没有overrides的方法,就会使用反射API,否则使用CGLIB 的API。
不管是使用上面哪种策略,最终产生的实例是一个BeanWrapper。一个用来包装Bean实例的对象。
为什么要包装一下呢?
继续看看获取到BeanWrapper后Spring做的事情。
再回到AbstractAutowireCapableBeanFactory的doCreateBean方法
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
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方法上面已经分析过了,会通过反射或者Cgilib创建子类实例化一个BeanWrapper返回。
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
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);
}
}
populateBean方法开始填充我们刚刚生成的BeanWrapper实例的属性值。
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
上面的代码会将By Name和By Type注入的属性给newPvs——MutablePropertyValues类型。
populateBean最后执行applyPropertyValues方法
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
applyPropertyValues关键代码如下:
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
上面的setPropertyValues内部会循环调用setPropertyValue,即遍历属性,逐个拷贝。
@Override
public void setPropertyValue(PropertyValue pv) throws BeansException {
PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
if (tokens == null) {
String propertyName = pv.getName();
AbstractNestablePropertyAccessor nestedPa;
try {
nestedPa = getPropertyAccessorForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
}
tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
if (nestedPa == this) {
pv.getOriginalPropertyValue().resolvedTokens = tokens;
}
nestedPa.setPropertyValue(tokens, pv);
}
else {
setPropertyValue(tokens, pv);
}
}
nestedPa.setPropertyValue方法内部,主要是通过反射设置属性值。
BeanWrapperImpl.setValue():
@Override
public void setValue(final @Nullable Object value) throws Exception {
final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
上面通过反射填充了属性值后,会接着执行
exposedObject = initializeBean(beanName, exposedObject, mbd);
该方法的代码如下:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
上面的代码就是Spring在初始化bean时的扩展点的调用,下面逐个看下:
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
看到这里判断,如果bean是BeanNameAware接口的实现类会调用setBeanName方法、如果bean是BeanClassLoaderAware接口的实现类会调用setBeanClassLoader方法、如果是BeanFactoryAware接口的实现类会调用setBeanFactory方法,注入对应的属性值。
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
遍历每个BeanPostProcessor接口实现,调用postProcessBeforeInitialization方法,调用时机是什么?
invokeInitMethods(beanName, wrappedBean, mbd);
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
初始化的时候,如果实现了InitializingBean接口或者自定义init方法,这里会执行到。
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
上面的方法遍历BeanPostProcessor,调用postProcessAfterInitialization方法。
registerDisposableBeanIfNecessary(beanName, bean, mbd);
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// 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, getBeanPostProcessors(), acc));
}
else {
// 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() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
第三行要求注册销毁的Bean不是原型,并且满足requiresDestruction方法
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean.getClass() != NullBean.class &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
可以被销毁的bean需要满足:
1、首先,bean不为空,然后2、3有一个满足即可
2、bean有destroy方法
3、bean对应的beanFactory持有DestructionAwareBeanPostProcessor接口的实现类,并且bean有destruction-aware post-processors,即DestructionAwareBeanPostProcessor这个接口的实现。
满足以上条件才能注册为可销毁的Bean
registerDisposableBean(beanName,new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
容器销毁的时候,会遍历disposableBeans,逐一执行销毁方法。
图像来源:https://www.cnblogs.com/xrq730/p/6363055.html
文章参考五月的仓颉大佬的博客,并结合自己的实践而成。
自己目前debug了三遍源码,觉得只有自己debug到源码去看,才能有一个清晰的认识,看博客和自己debug是两码事。