(三)源码导读-SpringBean实例化流程
✨这里是第七人格的博客✨小七,欢迎您的到来~✨
🍅系列专栏:源码解析🍅
✈️本篇内容: 源码导读-SpringBean实例化流程✈️
🍱 本篇收录完整代码地址:gitee.com/diqirenge/s… 🍱
楔子
前面我们分析了Spring容器的初始化流程,这一篇开始,我们继续分析bean是怎么被实例化的。
使用示例
首先在BeanFactoryDemo,使用XmlBeanFactory和ClassPathXmlApplicationContext,并且分别调用它们的getBean方法
/**
* Spring 简单使用示例
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @author 第七人格
* @date 2024/01/25
*/
public class BeanFactoryDemo {
private static final String FILE_NAME = "spring.xml";
public static void main(String[] args) {
XmlBeanFactory demo = createXmlBeanFactory(FILE_NAME);
MyBean myBean = (MyBean) demo.getBean("myBean");
System.out.println(myBean.getName());
ClassPathXmlApplicationContext demo2 = createApplicationContext(FILE_NAME);
MyBean myBean2 = (MyBean) demo2.getBean("myBean");
System.out.println(myBean2.getName());
}
public static XmlBeanFactory createXmlBeanFactory(String fileName) throws BeansException {
return new XmlBeanFactory(new ClassPathResource(fileName));
}
public static ClassPathXmlApplicationContext createApplicationContext(String fileName) throws BeansException {
return new ClassPathXmlApplicationContext(fileName);
}
}
执行main方法输出结果
myName
myName
实例化入口
构造XmlBeanFactory、ClassPathXmlApplicationContext对象的时候,Spring进行了bean的初始化,而bean什么时候实例化的呢?就是在调用getBean方法的时候。接下来我们来找一下他的实例化入口。
首先看看XmlBeanFactory的getBean方法,其实就是调用的AbstractBeanFactory的getBean方法
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
然后调用的doGetBean方法。
然后看看ClassPathXmlApplicationContext的getBean方法
public Object getBean(String name) throws BeansException {
// 1、判断容器是否被激活
assertBeanFactoryActive();
// 2、获取BeanFactory,并通过BeanFactory获取bean
return getBeanFactory().getBean(name);
}
它分为两部分
①判断容器是否被激活
②获取BeanFactory,并通过BeanFactory获取bean
跟进getBeanFactory()方法
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return beanFactory;
}
我们可以发现getBeanFactory()返回的实际对象为DefaultListableBeanFactory,而DefaultListableBeanFactory是AbstractBeanFactory的子类,所以DefaultListableBeanFactory调用getBean方法,最终都调用的AbstractBeanFactory的getBean方法
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
也就是说他们共同的实例化入口为:AbstractBeanFactory的getBean方法。而getBean又调用了doGetBean,所以接下来我们需要重点分析一下doGetBean方法。
转换并得到beanName
跟进doGetBean方法
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1、转换并得到beanName
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 2、检查手动注册的单例缓存
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 3、判断单例是否正在创建中
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 + "'");
}
}
// 获取bean的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 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 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 {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
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);
}
}
}
// 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);
}
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();
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);
}
});
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;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
方法有点长,但是无所谓,干就完了!
首先我们来分析transformedBeanName方法
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
第一步他调用了BeanFactoryUtils的transformedBeanName方法,我们跟进这个方法
public static String transformedBeanName(String name) {
// 断言name不能为空
Assert.notNull(name, "'name' must not be null");
// 如果name不是以 & 开始的话,那么直接返回name
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 如果name是以 & 开始的话,那么循环去掉所有的name中所有的 & ,再返回
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
发现他其实是在对传入的beanName中的 & 做处理,那么为什么要对&做特殊处理呢?这里我们先插个眼,既然有特殊处理,后面肯定是有地方用到的。
接下来我们看看canonicalName()方法做了些什么事情
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
很简单就是到别名缓存aliasMap中获取了bean真正的名称。
Spring解决循环依赖的核心代码
上一步我们得到了beanName,接下来我们继续看后面的代码
// Eagerly check singleton cache for manually registered singletons.
// 2、检查手动注册的单例缓存
Object sharedInstance = getSingleton(beanName);
根据注释我们知道,这一步是在检查手动注册的单例缓存,跟进getSingleton方法
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
我们发现他调用了另一个重载的getSingleton方法,继续跟进重载的方法,并且添加一些简单的注释方便我们理解
// 获取单例对象的方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 快速检查是否存在实例,不使用完整的单例锁
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 如果单例对象正在创建中,尝试从早期单例对象中获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 如果允许提前引用且早期单例对象中不存在,则在完整的单例锁内创建早期引用
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 如果早期单例对象中仍然不存在,尝试从单例工厂中获取
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
分析以上方法,我们可以发现他其实是在对singletonObjects、singletonFactories、earlySingletonObjects3个对象进行操作,而这3个对象是什么东西呢?他们就是Spring中大名鼎鼎的三级缓存。
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
分析代码,可以看到这三个缓存,其实就是三个Map。继续往下分析代码。
Object singletonObject = this.singletonObjects.get(beanName);
首先会从singletonObjects中,根据bean的名称beanName来获取单例bean,singletonObjects这个缓存主要是用来存放已经完全实例化好的单例bean。
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {...}
如果singletonObject为空,isSingletonCurrentlyInCreation返回的是true,就会进入到if分支中。而isSingletonCurrentlyInCreation()方法也很简单。
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
就是判断beanName是否在singletonsCurrentlyInCreation中。(后面我们会看到,当bean实例化完成后就会从singletonsCurrentlyInCreation中将bean的名称移除掉)。接下来就会尝试从缓存earlySingletonObjects中获取单例,代码如下:
singletonObject = this.earlySingletonObjects.get(beanName);
如果earlySingletonObjects中也没有这个bean,并且allowEarlyReference为true(默认传进来的就是bean),那么就会进行下面这个if
if (singletonObject == null && allowEarlyReference) {...}
if中具体逻辑如下:
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 如果早期单例对象中仍然不存在,尝试从单例工厂中获取
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
首先从singletonObjects中找bean,如果没有,就去earlySingletonObjects中找,如果earlySingletonObjects也没有,就去singletonFactories中找,如果在singletonFactory中找到了,那么将这个bean放到earlySingletonObjects中,并且从singletonFactories删除掉。
Spring是如何通过FactoryBean来获取bean的?
接着回到doGetBean方法,分析以下分支
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 + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
我们看看getObjectForBeanInstance方法
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
跟进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.
// 判断name是否以 & 开头
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果bean的name是以 & 开头,并且不是FactoryBean的实例
// 那么直接抛异常
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.
// 如果name不是否以 & 开头,并且不是FactoryBean的实例
// 那么直接返回这个bean
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
// 标记bean的类型是FactoryBean
mbd.isFactoryBean = true;
}
else {
// 从缓存中获取bean
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);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 通过FactoryBean来获取bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
看看第一个if条件,跟进isFactoryDereference,熟悉的 & 又出现了。
public static boolean isFactoryDereference(@Nullable String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
也就是说getObjectForBeanInstance方法一来就判断了bean的name是否是以 & 开头的。
现在我们假设我们传进来的beanName是以&开头的,比如叫&seven
,然后继续分析代码。
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果bean的name是以 & 开头,并且不是FactoryBean的实例
// 那么直接抛异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
这个if很简单,如果bean类型是NullBean那么就直接返回,如果他的类型不是FactoryBean,那么就直接报错,否则再往下走,就返回这个类型为FactoryBean的bean了。
如果我们传进来的beanName不是以&开头的,那么就不会走上面的if逻辑,会继续走下面的代码。
注意:以下代码的前提都是传进来的beanName不是以&开头的
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
首先判断了如果bean类型不是FactoryBean,那么会直接返回这个实例。
继续往下看,根据这次假设,mbd的值没有改变,且传进来的时候,是空的,所以Spring会执行这行代码
getCachedObjectForFactoryBean(beanName)
跟进getCachedObjectForFactoryBean方法
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}
我们会发现,他其实就是通过beanName从缓存中去拿了这个bean。
接下来,如果object不为空的话,就直接返回了,否则还要执行以下代码
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);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
首先我们可以看到,Spring将beanInstance强转成了FactoryBean的类型,接着调用containsBeanDefinition方法,判断该beanName是否有对应的BeanDefinition
public boolean containsBeanDefinition(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return this.beanDefinitionMap.containsKey(beanName);
}
然后调用getMergedLocalBeanDefinition方法合并本地的BeanDefinition,最后调用getObjectFromFactoryBean方法获取bean实例
我们跟进getObjectFromFactoryBean方法看看
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// factory.isSingleton()默认为true
// containsSingleton(beanName) 是在判断beanName是不是在单例池里面,我们前面放进去了的,所以这个if是满足的
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 通过doGetObjectFromFactoryBean创建bean实例
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
// 单例bean是否正在实例化
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// 标识单例bean正在创建
beforeSingletonCreation(beanName);
try {
// 在bean创建之后的后置处理,默认什么都没做
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// 移除正在创建的标识
afterSingletonCreation(beanName);
}
}
// 判断beanName对应的单例的FactroyBean是否存在
if (containsSingleton(beanName)) {
// 如果存在则添加到缓存中
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
// 通过doGetObjectFromFactoryBean创建bean实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
接下来我们看看beforeSingletonCreation做了什么
protected void beforeSingletonCreation(String beanName) {
// 1、inCreationCheckExclusions去重,避免同一个bean被重复实例化
// 2、singletonsCurrentlyInCreation用来检查bean是否处于正在创建的状态,这里是加入
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
跟进postProcessObjectFromFactoryBean方法
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}
跟进afterSingletonCreation方法
protected void afterSingletonCreation(String beanName) {
// 1、inCreationCheckExclusions去重,避免同一个bean被重复实例化
// 2、singletonsCurrentlyInCreation用来检查bean是否处于正在创建的状态,这里是删除
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
处理BeanDefinition
再次回到doGetBean方法,继续分析if的else部分
if (sharedInstance != null && args == null)
也就是,第一次创建bean的代码
首先如果名字为beanName的bean正在创建,并且该bean是prototype-原型类型,那么就抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
调用getParentBeanFactory获取父类工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
跟进getParentBeanFactory方法
public BeanFactory getParentBeanFactory() {
return this.parentBeanFactory;
}
我们发现,他其实就是从缓存中去去取数据。(注:前两章我们其实在parentBeanFactory这个集合插过眼,无论是XmlBeanFactory的初始化,还是ClassPathXmlApplicationContext的初始化,这个集合其实都是空的
)
接下来的代码很明显是一段兜底逻辑
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);
}
}
大体逻辑是,如果Spring容器中不存在beanName对应的BeanDefinition,并且该容器是有爸爸的,那么就会到爸爸容器中获取bean的实例。
我们看看originalBeanName方法
String nameToLookup = originalBeanName(name);
跟进originalBeanName方法
protected String originalBeanName(String name) {
// 获取beanName(前面分析过这个方法其实就是去掉了name中的&)
String beanName = transformedBeanName(name);
// 如果传入的name是以&开头的,那么就把开头的&拼回去
if (name.startsWith(FACTORY_BEAN_PREFIX)) {
beanName = FACTORY_BEAN_PREFIX + beanName;
}
return beanName;
}
接着往下走
// typeCheckOnly,是方法传进来的,默认为false
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
typeCheckOnly,是方法传进来的,默认为false
所以我们跟进markBeanAsCreated方法
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
// 让我们在创建bean的时候重新合并bean定义,以防它的元数据在此期间发生了变化
clearMergedBeanDefinition(beanName);
// 标记bean实例已经被创建了
this.alreadyCreated.add(beanName);
}
}
}
}
回到doGetBean方法,继续往下看
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
跟进getMergedLocalBeanDefinition方法
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));
}
跟进getMergedBeanDefinition的重载方法
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
跟进getMergedBeanDefinition的重载方法
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
// Check with full lock now in order to enforce the same merged instance.
// 立即使用完全锁定来检查,以便强制执行相同的合并实例。
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
// 子类的bean definition 需要和分类合并
BeanDefinition pbd;
try {
// 获取父类的beanName
String parentBeanName = transformedBeanName(bd.getParentName());
// 如果当前bean的name和父类beanName不同
if (!beanName.equals(parentBeanName)) {
// 递归调用getMergedBeanDefinition,直到获取到父类bean的RootBeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
}
// 如果当前bean的name和父类beanName相同
else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// 深拷贝
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
// 设置默认的BeanDefinition为单例的
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
// 添加到mergedBeanDefinitions缓存中
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
以上代码看着很多,但是很多都是分析过的方法了。逻辑也很清晰,大概做了以下几件事:
-
Spring在实例化前需要通过RootBeanDefinition封装从Spring容器中获取到的BeanDefinition。
-
如果当前的bean配置了父类bean,那就先封装父类bean的RootBeanDefinition,否则封装当前bean对应的BeanDefinition。
-
设置默认的BeanDefinition为单例的。
-
将包装好的RootBeanDefinition添加到mergedBeanDefinitions缓存中。
预先实例化被依赖的bean
回到doGetBean方法,继续往下看
// 检查合并好的BeanDefinition是否满足实例化条件
// 其实里面就是判断了一下BeanDefinition对应的bean是否是抽象类
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 获取当前bean依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 判断当前bean和被依赖的bean是否存在循环关系
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册被依赖的bean
registerDependentBean(dep, beanName);
try {
// 递归,先实例化被依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
Spring会通过
String[] dependsOn = mbd.getDependsOn();
获取当前bean所依赖的bean。并且循环遍历这些被依赖bean,判断当前bean和被依赖的bean是否存在循环关系。
跟进isDependent方法,代码如下:
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
// 获取bean名称
String canonicalName = canonicalName(beanName);
// 获取被依赖的bean的名称
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
// 当前bean的依赖中是否包含包含传进来的bean依赖的名称
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
alreadySeen.add(beanName);
// 递归判断bean名称是否在依赖链上
// 比如:A——>B——>C——>D
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
分析以上代码,其实就是在判断当前bean和被依赖的bean是否存在循环关系。
接着分析registerDependentBean方法
// 注册被依赖的bean
registerDependentBean(dep, beanName);
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
我们可以看到他其实就是将bean名称,和bean依赖的bean的名称,都放入各种的缓存map中。
createBean
实例化被依赖的bean后,回到doGetBean方法,继续往下看,分别是处理单例bean,原型bean,以及其他。
这里我们跟着代码,先看看是如何处理单例bean的。
// 判断是否是单例bean
if (mbd.isSingleton()) {
// 获取单例的bean集合
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;
}
});
// 获取bean的实例化对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
流程很简单,先获取单例的bean集合,再通过getObjectForBeanInstance获取实例化对象,我们先来看看getSingleton方法。他传入了beanName,和一个匿名函数。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 从单例池中获取bean实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 如果单例bean正在销毁,那么不允许创建bean
// 这个属性默认为false
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 标记单例bean正在被创建
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 调用工厂创建bean实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 标记单例bean创建完成
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 对各个缓存进行操作
// 这里会加入到单例池中,并且从单例工厂缓存和早期bean缓存中移除
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
getSingleton方法的流程还是比较简单的,首先尝试从单例池中取,取不到则先标记单例bean正在被创建,然后调用工厂创建bean实例,接着标记单例bean创建完成,并对三级缓存进行相应的处理。
beforeSingletonCreation方法和afterSingletonCreation方法前面我们已经分析过了,他们主要是先检查bean是否重复创建,接着再在bean实例化之前,添加beanName到singletonsCurrentlyInCreation缓存中,表明当前bean正在创建;在bean实例化完成之后,再从缓存singletonsCurrentlyInCreation中移除,表明当前bean已经创建。
接着我们分析一下,Spring是如何调用工厂创建bean实例的,关键代码如下
// 调用工厂创建bean实例
singletonObject = singletonFactory.getObject();
singletonFactory是我们前面通过匿名内部类传进来的,也就是说实际的方法是这个createBean,跟进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;
// 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类,并且如果是一个动态解析的Class,它不能被存储在共享的合并bean定义中,所以需要克隆bean定义。
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.
// 让BeanPostProcessors有机会返回一个代理对象,而不是目标bean实例。
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 {
// do打头的方法,你懂的
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.
// 之前检测到的异常已经具有适当的bean创建上下文,或者要将非法的单例状态上报给DefaultSingletonBeanRegistry。
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
createBean方法前面半截大多还是在做一些准备工作,直到我们看到了resolveBeforeInstantiation方法,根据注释我们知道它能够让BeanPostProcessors有机会返回一个代理对象,而不是目标bean实例。也就是说它是Spring给我们的一个拓展点,让我们能做在bean实例化前做一些事。
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.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
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;
}
这里我们把重点放在applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization方法上。
首先我们到applyBeanPostProcessorsBeforeInstantiation方法里看看。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 循环遍历注册好的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 如果这些后置处理器是InstantiationAwareBeanPostProcessor的类型
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 执行实例化前的后置处理方法,去创建bean实例
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
跟进InstantiationAwareBeanPostProcessor这个类,我们可以知道他其实实现了BeanPostProcessor接口,并且定义了一些自己的方法。
也就是说BeanPostProcessor的关注点在于定义初始化bean的操作,而InstantiationAwareBeanPostProcessor的关注点在于定义实例化bean的操作。
接着我们来看看applyBeanPostProcessorsAfterInitialization这个方法。
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;
}
applyBeanPostProcessorsAfterInitialization方法的流程,和前面分析的applyBeanPostProcessorsBeforeInstantiation方法简直一模一样,只是这里他执行的是BeanPostProcessor的postProcessAfterInitialization方法,也就是在bean实例化完成之后,再对bean做一些初始化操作,当然他也是Spring留给我们的拓展点。
再次解析BeanClass
回到AbstractAutowireCapableBeanFactory#createBean方法,我们进入doCreateBean方法,分析一下Spring是如何实例化Bean的。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 实例化这个bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建bean实例的包装类
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.
// 允许后处理器修改合并后的bean定义。
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;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 将单例对象缓存起来,以便在生命周期接口(如BeanFactoryAware)触发时能够解析循环引用。
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");
}
// 往单例工厂的缓存中,添加早期实例化bean的objectFactory
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
// 初始化bean实例
Object exposedObject = bean;
try {
// 为bean添加属性
populateBean(beanName, mbd, instanceWrapper);
// 初始化bean
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);
}
}
if (earlySingletonExposure) {
// 从早期单例池中获取,获取早期单例bean
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
// 判断是否有其他的bean依赖当前的bean
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 将依赖当前bean的bean名称放到 actualDependentBeans的set中
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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
// 将bean注册为可丢弃的
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
首先如果bean是单例的,那么就从factoryBeanInstanceCache中删除它,我们这里进来返回的instanceWrapper就是空的。
接着会调用createBeanInstance方法,去创建bean实例的包装类。而createBeanInstance具体又是怎么做的呢?我们跟进createBeanInstance方法看看。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 再次解析BeanClass,确保在这个时点实际上已经解析了bean类
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 如果这个解析的baan不为空,并且不是public修饰的,并且也没有通过反射设置访问权限,那么就抛出异常
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果属性factory-method不为空,则通过配置好的工厂方法来实例化bean
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 当你重新创建相同的bean时,可以使用快捷方式...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 自动装配的候选构造函数?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 实例化构造方法上添加了@Autowired注解的bean
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
// 优先构造默认的构造函数?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 无需特殊处理:只需使用无参构造函数
return instantiateBean(beanName, mbd);
}
首先会调用resolveBeanClass方法,再次解析BeanClass,确保在这个时点实际上已经解析了bean类;接着会判断bean对应的Class,如果它不被public修饰,并且也没有通过反射来设置这个Class是可以访问的,那么就会抛出异常,从而中止bean的实例化。
通过工厂方法实例化bean
然后往下走,根据BeanDefinition的属性设置,调用不同的方法,我们这里看一下instantiateUsingFactoryMethod这个方法。
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
继续跟进ConstructorResolver#instantiateUsingFactoryMethod方法,其核心逻辑就是判断当前是通过静态工厂方法,还是实例工厂方法来实例化bean的,它里面有大量的反射相关的代码,小七这里就不带着看了。
通过反射/CGLIB实例化bean
因为我们是第一次进来,所以以下分支我们是不会走的(PS:就算要走,一眼也可以看到,重点的方法就是autowireConstructor和instantiateBean)
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
我们继续往下看,进入到determineConstructorsFromBeanPostProcessors
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
// 首先检查beanClass是否为非空,以及是否存在实例化感知的Bean后处理器(InstantiationAwareBeanPostProcessors)
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
// 循环遍历这些后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 如果这些后置处理器的类型是 SmartInstantiationAwareBeanPostProcessor
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 执行 determineCandidateConstructors 方法
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
还是熟悉的配方,熟悉的结构,一看就是Spring留给咱们的拓展点,拓展关键为SmartInstantiationAwareBeanPostProcessor,确定用于给定bean的候选构造函数。
我们继续往下看,当满足某些条件的时候,他有可能会走autowireConstructor方法,我们进入autowireConstructor方法,简单的瞟一眼,他也是一坨反射的代码,主要是为了实例化构造方法上添加了@Autowired注解的bean,这个我们后面再详细的说,这里先插个眼。
最后来到我们的instantiateBean方法了。跟进instantiateBean方法
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
instantiateBean方法的逻辑还是比较简单的,首先会通过初始化策略实例化一个实例beanInstance,然后将bean的实例封装到BeanWrapper中,最后再
调用initBeanWrapper方法实例化包装类BeanWrapper。
我们跟进InstantiationStrategy#instantiate方法
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<Constructor<?>>) 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是否被覆写(也就是当前的bean标签中是否配置了属性lookup-method或者replace-method),如果被覆写,那么最终调用BeanUtils.instantiateClass的方法,通过反射去创建实例;如果没有被覆写,则调用instantiateWithMethodInjection方法,通过CGLIB去创建bean实例。
我们继续跟进instantiateWithMethodInjection方法,最后能在CglibSubclassingInstantiationStrategy找到他默认的实现。
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
继续跟进instantiate方法
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
// 创建一个增强的子类,用于提供的bean定义,使用CGLIB
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
我们可以从instantiate这个方法看到,对于覆写方法的bean,Spring默认是使用CGLIB来玩的。反过来说,Spring默认是通过反射来实现bean的实例化的。
createBeanInstance方法分析得差不多了,我们回到AbstractAutowireCapableBeanFactory#doCreateBean的主干上。
跟进applyMergedBeanDefinitionPostProcessors方法
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
我们可以知道主要就是获取了类型为MergedBeanDefinitionPostProcessor的后置处理器,并且调用了他的postProcessMergedBeanDefinition方法
提前曝光早期的单例bean
我们继续往下看
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 将单例对象预先缓存,以便在生命周期接口(如BeanFactoryAware)触发时解决循环引用问题。
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");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
通过注释,我们可以很清楚的知道以上代码是在干嘛,主要是将单例对象预先缓存,以便在生命周期接口(如BeanFactoryAware)触发时解决循环引用问题。
接下来我们看看关键方法addSingletonFactory,他有两个入参,第一个是当前正在实例化bean的名称beanName,第二个是实现了方法getEarlyBeanReference的匿名内部类。瞄一眼这个方法
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
他其实就是将实现了SmartInstantiationAwareBeanPostProcessor的后置处理器都拿了出来,并且执行了他们的getEarlyBeanReference方法,而getEarlyBeanReference也很简单,默认就是把传入的bean给返回了,也是很明显的拓展点写法。
继续分析addSingletonFactory方法
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 如果一级缓存里面没有
if (!this.singletonObjects.containsKey(beanName)) {
// 添加到三级缓存中
this.singletonFactories.put(beanName, singletonFactory);
// 从二级缓存中移除
this.earlySingletonObjects.remove(beanName);
// 添加到单例注册信息中
this.registeredSingletons.add(beanName);
}
}
}
为早期的单例bean填充属性
接着往下看,首先调用了populateBean方法,为刚实例化好的bean填充各种属性值。
// 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方法看看
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 熟悉的代码,熟悉的配方,Spring为我们提供的拓展点:在bean设置属性之前,可以调用 postProcessAfterInstantiation
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 获取BeanDefinition所有的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 判断自动装配模式
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
// 按名字自动注入
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// 按类型自动注入
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 是否注册过后置处理器:InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否需要对属性进行引用检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 检查依赖
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 填充属性
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
bw肯定不是空的,所以我们并不会进第一个if判断。接着往下走,Spring为我们提供了一个拓展点,InstantiationAwareBeanPostProcessor的后置处理器,可以在bean设置属性之前,调用 postProcessAfterInstantiation方法,做一些操作。然后就是对自动装配模式的处理了。
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
首先我们跟进getResolvedAutowireMode方法,看看它是如何解析自动装配模式的
public int getResolvedAutowireMode() {
// 如果是自动装配模式
if (this.autowireMode == AUTOWIRE_AUTODETECT) {
// Work out whether to apply setter autowiring or constructor autowiring.
// If it has a no-arg constructor it's deemed to be setter autowiring,
// otherwise we'll try constructor autowiring.
// 获取bean中所有的构造方法
Constructor<?>[] constructors = getBeanClass().getConstructors();
for (Constructor<?> constructor : constructors) {
// 如果有无参的构造方法
if (constructor.getParameterCount() == 0) {
// 那么就是按类型自动注入
return AUTOWIRE_BY_TYPE;
}
}
// 按构造方法自动注入
return AUTOWIRE_CONSTRUCTOR;
}
else {
// 默认不自动装配
return this.autowireMode;
}
}
代码很简单,就是如果配置了AUTOWIRE_AUTODETECT模式,那么Spring就会获取bean中所有的构造方法,如果有无参的构造方法,那么就按类型注入,否则按构造方法注入;如果没配置AUTOWIRE_AUTODETECT模式,那么就不会启用自动装配。
接着我们回到主干,跟进autowireByName方法,看下Spring是如何根据名称来自动装配的。
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取bean中满足条件的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 遍历这些属性
for (String propertyName : propertyNames) {
// 如果Spring容器中,已经有属性依赖的bean的实例
if (containsBean(propertyName)) {
// 通过属性名称获取bean实例
Object bean = getBean(propertyName);
// 向pvs中添加属性名称已经对应的bean
pvs.add(propertyName, bean);
// 注册属性与对应bean之间的依赖关系
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
第一步调用unsatisfiedNonSimpleProperties方法,获取bean中满足条件的属性。跟进unsatisfiedNonSimpleProperties方法
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
// 有set方法
if (pd.getWriteMethod() != null
// 没有被忽略的依赖检查项
&& !isExcludedFromDependencyCheck(pd)
// pvs中有属性的名称
&& !pvs.contains(pd.getName())
// 不是简单的数据类型
&& !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
我们看看isExcludedFromDependencyCheck这个方法
protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||
// 判断属性是否被添加到了忽略感知的接口中
AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces));
}
这里就和我们前面提到过的忽略感知的接口-ignoredDependencyInterfaces连起来了。
小结一下,在Spring的自动装配过程中,若发现集合ignoredDependencyInterfaces中添加了某些感知接口,并且这些接口与bean中的属性setter方法存在重名,同时该bean实现了这些接口,那么Spring会将这个属性排除在自动装配的范围之外。
第二步循环遍历上面获取的这些属性,如果在Spring容器中,根据属性的名称找到了bean的信息,那么会优先调用getBean方法来加载bean,同时,将属性名称propertyName和对应的实例bean绑定在MutablePropertyValues(pvs)中。
第三步调用之前分析过的方法registerDependentBean,注册属性propertyName和当前实例beanName之前的依赖关系。
autowireByName按名称自动装配这个方法,我们分析完了,接着分析autowireByType按类型自动装配这个方法。
跟进autowireByType方法
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
我们可以看到代码逻辑和autowireByName是很相似的,都是先获取满足条件的属性,然后根据bean的类型来解析获取bean实例,最后注册bean的依赖。
继续回到populateBean主干,往下走。
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 获取@Autowired、@Resource等注解上的一些属性信息
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
以上代码还是在处理类型是InstantiationAwareBeanPostProcessor的后置处理器,只不过他是在处理@Autowired、@Resource等注解上的一些属性信息。在往下走,applyPropertyValues方法才是将前面解析到的所有属性信息,通过BeanWrapper填充到bean实例中。
通过initializeBean方法初始化bean
接下来,我们再来看下方法initializeBean,跟进initializeBean方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 调用感知方法
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 调用感知方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 在bean初始化前,通过后置处理器调整下bean的实例
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 执行bean的初始化方法
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()) {
// 在bean初始化后,通过后置处理器调整下bean的实例
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
首先调用了invokeAwareMethods方法,我们看看它都做了些什么
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);
}
}
}
其实就是对对应的感知类型的bean实例设置了一些属性值。
接下来,我们跟进applyBeanPostProcessorsBeforeInitialization方法
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方法,也是Spring的一个拓展点,同理applyBeanPostProcessorsAfterInitialization方法也是一样的,只不过它调用的是BeanPostProcessor的postProcessAfterInitialization方法。
最后进入到关键方法invokeInitMethods,看看它的逻辑
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 判断bean的类型是否是InitializingBean
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<Object>) () -> {
// 调用 InitializingBean 的afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 调用 InitializingBean 的afterPropertiesSet方法
((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);
}
}
}
首先再跟进afterPropertiesSet方法
public interface InitializingBean {
/**
* Invoked by the containing {@code BeanFactory} after it has set all bean properties
* and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
* <p>This method allows the bean instance to perform validation of its overall
* configuration and final initialization when all bean properties have been set.
* @throws Exception in the event of misconfiguration (such as failure to set an
* essential property) or if initialization fails for any other reason
*/
void afterPropertiesSet() throws Exception;
}
他的实现非常多,看起来很困难,我们换个思路,看看注释有没有给我提供有用的信息。翻译如下:
被包含的{@code BeanFactory}在设置所有bean属性并满足{@link BeanFactoryAware}、{@code ApplicationContextAware}等之后调用。
此方法允许bean实例在所有bean属性设置完成后执行其整体配置的验证和最终初始化。
通过注释,我们可以知道在bean初始化时,会执行InitializingBean接口中的afterPropertiesSet方法。
接着往下走,满足某些条件时会执行自定义的初始化方法invokeCustomInitMethod。而invokeCustomInitMethod方法主要就是通过反射,执行我们在标签中指定的 init-method 方法。
小结一下,在实例化bean时,首先会判断bean是否实现了接口InitializingBean。如果实现了该接口,那么Spring容器会在执行指定的初始化方法之前,先调用InitializingBean中的afterPropertiesSet()方法进行初始化操作,然后再执行指定的初始化方法。这样可以确保在执行其他初始化操作之前,已经完成了必要的初始化工作。
为bean注册DisposableBeanAdapter
接着往下看
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
跟进registerDisposableBeanIfNecessary方法
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));
}
}
}
可以看到,方法registerDisposableBeanIfNecessary主要就是为bean注册DisposableBeanAdapter。而DisposableBeanAdapter又是干什么的呢?
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable
它实现了DisposableBean接口,并且接口中只定义了一个方法destroy
public interface DisposableBean {
/**
* Invoked by the containing {@code BeanFactory} on destruction of a bean.
* @throws Exception in case of shutdown errors. Exceptions will get logged
* but not rethrown to allow other beans to release their resources as well.
*/
void destroy() throws Exception;
}
方法destory会在bean销毁之前被Spring容器调用执行,我们可以在destroy方法中释放资源,或者进行垃圾回收等等操作。
我们回到DisposableBeanAdapter的destroy方法,看看它具体都做了些什么。
public void destroy() {
// 拓展点,实现DestructionAwareBeanPostProcessor接口的postProcessBeforeDestruction方法
// 可以在bean销毁前做一些事情
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// 如果invokeDisposableBean为true
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
// 如果bean是 DisposableBean 类型的,那么会调用destroy方法
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
// 如果有和初始化方法相对应的销毁方法,如bean标签的destory-method
if (this.destroyMethod != null) {
// 那么执行自定义的销毁方法
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
单例bean的实例化流程我们基本分析完了,我们回到AbstractBeanFactory的doGetBean方法
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);
}
在实例完成之后,getObjectForBeanInstance方法,分析bean是不是FactoryBean的实例,并且是否需要通过FactoryBean来实例化bean,这一块我们在**《Spring是如何通过FactoryBean来获取bean的?》**一章已经看过了,这里就不再复述了。
再往下走,就是对原型类型bean的实例化操作了
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);
}
当然,其他类型bean的实例化也仅跟其后
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);
}
});
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);
}
}
只看代码结构,我们也可以知道他们的核心代码就是createBean方法和getObjectForBeanInstance方法,自此SpringBean的实例化流程我们就分析完了。最后小七梳理了一张流程图,作为本文的总结:
转载自:https://juejin.cn/post/7355745761369882639