Spring框架Ioc容器加载流程及Bean的生命周期源码分析

Spring框架Ioc容器加载流程及Bean的生命周期源码分析,第1张

Spring框架Ioc容器加载流程及Bean的生命周期源码分析 从构造方法开始

SpringIoC容器加载流程
代码如下

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

整体调用链如下

进入构造方法

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
	this();
	register(annotatedClasses);
	refresh();
}
  1. 先看看调用无参构造this()后,Spring都做了哪些事呢
    整体构造调用链可以简化为以下

可以看到AnnotationConfigApplication最顶级的父类即是DefaultResourceLoader,我们知道面向对象编程中,继承关系中构造方法从父类依次向子类执行。所以现在看下在这过程中Spirng都帮我们做了哪些事情
源码如下:

  • DefaultResourceLoader.class
public DefaultResourceLoader() {
    this.classLoader = ClassUtils.getDefaultClassLoader();
}

首先是获取默认的类加载器
获取流程是什么样的呢,点到spring提供的工具类里面去,看下这段代码

 @Nullable
    public static ClassLoader getDefaultClassLoader() {
        ClassLoader cl = null;

        try {
            cl = Thread.currentThread().getContextClassLoader();//获取当前线程的类加载器
        } catch (Throwable var3) {
        }

        if (cl == null) {
            cl = ClassUtils.class.getClassLoader();//获取当前类的类加载器
            if (cl == null) {
                try {
                    cl = ClassLoader.getSystemClassLoader();//获取系统类加载器
                } catch (Throwable var2) {
                }
            }
        }

        return cl;
    }

这里逻辑相对简单,首先去获取当前线程的类加载器,如果获取不到就去获取当前类的类加载器,如果也获取不到,就去获取系统的类加载器。
至此,classLoader就由此构造方法先给到了一个类加载器,此时断点调出当前类,到抽象类看看做了什么。

  • AbstractApplicationContext.class
	
	public AbstractApplicationContext() {
		this.resourcePatternResolver = getResourcePatternResolver();
	}

这个抽象类主要是,构造出

private ResourcePatternResolver resourcePatternResolver;

这里有点绕,再看看当前类的类图

由于此抽象类实现的接口中有一层就是ResourcePatternResolver这个接口,可以看到此抽象类中对该方法的实现

	@Override
	public Resource[] getResources(String locationPattern) throws IOException {
		return this.resourcePatternResolver.getResources(locationPattern);
	}

那这个Resource又是个啥?有啥作用呢?
把代码跟过来看一下

public interface ResourcePatternResolver extends ResourceLoader {
    String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

    Resource[] getResources(String var1) throws IOException;
}

public interface ResourceLoader {
    String CLASSPATH_URL_PREFIX = "classpath:";

    Resource getResource(String var1);

    @Nullable
    ClassLoader getClassLoader();
}
public interface Resource extends InputStreamSource{
//xxx
}
public interface InputStreamSource {
    InputStream getInputStream() throws IOException;
}

点过来可以看到,原来这个ResourceLoader是Spring框架对资源访问的一个对象。其底层就是一个InputStream输入流的对象,只不过Spring对他进行了一次封装。
到这里,就比较清晰了,其实这两个抽象类做的事情

  1. 设置默认类加载器,2.构造出Spring访问静态资源的Resource对象
  • GenericApplicationContext.class
	
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

这里点过去看看,创建出DefaultListableBeanFactory

    public DefaultListableBeanFactory() {
    }

这里是个空方法,其实也就是创建出一个DefaultListableBeanFactory 的bean工厂的对象。

  • AnnotationConfigApplicationContext.class
	
	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

最后回到这个方法,里面做了两件事,构造this.reader和this.scanner,那这两个又是啥东西,能干嘛呢?
点进去这两个源码

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionevaluator = new Conditionevaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		if (useDefaultFilters) {
			registerDefaultFilters();
		}
		setEnvironment(environment);
		setResourceLoader(resourceLoader);
	}

所以可以看到
this.reader为注解的方式,读到IoC容器
this.scanner为扫包的形式,读到IoC容器

到这里,基本对构造this()构造方法执行有点概念了

