SpringBoot源码分析

cnblogs 2024-09-18 08:09:04 阅读 59

Springboot源码分析

1、SpringApplication初始化

从run()方法进入,可以看到Springboot首先创建了SpringApplication,然后调用SpringApplication的run()方法。

<code>public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {

return (new SpringApplication(primarySources)).run(args);

}

创建SpringApplication,首先要执行它的构造方法。

//SpringApplication.class

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {

this.sources = new LinkedHashSet();

this.bannerMode = Mode.CONSOLE;

this.logStartupInfo = true;

this.addCommandLineProperties = true;

this.addConversionService = true;

this.headless = true;

this.registerShutdownHook = true;

this.additionalProfiles = new HashSet();

this.isCustomEnvironment = false;

this.lazyInitialization = false;

this.resourceLoader = resourceLoader;

Assert.notNull(primarySources, "PrimarySources must not be null");

this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));

//webApplication类型一般是servlet

this.webApplicationType = WebApplicationType.deduceFromClasspath();

//设置初始化器,加载spring.factories文件中的ApplicationContextInitializer

this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));

//设置监听器,加载spring.factories文件中的ApplicationListener

this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

//启动类的类型,我们的是com.example.demo.DemoApplication

this.mainApplicationClass = this.deduceMainApplicationClass();

}

1.1 & 1.2 设置初始化器和监听器

上面的setInitializers和setListeners去初始化spring.factories文件中对应的类,然后放入ArrayList中。比如这些:

org.springframework.context.ApplicationContextInitializer=\

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\

org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners

org.springframework.context.ApplicationListener=\

org.springframework.boot.autoconfigure.BackgroundPreinitializer

1.2.1 getSpringFactoriesInstances

在getSpringFactoriesInstances()方法中,springboot首先去所有spring.factories找到对应的类,然后通过反射创建类的实例。

//SpringApplication.class

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {

return this.getSpringFactoriesInstances(type, new Class[0]);

}

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {

ClassLoader classLoader = this.getClassLoader();

//获取spring.factories中对应类的类名,以ApplicationListenser为例,springboot会去文件中找到所有ApplicationListener对应的类,放入Set中。

Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

//反射创建类的实例对象,放到List中返回

List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

AnnotationAwareOrderComparator.sort(instances);

return instances;

}

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {

List<T> instances = new ArrayList(names.size());

Iterator var7 = names.iterator();

while(var7.hasNext()) {

String name = (String)var7.next();

try {

//获取类信息

Class<?> instanceClass = ClassUtils.forName(name, classLoader);

Assert.isAssignable(type, instanceClass);

//获取构造器

Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);

//创建实例

T instance = BeanUtils.instantiateClass(constructor, args);

instances.add(instance);

} catch (Throwable var12) {

throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);

}

}

return instances;

}

1.2.2 loadFactoryNames()

进入SpringFactoriesLoader.loadFactoryNames(type, classLoader)看一下,这里还是以ApplicationListener为例,这时的type是org.springframework.context.ApplicationListener,classLoader是AppClassLoader。

//SpringFactoriesLoader.class

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {

String factoryTypeName = factoryType.getName();

return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());

}

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {

MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);

if (result != null) {

return result;

} else {

try {

Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");

MultiValueMap<String, String> result = new LinkedMultiValueMap();

while(urls.hasMoreElements()) {

URL url = (URL)urls.nextElement();

UrlResource resource = new UrlResource(url);

Properties properties = PropertiesLoaderUtils.loadProperties(resource);

Iterator var6 = properties.entrySet().iterator();

while(var6.hasNext()) {

Map.Entry<?, ?> entry = (Map.Entry)var6.next();

String factoryTypeName = ((String)entry.getKey()).trim();

String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());

int var10 = var9.length;

for(int var11 = 0; var11 < var10; ++var11) {

String factoryImplementationName = var9[var11];

result.add(factoryTypeName, factoryImplementationName.trim());

}

}

}

cache.put(classLoader, result);

return result;

} catch (IOException var13) {

throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);

}

}

}

loadSpringFactories()方法会遍历所有的spring.factories文件,把所有的类的名字保存到map中,然后调用getOrDefault()方法就可以获取到所有的ApplicationListner对应的类名了。

image-20240908150805908

SpringApplication初始化完了,接下来该执行run()方法了

2、SpringApplication执行run()方法

<code>//SpringApplication.class

public ConfigurableApplicationContext run(String... args) {

StopWatch stopWatch = new StopWatch();

stopWatch.start();

//这里是Spring的上下文

ConfigurableApplicationContext context = null;

Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();

this.configureHeadlessProperty();

//获取运行监听器,获取到的是EventPublishingRunListener,这是springboot的启动监听器

SpringApplicationRunListeners listeners = this.getRunListeners(args);

//启动监听器

listeners.starting();

Collection exceptionReporters;

try {

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

//2.1 准备环境

ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);

this.configureIgnoreBeanInfo(environment);

//Banner打印类

Banner printedBanner = this.printBanner(environment);

//2.2 创建应用上下文

context = this.createApplicationContext();

exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);

