本文带着如下问题,分析下spring bean的创建过程,spring是怎么创建bean?ioc又体现在哪里,创建bean的过程中做了些什么,aop的代理对象是什么时候生成的?
1、应用程序的启动
现在的工程大部分都是springboot工程,SpringBoot可以轻松创建独立的、生产级的、基于Spring的应用程序,SpringBoot应用程序可以通过main方法轻松启动,如下:
public static void main(String[] args) {
SpringApplication.run(XXXApplication.class,args);
}
跟进 SpringApplication.run的run方法,会发现应用程序的启动过程,最主要的就是创建ConfigurableApplicationContext了,bean的创建也就是在AbstractApplicationContext.refresh方法中,refresh方法干了啥呢(网上很多人对这些方法进行了翻译,我就不翻译了)?
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 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();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
...
}
}
接下来我们重点讲下其中的 finishBeanFactoryInitialization,实例化所有的非延迟加载的单例bean。
2、创建bean的整体流程。
跟进finishBeanFactoryInitialization方法,就会发现调用到AbstractAutowireCapableBeanFactory.createBean方法,可以通过sequence diagram辅助分析下
下边我们就重点看下AbstractAutowireCapableBeanFactory的createBean方法,代码加了些注释,并把一些内部方法的调用放到了注释中,一并解决方法的作用,省得跳到内部方法,不好看全貌,方法如下(省略了一些异常处理信息):
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
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.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
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.
* 如果有aop等就会生成bean的代理对象
* AbstractAutoProxyCreator类中有调用
* Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
*/
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 {
/**
* 这里会通过缓存对象,解决循环依赖的问题。
* // Eagerly cache singletons to be able to resolve circular references
* // even when triggered by lifecycle interfaces like BeanFactoryAware.
* boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
* isSingletonCurrentlyInCreation(beanName));
*
* 1、实例化bean,创建bean的过程中,会同时实例化那些autowired的对象。
通过获取bean的构造方法,通过反射调用,创建bean,BeanUtil中的方法
* public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
* return ctor.newInstance(argsWithDefaultValues);
* }
* 2、初始化bean
* protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
* Object wrappedBean = bean;
* if (mbd == null || !mbd.isSynthetic()) {
* wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
* }
* try {
* invokeInitMethods(beanName, wrappedBean, mbd);
* }
*
* if (mbd == null || !mbd.isSynthetic()) {
* wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
* }
* return wrappedBean;
* }
*
*/
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
...
}
3、bean的创建
bean的创建就在上边方法的doCreateBean方法中实现,其中包含了实例化和初始化两个过程。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//实例化bean,autowire的对象也会在这个时候创建
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
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);
}
mbd.postProcessed = true;
}
}
//解决循环引用问题
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
//初始化bean,调用init方法,并且会回调BeanPostProcessor 的两个方法。
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
4、总结
通过以上的分析,我们发现spring的bean是通过获取到bean的构造函数,通过反射调用ctor.newInstance(argsWithDefaultValues)创建; ,ioc的自动注入在bean的创建过程中实现,aop的代理对象在创建bean的时候就生成了。
5、扩展阅读
ApplicationContext ,AbstractAutowireCapableBeanFactory,BeanPostProcessor,InitializingBean
/**
* Central interface to provide configuration for an application.
* This is read-only while the application is running, but may be
* reloaded if the implementation supports this.
*
*/
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}
/**
* Factory hook that allows for custom modification of new bean instances —
* for example, checking for marker interfaces or wrapping beans with proxies.
*
*/
public interface BeanPostProcessor {
/**
* 在bean的实例化完成(已调用构造函数),自动注入属性(setter方法)完成,
* 初始化(init-method)之前调用,返回的bean可能是WrapperBean或原始bean
*
* Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
*
* 在bean的初始化(init-method)之后调用,返回的bean可能是WrapperBean或原始bean
* Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* Interface to be implemented by beans that need to react once all their properties
* have been set by a {@link BeanFactory}: e.g. to perform custom initialization,
* or merely to check that all mandatory properties have been set.
*/
public interface InitializingBean {
/**
* Invoked by the containing {@code BeanFactory} after it has set all bean properties
* and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
*/
void afterPropertiesSet() throws Exception;
}
,