接下来就是IoC容器加载的核心
register(annotatedClasses);的部分
这里点进去

	public void register(Class... annotatedClasses) {
		Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
		this.reader.register(annotatedClasses);
	}

首先看到了调用到了this.reader这个对象,由于我们用的是基于注解的方式,所以刚刚的this.reader方法的初始化也得到了论证。
继续往下点

	public void register(Class... annotatedClasses) {
		for (Class annotatedClass : annotatedClasses) {
			registerBean(annotatedClass);
		}
	}
	public void registerBean(Class annotatedClass) {
		doRegisterBean(annotatedClass, null, null, null);
	}

这里由于入参类型是数组,所以存在传入多个类,因此,这里是循环去注册Bean,到Ioc容器中。那就看看注册的动作是啥样的

	 void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name,
			@Nullable Class[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		if (this.conditionevaluator.shouldSkip(abd.getmetadata())) {
			return;
		}

		abd.setInstanceSupplier(instanceSupplier);
		Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(abd);
		abd.setScope(scopemetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry);
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

到这里,就是到了IoC容器的核心代码了
从上往下依次是

AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);

这个里面两个动作

this.setBeanClass(beanClass);
this.metadata = new StandardAnnotationmetadata(beanClass, true);

作用就是将注解的相关信息,设置到我们的AnnotatedGenericBeanDefinition对象里面

if (this.conditionevaluator.shouldSkip(abd.getmetadata())) {
	return;
}

这个是判断是否有条件注入,如果有判断到这个注解,就不将其注入到IoC容器中

abd.setInstanceSupplier(instanceSupplier);

这个的作用为:设置回调

Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(abd);
abd.setScope(scopemetadata.getScopeName());

这里判断你是否加了@Scope这个注解,默认情况下为单例
可以点进去看看源码

	@Override
	public Scopemetadata resolveScopemetadata(BeanDefinition definition) {
		Scopemetadata metadata = new Scopemetadata();
		if (definition instanceof AnnotatedBeanDefinition) {
			AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
			AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
					annDef.getmetadata(), this.scopeAnnotationType);
			if (attributes != null) {
				metadata.setScopeName(attributes.getString("value"));
				ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
				if (proxyMode == ScopedProxyMode.DEFAULT) {
					proxyMode = this.defaultProxyMode;
				}
				metadata.setScopedProxyMode(proxyMode);
			}
		}
		return metadata;
	}

接下来

String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

	@Override
	public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
		if (definition instanceof AnnotatedBeanDefinition) {
			String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
			if (StringUtils.hasText(beanName)) {
				// Explicit bean name found.
				return beanName;
			}
		}
		// Fallback: generate a unique default bean name.
		return buildDefaultBeanName(definition, registry);
	}

	@Nullable
	protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
		Annotationmetadata amd = annotatedDef.getmetadata();
		Set types = amd.getAnnotationTypes();
		String beanName = null;
		for (String type : types) {
			AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
			if (attributes != null && isStereotypeWithNamevalue(type, amd.getmetaAnnotationTypes(type), attributes)) {
				Object value = attributes.get("value");
				if (value instanceof String) {
					String strVal = (String) value;
					if (StringUtils.hasLength(strVal)) {
						if (beanName != null && !strVal.equals(beanName)) {
							throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
									"component names: '" + beanName + "' versus '" + strVal + "'");
						}
						beanName = strVal;
					}
				}
			}
		}
		return beanName;
	}

这里,首先判断你是否是注解的方式注入,判断是否有传beanName,如果没有就给一个默认的beanName,默认首字母小写的类名。
具体的为:determineBeanNameFromAnnotation()方法就是看一下你有没有自己设置bean的名称
如果没有,就走buildDefaultBeanName(definition, registry);这个方法给你设置一个默认的bean名称。