//2.3 准备上下文

this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

//2.4 刷新上下文

this.refreshContext(context);

//刷新上下文后置处理

this.afterRefresh(context, applicationArguments);

stopWatch.stop();

if (this.logStartupInfo) {

(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);

}

//发布上下文启动完成事件

listeners.started(context);

this.callRunners(context, applicationArguments);

} catch (Throwable var10) {

this.handleRunFailure(context, var10, exceptionReporters, listeners);

throw new IllegalStateException(var10);

}

try {

listeners.running(context);

return context;

} catch (Throwable var9) {

this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);

throw new IllegalStateException(var9);

}

}

2.1 prepareEnvironment()准备环境

//SpringApplication.class

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {

//根据前面推断的webApplicationType创建对应的环境,servlet对应的是StandardServletEnvironment()

ConfigurableEnvironment environment = this.getOrCreateEnvironment();

//根据参数配置环境,包括命令行参数,启动类传入的参数

this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());

ConfigurationPropertySources.attach((Environment)environment);

//执行完这个,配置文件中的配置进行就被加载到环境中了

listeners.environmentPrepared((ConfigurableEnvironment)environment);

//环境和SpringApplication绑定起来

this.bindToSpringApplication((ConfigurableEnvironment)environment);

if (!this.isCustomEnvironment) {

environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());

}

ConfigurationPropertySources.attach((Environment)environment);

return (ConfigurableEnvironment)environment;

}

2.1.1 根据参数配置环境configureEnvironment()

//SpringApplication.class

protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {

if (this.addConversionService) {

ConversionService conversionService = ApplicationConversionService.getSharedInstance();

environment.setConversionService((ConfigurableConversionService)conversionService);

}

//配置命令行中的参数

this.configurePropertySources(environment, args);

//激活相应的配置文件,例如application.propertires或者application-dev.properties等

this.configureProfiles(environment, args);

}

如果我启动的dev环境,执行完上面的代码后环境中是这样的

image-20240908162616219

2.1.2 listeners.environmentPrepared()

执行完这句代码后,配置文件中的信息就被加载到环境中了,如下图。具体怎么做到的还没看懂

image-20240908164518735

2.2 创建应用上下文createApplicationContext()

<code>//SpringApplication.class

protected ConfigurableApplicationContext createApplicationContext() {

Class<?> contextClass = this.applicationContextClass;

if (contextClass == null) {

try {

switch (this.webApplicationType) {

case SERVLET:

contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");

break;

case REACTIVE:

contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");

break;

default:

contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");

}

} catch (ClassNotFoundException var3) {

throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);

}

}

return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);

}

这个函数也是根据前面的webApplicationType创建应用上下文,servlet对应的是AnnotationConfigServletWebServerApplicationContext,当初始化完这个类时,其实也会创建一个IOC容器beanFactory,如下图所示。这是因为AnnotationConfigServletWebServerApplicationContext会继承GenericApplicationContext,当执行完这个类的构造函数,会创建一个DefaultListableBeanFactory()的beanFactory,这个就是IOC容器。

image-20240908165849323

2.3 准备上下文prepareContext()

<code>//SpringApplication.class

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {

//设置上下文环境

context.setEnvironment(environment);

this.postProcessApplicationContext(context);

//初始化所有的ApplicationContextInitializer

this.applyInitializers(context);

//发布上下文准备完成事件

listeners.contextPrepared(context);

if (this.logStartupInfo) {

this.logStartupInfo(context.getParent() == null);

this.logStartupProfileInfo(context);

}

//获取IOC容器beanFactory

ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

//将springApplicationArguments和springBootBanner注册成单例

beanFactory.registerSingleton("springApplicationArguments", applicationArguments);

if (printedBanner != null) {

beanFactory.registerSingleton("springBootBanner", printedBanner);

}

if (beanFactory instanceof DefaultListableBeanFactory) {

((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);

}

if (this.lazyInitialization) {

context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());

}

//2.3.1 获取资源,其中primarySources就是我们定义的启动类DemoApplication

Set<Object> sources = this.getAllSources();

Assert.notEmpty(sources, "Sources must not be empty");

//2.3.2 加载启动类,注入IOC容器

this.load(context, sources.toArray(new Object[0]));

//发布完成加载事件

listeners.contextLoaded(context);

}

2.3.1 & 2.3.2 获取启动类,注入IOC容器

当执行完getAllSources(),可以获取到启动类DemoApplication

image-20240908173716481

重点看load()方法,进入load()。

<code>//SpringApplication.class

protected void load(ApplicationContext context, Object[] sources) {

if (logger.isDebugEnabled()) {

logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));

}

//创建BeanDefinitionLoader

BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);

