上一篇说了 bean的的创建需要生成BeanDefinition,合并BeanDefinition,然后通过getBean方法创建bean,那么现在就来看下getBean是如何创建bean的
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//传进来的name有可能是&xxx或者xxx或者别名
//下面这个方法通过do while 删除&符号同时或者对别名处理
String beanName = transformedBeanName(name);
Object beanInstance;
//从单例池中获取bean 这里面涉及到循环依赖的处理
Object sharedInstance = getSingleton(beanName);
//这个if判断获取到的单例bean是不是是FactoryBean 如果是调用getObjectForBeanInstance方法
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 + "'");
}
}
//如果sharedInstance 是FactoryBean 则调用getObject方法返回对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//这个if大致过程就是先判断有没有父BeanFactory
// 根据beanName获取BeanDefinition,如果没有就从parentBeanFactory就是父BeanFactory中获取
//具体的做法就是调用父BeanFactory的getBean方法
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);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
//获取合并后的RootBeanDefinition 大致过程就是从Map中根据beanName获取RootBeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查RootBeanDefinition是不是抽象的 是的话就会抛异常
checkMergedBeanDefinition(mbd, beanName, args);
//获取设置@DependsOn()的值
String[] dependsOn = mbd.getDependsOn();
//这个if主要解决@DependsOn()的作用
// 如果A类上边有@DependsOn(B类的beanName) 那么就会先创建B类 创建不了B类就会抛异常
if (dependsOn != null) {
// dependsOn表示当前beanName所依赖的
for (String dep : dependsOn) {
// beanName是不是被dep依赖了,如果是则出现了循环依赖
//就是说 A类依赖B类 如果B类也依赖A类 就出现循环依赖 抛异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//这里涉及到两个Map 一个是dependentBeanMap 一个是 dependenciesForBeanMap
// dependentBeanMap :某个bean被哪些bean依赖了
// dependenciesForBeanMap :某个bean依赖了哪些bean
// 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);
}
}
}
//这个if else 主要根据主用域 也就是@Scope的值做出响应创建bean的方式
//如果RootBeanDefinition是单例的
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//实例化bean的方法
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;
}
});
//判断是不是FactoryBean对象如果是就会调用getObject方法
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//如果RootBeanDefinition是原型的
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//创建bean的方法
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//删除创建bean的标记
afterPrototypeCreation(beanName);
}
//判断是不是FactoryBean对象如果是就会调用getObject方法
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//其他类型的作用域 例如springMVC 里面的 request session 等等
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();
}
}
// 检查通过name所获得到的beanInstance的类型是否是requiredType
return adaptBeanInstance(name, beanInstance, requiredType);
}
上述代码大致流程就是,首先根据传进来的name做处理获取到beanName,根据beanName从单例池中获取,如果获取到判断是不是FactoryBean,然后出对应处理。一般来说是获取不到的,执行else的代码。if (parentBeanFactory != null && !containsBeanDefinition(beanName))
判断有没有父BeanFactory然后做对应处理。if (dependsOn != null)
处理dependsOn 注解。后续的if就是判断该bean是单例的还是原型还是springmvc相关内容的做出对应处理。
这部分代码都是一些判断,主要核心创建bean的代码是createBean
方法
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了,确保beanClass被加载了 开始类加载的步骤
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
//给RootBeanDefinition赋值class对象 之前可能是类名(一个字符串)
mbdToUse.setBeanClass(resolvedClass);
}
try {
//和lookUp注解有关 暂时不管
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.
// 实例化前
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 {
//核心方法 这个方法 涉及 合并BeanDefinition的处理 实例化 实例化后 属性赋值 初始化前后等过程
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);
}
}
大致流程是,加载类,实例化前的处理,然后核心方法doCreateBean(beanName, mbdToUse, args)
的处理,该方法包含了 实例化,实例化后,属性赋值,初始化前后等过程。下面对核心部分一一分析
这部分过程主要体现在createBean方法中的resolveBeanClass(mbd, beanName)
。
resolveBeanClass(mbd, beanName)
的核心代码
// 如果beanClass被加载了
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
// 如果beanClass没有被加载
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {//这个方法开始加载类
return doResolveBeanClass(mbd, typesToMatch);
}
public boolean hasBeanClass() {
return (this.beanClass instanceof Class);
}
如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用ClassUtils.getDefaultClassLoader()
所返回的类加载器来加载。
ClassUtils.getDefaultClassLoader()
在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean实例化之前做一些启动动作。这部分过程主要体现在createBean方法中的resolveBeforeInstantiation(beanName, mbdToUse)
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//hasInstantiationAwareBeanPostProcessors()判断有没有InstantiationAwareBeanPostProcessor的实现类
//大致过程:从BeanPostProcessorCache中获取List判断是否为空 空就没有
//而BeanPostProcessorCache是一个静态内部类 作用是分类缓存实现了BeanPostProcessor接口的接口,把他们分类放入到list中
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//如果有InstantiationAwareBeanPostProcessor的实现类
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//实例化前方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//如果实例化前返回了bean那么就会直接调用初始化后方法
if (bean != null) {
//初始化后方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//遍历 List 调用实现类的postProcessBeforeInstantiation
//如果其中一个实现类重写的postProcessBeforeInstantiation方法有返回值就直接return了 不会再走下一个实现了
//如果没有返回值 就会循环调用每一个实现类重写的postProcessBeforeInstantiation方法
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
这部分过程主要体现在doCreateBean方法中下面代码这部分
// 实例化bean
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建Bean实例 涉及到构造方法的推断 @bean注解的方法调用 工厂方法创建bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
实例化核心代码在于createBeanInstance(beanName, mbd, args);
createBeanInstance
这部分代码涉及到构造方法的推断 @bean注解的方法调用 工厂方法创建bean等。后续会详细分析
这部分过程主要体现在doCreateBean方法中下面代码这部分
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//从BeanPostProcessor的缓存类BeanPostProcessorCache获取List
//遍历这个list 执行重写的方法
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工
BeanDefinition的后置处理结束后会就到了doCreateBean
方法中的populateBean(beanName, mbd, instanceWrapper);
。这部分代码主要涉及属性填充。在这部分代码中同时包含了对实例化后的处理。
Spring又设计了一个扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
这部分核心都在于populateBean(beanName, mbd, instanceWrapper);
方法中,该方法执行了实例化后的处理,就开始处理自动注入和属性依赖等等。这里也有一个扩展点,就是InstantiationAwareBeanPostProcessor
的postProcessProperties
。例如@Autowired @Resource等注解都是基于InstantiationAwareBeanPostProcessor
的实现类来处理。这部分后续详细分析
在执行完populateBean(beanName, mbd, instanceWrapper);
方法后 就到了 初始化的部分,主要流程在initializeBean(beanName, exposedObject, mbd);
这部分代码中,会先执行Aware回调
invokeAwareMethods(beanName, bean);
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);
}
}
}
完成了属性赋值之后,Spring会执行一些回调,包括:
这也是spring的一个扩展点
初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization()。利用初始化前,可以对进行了依赖注入的Bean进行处理。
@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;
}
Spring源码中:
InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法,
ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:
EnvironmentAware:回传环境变量
EmbeddedValueResolverAware:回传占位符解析器
ResourceLoaderAware:回传资源加载器
ApplicationEventPublisherAware:回传事件发布器
MessageSourceAware:回传国际化资源
ApplicationStartupAware:回传应用其他监听对象,可忽略
ApplicationContextAware:回传Spring容器ApplicationContext
invokeInitMethods(beanName, wrappedBean, mbd);
//invokeInitMethods中部分代码
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);
}
}
查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
执行BeanDefinition中指定的初始化方法
这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessAfterInitialization()
可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象。