接下来
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

	public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
		processCommonDefinitionAnnotations(abd, abd.getmetadata());
	}

	static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypemetadata metadata) {
		AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
		if (lazy != null) {
			abd.setLazyInit(lazy.getBoolean("value"));
		}
		else if (abd.getmetadata() != metadata) {
			lazy = attributesFor(abd.getmetadata(), Lazy.class);
			if (lazy != null) {
				abd.setLazyInit(lazy.getBoolean("value"));
			}
		}

		if (metadata.isAnnotated(Primary.class.getName())) {
			abd.setPrimary(true);
		}
		AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
		if (dependsOn != null) {
			abd.setDependsOn(dependsOn.getStringArray("value"));
		}

		if (abd instanceof AbstractBeanDefinition) {
			AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
			AnnotationAttributes role = attributesFor(metadata, Role.class);
			if (role != null) {
				absBd.setRole(role.getNumber("value").intValue());
			}
			AnnotationAttributes description = attributesFor(metadata, Description.class);
			if (description != null) {
				absBd.setDescription(description.getString("value"));
			}
		}
	}

这里就是判断下你是否带上了@ Lazy、@ Primary、@ DependsOn、@ Role、@ Description这些注解,如果带上了,进行一些相应的处理。
@ DependsOn:加载优先级
@ Role:有没有设置分类

往下

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry);

这里为啥要用一个BeanDefinitionHolder呢,debug一下可以看到,BeanDefinitionHolder对象内部包括了

private final BeanDefinition beanDefinition;
private final String beanName;
@Nullable
private final String[] aliases;

由于beanDefinition中不包含beanName,无法注入到IoC容器中,所以会需要用BeanDefinitionHolder再给他包装有带一个beanName的对象。

最后

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        String[] var4 = aliases;
        int var5 = aliases.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String alias = var4[var6];
            registry.registerAlias(beanName, alias);
        }
    }

}

这里就是注册到IoC容器的动作了,可以看到这里首先会去获取beanName,也就说明了,为什么前面会需要带beanName这个节点。
这里的registry.registerBeanDefinition(),一共具有三个实现类:DefaultListableBeanFactory、GenericApplicationContext、SimpleBeanDefinitionRegistry。那到底是哪个实现类呢,其实再初始化this()里面,初始化父类的时候有一段源码如下。

	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

可以看到beanFactory类型为DefaultListableBeanFactory

此时子类中this.registry = registry;

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionevaluator = new Conditionevaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

因此
this.reader = new AnnotatedBeanDefinitionReader(this);
里面的
private final BeanDefinitionRegistry registry;
即是前面父类给过来的DefaultListableBeanFactory实现类
所以现在代码走到了

    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition)beanDefinition).validate();
            } catch (BeanDefinitionValidationException var9) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
            }
        }

        BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
            }

            if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (!beanDefinition.equals(oldBeanDefinition)) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (this.logger.isDebugEnabled()) {
                this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }

            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if (this.hasBeanCreationStarted()) {
                synchronized(this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set updatedSingletons = new linkedHashSet(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }

        if (oldBeanDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }

    }

那么其实最后是通过
this.beanDefinitionMap.put(beanName, beanDefinition);
进行注册到IoC容器中,至此注册一些基本的信息到SpringIoC容器已经完成

最后到this.refresh();方法,主要分析其bean的生命周期流程,见下图

源码如下

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

bean的加载是从

// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

开始执行
进入这个方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

进入beanFactory.preInstantiateSingletons();这个方法,这个方法中主要看到getBean()方法,因为当bean不存在的时候,该方法即会进行创建。

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

进入doGetBean方法,看到createBean()方法

try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}

继续跟到doCreateBean方法
核心在于

		try {
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

这段代码中就执行了bean的生命周期的主要流程
其中populateBean()主要完成对bean属性的设置
其中initializeBean()方法里面,完成了BeanPostProcessor的主要内容
其中主要分析
invokeAwareMethods()方法
源码如下

	private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

这里首先会校验下是否属于Aware这个类
然后分别判断是否实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware这些接口,如果实现了,执行对应实现该接口的类中的具体代码
往回看,接着代码往下走
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
这个则是通过反射,执行到具体实现的前置通知方法
invokeInitMethods(beanName, wrappedBean, mbd);
这个就是执行init方法里面的内容了
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
这个就执行init方法完成后的后置通知方法了,类似aop的环绕
到这里spring-bean的生命周期就基本上结束了。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5686399.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存