if (this.beanNameGenerator != null) {

loader.setBeanNameGenerator(this.beanNameGenerator);

}

if (this.resourceLoader != null) {

loader.setResourceLoader(this.resourceLoader);

}

if (this.environment != null) {

loader.setEnvironment(this.environment);

}

//加载启动类

loader.load();

}

其中getBeanDefinitionRegistry(context)方法会将之前的上下文context强转成BeanDefinitionRegistry,他们之间的继承关系很复杂,可以转换成不同的类完成不同的方法。createBeanDefinitionLoader()方法创建了一个BeanDefinitionLoader(),点进去看看。

//BeanDefinitionLoader.class

BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {

Assert.notNull(registry, "Registry must not be null");

Assert.notEmpty(sources, "Sources must not be empty");

this.sources = sources;

//注解形式的Bean阅读器

this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);

//xml形式的Bean阅读器

this.xmlReader = new XmlBeanDefinitionReader(registry);

if (this.isGroovyPresent()) {

this.groovyReader = new GroovyBeanDefinitionReader(registry);

}

//类路径扫描器

this.scanner = new ClassPathBeanDefinitionScanner(registry);

this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));

}

一直跟进load()。

//BeanDefinitionLoader.class

private int load(Class<?> source) {

if (this.isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {

GroovyBeanDefinitionSource loader = (GroovyBeanDefinitionSource)BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);

this.load(loader);

}

//启动类会走进这里

if (this.isEligible(source)) {

//将启动类注册进beanDefinitionMap

this.annotatedReader.register(new Class[]{source});

return 1;

} else {

return 0;

}

}

进入register()方法。

//AnnotatedBeanDefinitionReader.class

public void register(Class<?>... componentClasses) {

Class[] var2 = componentClasses;

int var3 = componentClasses.length;

for(int var4 = 0; var4 < var3; ++var4) {

Class<?> componentClass = var2[var4];

this.registerBean(componentClass);

}

}

public void registerBean(Class<?> beanClass) {

this.doRegisterBean(beanClass, (String)null, (Class[])null, (Supplier)null, (BeanDefinitionCustomizer[])null);

}

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {

//将beanClass(这里是启动类DemoApplication)封装成AnnotatedGenericBeanDefinition

AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {

abd.setInstanceSupplier(supplier);

ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

abd.setScope(scopeMetadata.getScopeName());

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

AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

int var10;

int var11;

if (qualifiers != null) {

Class[] var9 = qualifiers;

var10 = qualifiers.length;

for(var11 = 0; var11 < var10; ++var11) {

Class<? extends Annotation> qualifier = var9[var11];

if (Primary.class == qualifier) {

abd.setPrimary(true);

} else if (Lazy.class == qualifier) {

abd.setLazyInit(true);

} else {

abd.addQualifier(new AutowireCandidateQualifier(qualifier));

}

}

}

if (customizers != null) {

BeanDefinitionCustomizer[] var13 = customizers;

var10 = customizers.length;

for(var11 = 0; var11 < var10; ++var11) {

BeanDefinitionCustomizer customizer = var13[var11];

customizer.customize(abd);

}

}

//创建BeanDefinitionHolder,就是把BeanDefinition包装了一下,添加了一些属性和方法。

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

//将启动类BeanDefinition注册到IOC容器的map中。

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

}

}

registerBeanDefinition()方法实际会调用BeanDefinitionRegistry的registerBeanDefinition()方法,它在DefaultListableBeanFactory实现类里实现的,之前说过这个就是IOC容器。

//DefaultListableBeanFactory.class

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 var8) {

throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);

}

}

//IOC容器beanFactory的beanDefinitionMap

BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);

if (existingDefinition != null) {

if (!this.isAllowBeanDefinitionOverriding()) {

throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);

}

if (existingDefinition.getRole() < beanDefinition.getRole()) {

if (this.logger.isInfoEnabled()) {

this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");

}

} else if (!beanDefinition.equals(existingDefinition)) {

if (this.logger.isDebugEnabled()) {

this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");

}

} else if (this.logger.isTraceEnabled()) {

this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");

}

this.beanDefinitionMap.put(beanName, beanDefinition);

} else {

if (this.hasBeanCreationStarted()) {

synchronized(this.beanDefinitionMap) {

this.beanDefinitionMap.put(beanName, beanDefinition);

List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);

updatedDefinitions.addAll(this.beanDefinitionNames);

updatedDefinitions.add(beanName);

this.beanDefinitionNames = updatedDefinitions;

this.removeManualSingletonName(beanName);

}

} else {

//启动阶段会走到这里,以beanName为key,beanDefinition为value存入beanDefinitionMap中

this.beanDefinitionMap.put(beanName, beanDefinition);

this.beanDefinitionNames.add(beanName);

this.removeManualSingletonName(beanName);

}

this.frozenBeanDefinitionNames = null;

}

if (existingDefinition == null && !this.containsSingleton(beanName)) {

if (this.isConfigurationFrozen()) {

this.clearByTypeCache();

}

} else {

this.resetBeanDefinition(beanName);

}

}

注册完之后可以看到demoApplication已经被添加到beanFactory的beanDefinitionMap中了。

image-20240908180912921

2.4、刷新上下文refreshContext()

Springboot最终在这里调用Spring的refresh()方法,从refreshContext()一直跟进去会到AbstractApplicationContext的refresh()方法。

<code>//AbstractApplicationContext.class

public void refresh() throws BeansException, IllegalStateException {

synchronized(this.startupShutdownMonitor) {

this.prepareRefresh();

//2.4.1 获取容器

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

//准备beanFactory,这个方法就是为beanFactory添加一些组件和配置,比如后置处理器、类加载器、依赖处理器等等

this.prepareBeanFactory(beanFactory);

try {

//在上下文添加一些BeanFactory后置处理器,处理器在beanDefinition加载完后,bean实例化之前执行

this.postProcessBeanFactory(beanFactory);

//2.4.2 调用BeanFactory后置处理器,这一步会进行IOC容器的初始化

this.invokeBeanFactoryPostProcessors(beanFactory);

//注册bean的后置处理器,上面是BeanFactory后置处理器

this.registerBeanPostProcessors(beanFactory);

this.initMessageSource();

this.initApplicationEventMulticaster();

this.onRefresh();

this.registerListeners();

//上面这些不看了,直接从这开始

//2.4.3 完成所有单例bean的初始化

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();

}

}

}

2.4.1 obtainFreshBeanFactory()获取容器

之前说过Springboot在创建应用上下文时,触发了GenericApplicationContext的构造函数,创建了beanFactory,这个方法就是获取之前创建的beanFactory。

//AbstractApplicationContext.class

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {

this.refreshBeanFactory();

return this.getBeanFactory();

}

这两个方法都是模板方法,由子类GenericApplicationContext实现

//GenericApplicationContext.class

protected final void refreshBeanFactory() throws IllegalStateException {

if (!this.refreshed.compareAndSet(false, true)) {

throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");

} else {

this.beanFactory.setSerializationId(this.getId());

}

}

public final ConfigurableListableBeanFactory getBeanFactory() {

return this.beanFactory;

}

2.4.2 invokeBeanFactoryPostProcessors()

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

...

//默认的beanFactoryPostProcessors有三个,SharedMetadataReaferFactoryContextInitializer、ConfigurationWArningsApplicationContextInitializer、ConfigFileApplicationListener

Iterator var6 = beanFactoryPostProcessors.iterator();

//循环将它们注册到beanDefinitionMap中

while(var6.hasNext()) {

BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();

if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {

BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;

registryProcessor.postProcessBeanDefinitionRegistry(registry);

registryProcessors.add(registryProcessor);

} else {

regularPostProcessors.add(postProcessor);

}

}

currentRegistryProcessors = new ArrayList();

//这里postProcessorNames是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,internalConfigurationAnnotationProcessor是专门用来处理Configuration注解的类。

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

String[] var16 = postProcessorNames;

var9 = postProcessorNames.length;

int var10;

String ppName;

for(var10 = 0; var10 < var9; ++var10) {

ppName = var16[var10];

if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

//通过getBean,从实例化了ConfigurationClassPostProcessor到容器中

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

}

}

sortPostProcessors(currentRegistryProcessors, beanFactory);

registryProcessors.addAll(currentRegistryProcessors);

//对于使用基于@Configuration注解和@bean注入的对象, 此时的processor类型为ConfigurationClassPostprocessor, 且在此处执行

//如果是@Autowired和@Value注解注入的对象,processor类型应该是AutowiredAnnotationBeanPostProcessor,这些东西是在AnnotationConfigUtils类下定义的

//2.4.2.1 进去重点看看此时的processor类型为ConfigurationClassPostprocessor的postProcessBeanDefinitionRegistry()做了什么

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

...

}

2.4.2.1 invokeBeanDefinitionRegistryPostProcessors()

一直跟进这个方法,知道ConfigurationClassPostProcessor.class中的parser.parse(candidates)方法,看下面这张图,这时候的只有这个启动类,接下来继续跟进这个方法。

image-20240909162509314

<code>//ConfigurationClassParser.class

public void parse(Set<BeanDefinitionHolder> configCandidates) {

Iterator var2 = configCandidates.iterator();

while(var2.hasNext()) {

BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();

BeanDefinition bd = holder.getBeanDefinition();

try {

//会走这里,之前看到过启动类是被封装成AnnotatedBeanDefinition的

if (bd instanceof AnnotatedBeanDefinition) {

this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());

} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {

this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());

} else {

this.parse(bd.getBeanClassName(), holder.getBeanName());

}

} catch (BeanDefinitionStoreException var6) {

throw var6;

} catch (Throwable var7) {

throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);

}

}

//springboot自动装配的入口

this.deferredImportSelectorHandler.process();

}

继续跟进parse()方法直到ConfigurationClassParser.class的doProcessConfigurationClass()方法。

//ConfigurationClassParser.class

protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {

...

do {

//主要就是这个方法进行处理

sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);

} while(sourceClass != null);

this.configurationClasses.put(configClass, configClass);

}

}

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {

//递归处理内部类,启动类是没有内部类的,如果是启动类这里进去什么都不做

if (configClass.getMetadata().isAnnotated(Component.class.getName())) {

this.processMemberClasses(configClass, sourceClass, filter);

}

//处理@PropertySource注解配置的属性,对于启动类来说,这里也没有

Iterator var4 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();

AnnotationAttributes importResource;

while(var4.hasNext()) {

importResource = (AnnotationAttributes)var4.next();

if (this.environment instanceof ConfigurableEnvironment) {

this.processPropertySource(importResource);

} else {

this.logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");

}

}

//处理@ComponentScan注解,扫描项目中的bean,启动类上包含这个注解

Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);

if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {

Iterator var14 = componentScans.iterator();

while(var14.hasNext()) {

AnnotationAttributes componentScan = (AnnotationAttributes)var14.next();

//2.4.2.2 扫描项目中的bean

Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

Iterator var8 = scannedBeanDefinitions.iterator();

while(var8.hasNext()) {

BeanDefinitionHolder holder = (BeanDefinitionHolder)var8.next();

BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();

if (bdCand == null) {

bdCand = holder.getBeanDefinition();

}

if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {

//todo:解析扫描到的bean,这里又循环会去了,可能是再从它们所在的包继续向下扫描?

this.parse(bdCand.getBeanClassName(), holder.getBeanName());

}

}

}

}

//2.4.2.3 递归处理@Import注解,SpringBoot中经常用的各种@Enable***注解基本都是封装的@Import

this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);

...

return null;

}

2.4.2.2 扫描bean

主要看看怎么从扫描bean的,这里会调用doScan()方法扫描bean,然后将beanDefinition注册到beanDefinitionMap中。

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {

...

for(int var5 = 0; var5 < var4; ++var5) {

String basePackage = var3[var5];

//从basePackage下找bean

Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage);

Iterator var8 = candidates.iterator();

while(var8.hasNext()) {

BeanDefinition candidate = (BeanDefinition)var8.next();

...

if (this.checkCandidate(beanName, candidate)) {

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);

definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

beanDefinitions.add(definitionHolder);

//注册beanDefinition

this.registerBeanDefinition(definitionHolder, this.registry);

}

}

}

return beanDefinitions;

}

执行完上面代码,看看扫描到了那些bean,这两个bean是我们提前写好的。

image-20240909171009383

<code>@Configuration

public class Config {

@Bean

public MyService getMyService(MyService myService){

return myService;

}

}

回到2.4.2.1的doProcessConfigurationClass(),此时代码执行到processImports()方法了,这个方法是处理@Import注解的。

2.4.2.3 processImports()

这个方法会处理@Import注解,这里主要从SpringBoot自动配置的角度看看这个方法,因为springboot开启自动配置的注解@EnableAutoConfiguration封装了@Import注解。进入processImports()代码。

image-20240909180847627

<code>private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {

//先看下面那段话

if (!importCandidates.isEmpty()) {

if (checkForCircularImports && this.isChainedImportOnStack(configClass)) {

this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));

} else {

this.importStack.push(configClass);

try {

Iterator var6 = importCandidates.iterator();

while(var6.hasNext()) {

SourceClass candidate = (SourceClass)var6.next();

Class candidateClass;

if (candidate.isAssignable(ImportSelector.class)) {

candidateClass = candidate.loadClass();

ImportSelector selector = (ImportSelector)ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class, this.environment, this.resourceLoader, this.registry);

Predicate<String> selectorFilter = selector.getExclusionFilter();

if (selectorFilter != null) {

exclusionFilter = exclusionFilter.or(selectorFilter);

}

//AutoConfigurationImportSelector会走这里

if (selector instanceof DeferredImportSelector) {

this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector)selector);

} else {

String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());

Collection<SourceClass> importSourceClasses = this.asSourceClasses(importClassNames, exclusionFilter);

this.processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);

}

} else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {

//ImportBeanDefinitionRegistrar会

candidateClass = candidate.loadClass();

ImportBeanDefinitionRegistrar registrar = (ImportBeanDefinitionRegistrar)ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class, this.environment, this.resourceLoader, this.registry);

configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());

} else {

//当真正需要注册需要自动配置的类时会走这里,不过要走到这里的入口是在2.4.2.1中提到的 this.deferredImportSelectorHandler.process()这个方法

this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());

//又回到了这个方法,在2.4.2.1介绍启动类注册的时候说过了,就是注册到把beanDefinition注册到Map中,那这里就是去注册那些自动配置类了。

this.processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);

}

}

} catch (BeanDefinitionStoreException var17) {

throw var17;

} catch (Throwable var18) {

throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", var18);

} finally {

this.importStack.pop();

}

}

}

}

看这张图,传入的两个importCandidates一个是ImportBeanDefinitionRegistrar类,一个是ImportSelector类,对于AutoConfigurationImportSelector,更准确的说他是一个DeferredImportSelector。从名字也能看出他是延迟执行的,所以这时并不会将自动配置的类注入近来,在2.4.2.1中说过,springboot自动配置的入口是在 this.deferredImportSelectorHandler.process()这个方法下。在看上面的代码,两个不同的类会走不同的if或else。

image-20240909180322097

一直跟进代码,直到走到this.deferredImportSelectorHandler.process()。这个方法在ConfigurationClassParser.class的parse()方法下。

<code>//ConfigurationClassParser.class

public void process() {

List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;

this.deferredImportSelectors = null;

try {

if (deferredImports != null) {

DeferredImportSelectorGroupingHandler handler = ConfigurationClassParser.this.new DeferredImportSelectorGroupingHandler();

deferredImports.sort(ConfigurationClassParser.DEFERRED_IMPORT_COMPARATOR);

deferredImports.forEach(handler::register);

//重点是这个

handler.processGroupImports();

}

} finally {

this.deferredImportSelectors = new ArrayList();

}

}

在跟进processGroupImports()方法。

//ConfigurationClassParser.class

public void processGroupImports() {

Iterator var1 = this.groupings.values().iterator();

while(var1.hasNext()) {

...

//调用getImport()方法去找spring.factories文件中的自动配置类

grouping.getImports().forEach((entry) -> {

ConfigurationClass configurationClass = (ConfigurationClass)this.configurationClasses.get(entry.getMetadata());

try {

//又到了这个方法了,之前也提过,会走processImports()的最后一个else

ConfigurationClassParser.this.processImports(configurationClass, ConfigurationClassParser.this.asSourceClass(configurationClass, exclusionFilter), Collections.singleton(ConfigurationClassParser.this.asSourceClass(entry.getImportClassName(), exclusionFilter)), exclusionFilter, false);

}

...

});

}

}

进入getImport()方法:

////ConfigurationClassParser.class

public Iterable<DeferredImportSelector.Group.Entry> getImports() {

Iterator var1 = this.deferredImports.iterator();

while(var1.hasNext()) {

DeferredImportSelectorHolder deferredImport = (DeferredImportSelectorHolder)var1.next();

//这里会调用Group接口的实现类AutoConfigurationImportSelector,执行process()方法将需要自动配置的类放到一个map中

this.group.process(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getImportSelector());

}

//调用AutoConfigurationImportSelector的selectImports()封装map然后返回需要自动配置的类

return this.group.selectImports();

}

DeferredImportSelector下定义了一个Group接口,AutoConfigurationImportSelector实现了这个接口,当程序运行到this.group.process(),会去调用AutoConfigurationImportSelector实现的process()。

public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {

Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector, () -> {

return String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName());

});

//getAutoConfigurationEntry()最终会调用SpringFactoriesLoader.loadFactoryNames()方法去加载spring.factories文件中的类

AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector)deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);

this.autoConfigurationEntries.add(autoConfigurationEntry);

Iterator var4 = autoConfigurationEntry.getConfigurations().iterator();

while(var4.hasNext()) {

String importClassName = (String)var4.next();

//将这些需要自动配置的类放到一个名为entries的map中

this.entries.putIfAbsent(importClassName, annotationMetadata);

}

}

image-20240912154757609

然后调用AutoConfigurationImportSelector的selectImports()封装map然后返回需要自动配置的类

image-20240912154941064

之后再回到ConfigurationClassParser的processGroupImports()方法执行后面的processImports()方法,这时才真正开始注册自动配置类的beanDefinition,这时的processImports()会进入processImports()的最后一个else,processConfigurationClass()这个方法前面说过了,将beanDefinition注册到Map中。

<code>//ConfigurationClassParser.class

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {

...

try {

Iterator var6 = importCandidates.iterator();

while(var6.hasNext()) {

...

} else {

this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());

this.processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);

}

}

}

...

}

这部分就到这里了,回到2.4。

2.4.3 finishBeanFactoryInitialization()初始化bean

之前只是将bean的beanDefinition注册到IOC容器中,但是还没有初始化,bean的完整生命周期是在这个方法中完成的。我们以自定义的bean为例来看看bean的初始化。跟进代码,到AbstractBeanFactory.class的doGetBean时在断点上添加条件,这个条件就是beanName=myController时才会进去。

image-20240910165937503

<code>//AbstractBeanFactory.class

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {

String beanName = this.transformedBeanName(name);

Object sharedInstance = this.getSingleton(beanName);

Object bean;

if (sharedInstance != null && args == null) {

//...

} else {

//...

try {

//获取bean的beanDefinition

RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);

this.checkMergedBeanDefinition(mbd, beanName, args);

//...

//如果是单例bean

if (mbd.isSingleton()) {

//获取bean,这里是从缓冲池里拿,在初始化bean的过程中会把他们放到缓冲池

sharedInstance = this.getSingleton(beanName, () -> {

try {

//bean的初始化过程是在这里完成的

return this.createBean(beanName, mbd, args);

} catch (BeansException var5) {

this.destroySingleton(beanName);

throw var5;

}

});

bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

} else if (mbd.isPrototype()) {

//...

} else {

//...

}

} catch (BeansException var26) {

this.cleanupAfterBeanCreationFailure(beanName);

throw var26;

}

}

//...

}

然后一直跟进代码createBean()方法,直到AbstractAutowireCapableBeanFactory.class的doCreateBean()方法,这里完成了bean的初始化,主要包括三个步骤:1、创建bean实例。2、为bean实例进行属性注入。3、调用bean的初始化方法。

//AbstractAutowireCapableBeanFactory.class

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);

}

if (instanceWrapper == null) {

//2.4.3.1 创建bean实例

instanceWrapper = this.createBeanInstance(beanName, mbd, args);

}

Object bean = instanceWrapper.getWrappedInstance();

//...

//如果bean是单例且允许循环引用且正在创建,暴露一个bean的早期对象工厂,放到三级缓存

boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);

if (earlySingletonExposure) {

//...

this.addSingletonFactory(beanName, () -> {

return this.getEarlyBeanReference(beanName, mbd, bean);

});

}

Object exposedObject = bean;

try {

//2.4.3.2 属性注入

this.populateBean(beanName, mbd, instanceWrapper);

//2.4.3.3 调用初始化方法

exposedObject = this.initializeBean(beanName, exposedObject, mbd);

} catch (Throwable var18) {

if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {

throw (BeanCreationException)var18;

}

throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);

}

if (earlySingletonExposure) {

Object earlySingletonReference = this.getSingleton(beanName, false);

if (earlySingletonReference != null) {

if (exposedObject == bean) {

exposedObject = earlySingletonReference;

} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {

String[] dependentBeans = this.getDependentBeans(beanName);

Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);

String[] var12 = dependentBeans;

int var13 = dependentBeans.length;

for(int var14 = 0; var14 < var13; ++var14) {

String dependentBean = var12[var14];

if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {

actualDependentBeans.add(dependentBean);

}

}

//...

}

}

}

try {

this.registerDisposableBeanIfNecessary(beanName, bean, mbd);

return exposedObject;

} catch (BeanDefinitionValidationException var16) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);

}

}

2.4.3.1 createBeanInstance()创建bean实例

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);

if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) &&

//...

} else {

Supplier<?> instanceSupplier = mbd.getInstanceSupplier();

if (instanceSupplier != null) {

return this.obtainFromSupplier(instanceSupplier, beanName);

} else if (mbd.getFactoryMethodName() != null) {

return this.instantiateUsingFactoryMethod(beanName, mbd, args);

} else {

//...

if (resolved) {

//...

} else {

Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);

if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {

ctors = mbd.getPreferredConstructors();

//对于myController这个我们自定义的bean,会进入instantiateBean()方法,通过BeanUtils创建bean实例

return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);

} else {

return this.autowireConstructor(beanName, mbd, ctors, args);

}

}

}

}

}

2.4.3.2 populateBean()属性注入

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

if (bw == null) {

//...

} else {

//...

boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();

//...

if (hasInstAwareBpps) {

if (pvs == null) {

pvs = mbd.getPropertyValues();

}

Iterator var9 = this.getBeanPostProcessors().iterator();

//使用后置处理器进行属性注入,对于通过@Autowired注入的属性,使用ImportAwareBeanPostProcessor这个处理器,用它完成属性注入,它是InstantiationAwareBeanPostProcessor的一个实现类。

while(var9.hasNext()) {

BeanPostProcessor bp = (BeanPostProcessor)var9.next();

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;

//假如MyController中注入了MyService,在这里会先去初始化MyService,流程和MyController一样,之后再回到MyController的生命周期进行属性注入。

PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);

//...

}

}

}

//...

}

}

进入postProcessProperties()看看注入逻辑。

//AutowriedAnnotationBeanPostProcessor.class

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {

//寻找要注入的属性

InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

try {

//注入

metadata.inject(bean, beanName, pvs);

return pvs;

} catch (BeanCreationException var6) {

throw var6;

} catch (Throwable var7) {

throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);

}

}

findAutowiringMetadata()可以找到要注入的属性,看下面的图,找到了要注入到MyController中的MyService。

image-20240910213820166

然后执行inject()方法进行注入,注入MyService时会先去初始化MyService,流程是一样的。

2.4.3.3 initializeBean()调用初始化方法

<code>protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

if (System.getSecurityManager() != null) {

AccessController.doPrivileged(() -> {

this.invokeAwareMethods(beanName, bean);

return null;

}, this.getAccessControlContext());

} else {

//调用Aware接口的实现,设置相关的beanName、beanClassLoader、BeanFactory等,自己定义的bean好像不会走这。

this.invokeAwareMethods(beanName, bean);

}

Object wrappedBean = bean;

if (mbd == null || !mbd.isSynthetic()) {

//在初始化之前调用BeanPostProcessor,为了方便扩展吧

wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);

}

try {

//调用初始化方法

this.invokeInitMethods(beanName, wrappedBean, mbd);

} catch (Throwable var6) {

throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);

}

if (mbd == null || !mbd.isSynthetic()) {

//初始化之后调用BeanPostProcessor

wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

}

return wrappedBean;

}

接下来看一下invokeInitMethods()方法,有两个初始化方法,第一个是实现InitializingBean接口并重写afterPropertiesSet()方法,第二种方法是设置init-method方法。springboot会判断我们有没有定义这些方法,如果有就按顺序执行就好了。

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {

//判断bean有没有实现InitializingBean接口并重写afterPropertiesSet()方法,如果判断为ture,那就调用afterPropertiesSet()方法进行初始化。

boolean isInitializingBean = bean instanceof InitializingBean;

if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {

if (this.logger.isTraceEnabled()) {

this.logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");

}

if (System.getSecurityManager() != null) {

try {

AccessController.doPrivileged(() -> {

((InitializingBean)bean).afterPropertiesSet();

return null;

}, this.getAccessControlContext());

} catch (PrivilegedActionException var6) {

throw var6.getException();

}

} else {

//调用afterPropertiesSet()进行初始化

((InitializingBean)bean).afterPropertiesSet();

}

}

//判断bean是否配置了init-method方法,如果判断为true,通过反射得到method对象,然后调用init-method,完成最后的初始化。

if (mbd != null && bean.getClass() != NullBean.class) {

String initMethodName = mbd.getInitMethodName();

if (StringUtils.hasLength(initMethodName) && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {

this.invokeCustomInitMethod(beanName, bean, mbd);

}

}

}

自定义这两种方法也很简单,如下:

//实现InitializingBean接口并重写afterPropertiesSet()方法

@Controller

public class MyController implements InitializingBean {

@Autowired

private MyService myService;

public void testController(){

return;

}

@Override

public void afterPropertiesSet() throws Exception {

System.out.println("method 1");

}

}

//配置了init-method方法

@Configuration

public class Config {

@Bean(initMethod = "test")

public MyService getMyService(MyService myService){

return myService;

}

}

@Service

public class MyService {

public void test(){

System.out.println("haha");

}

}

到这里单例bean就初始化完了,结束。

3、补充:循环依赖

Spring解决循环依赖的流程如下图所示。

没有AOP的情况下:

image-20240911223909057

Spring通过三级缓存解决循环依赖问题,假设A和B发生了循环依赖,在A的生命周期中,在A创建了实例之后,会生成一个A的对象工厂并将其放入三级缓存,在A进行属性注入时,发生A依赖了B,这时Spring会先去创建B,和A的流程一样,当B进行属性注入时发现依赖了A,这时Spring又会调用doGetBean()想去创建A,但是在创建A之前,会先调用getSingleton()方法从缓存中取,这时Spring从三级缓存中调用A的对象工厂来生成一个A的早期对象,然后把它放到二级缓存。将A注入B之后,B会走完剩下的生命周期,然后通过getSingleton()方法将B放入一级缓存。接下来,A会走完剩下的生命周期,并且会把A放入一级缓存。就这样,A和B就都初始化完了。

有AOP的情况下:

image-20240911223622854

AOP动态代理的处理一般是发生在bean初始化之后的,也就是initializeBean()方法中的最后执行applyBeanPostProcessorsAfterInitialization()时生成代理对象,但是当出现循环依赖时,可以发现bean的AOP代理提前发生了。我觉得将AOP代理提前才是为什么需要第三级缓存的原因把。

还是看上面这个例子,当A经过实例化createInstance之后,会生成一个早期bean工厂放入三级缓存,代码是这样的,可以看到它传入了一个lambda表达时,当三级缓存中的早期bean工厂执行getObject()时会触发这个lambda表达式调用getEarlyBeanReference(),也就是当B需要注入A时,需要走到这一步。如果A被AOP代理了,这个这个方法会去调wrapIfNecessary()方法生成A的代理对象。如果没有三级缓存,那么就无法提前生成bean的代理对象,那么B中就会注入A的原始对象,但是当A经过初始化之后再去生成AOP代理对象,就会出现多个A,这不符合单例模式。

<code>this.addSingletonFactory(beanName, () -> {

return this.getEarlyBeanReference(beanName, mbd, bean);

});



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。