bean覆盖 springboot_SpringBoot——bean解析

本文详细介绍了SpringBoot中bean的控制反转(IOC)和依赖注入(DI)原理,探讨了两者的关系,并展示了XML与注解两种方式配置bean的过程。内容涵盖了bean的创建、初始化、优缺点以及refresh方法解析,揭示了SpringApplication运行时容器的刷新步骤。
摘要由CSDN通过智能技术生成

IOC思想解析

IOC(控制反转):全称为:Inverse of Control。从字面上理解就是控制反转了,将对在自身对象中的一个内置对象的控制反转,反转后不再由自己本身的对象进行控制这个内置对象的创建,而是由第三方系统去控制这个内置对象的创建。

DI(依赖注入):全称为Dependency Injection,意思自身对象中的内置对象是通过注入的方式进行创建。

那么IOC和DI这两者又是什么关系呢?

IOC就是一种软件设计思想,DI是这种软件设计思想的一个实现。

把本来在类内部控制的对象,反转到类外部进行创建后注入,不再由类本身进行控制,这就是IOC的本质。

xml方式配置bean

利用标签进行注入

...

...

优点:

低耦合

对象关系清晰

集中管理

缺点:

配置繁琐

开发效率较低

文件解析耗时

注解方式配置bean

1、使用@Component声明

2、配置类中使用@Bean

3、实现FactoryBean

@Component

public class MyCat implements FactoryBean {

@Override

public Animal getObject() throws Exception {

return new Cat();

}

@Override

public Class> getObjectType() {

return Animal.class;

}

}

4、实现BeanDefinitionRegistryPostProcessor

@Component

public class MyBeanRegister implements BeanDefinitionRegistryPostProcessor {

@Override

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {

RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();

rootBeanDefinition.setBeanClass(Dog.class);

beanDefinitionRegistry.registerBeanDefinition("dog",rootBeanDefinition);

}

@Override

public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

}

}

5、实现ImportBeanDefinitionRegistry

public class MyBeanImport implements ImportBeanDefinitionRegistrar {

@Override

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();

rootBeanDefinition.setBeanClass(Bird.class);

registry.registerBeanDefinition("bird",rootBeanDefinition);

}

}

@Component

public class HelloService {

@Autowired

@Qualifier("bird")

private Animal animal;

public String hello(){

return animal.getName();

}

}

@RunWith(SpringRunner.class)

@SpringBootTest

@Import(MyBeanImport.class)

public class ApplicationTest {

@Autowired

private HelloService helloService;

@Test

public void test(){

System.out.println(helloService.hello());

}

}

优点:

使用简单

开发效率高

高内聚

缺点:

配置分散

对象关系不清晰

修改配置需要重新编译工程

refresh方法解析

完成了SpringApplication的run方法:

public ConfigurableApplicationContext run(String... args) {

// 计时工具

StopWatch stopWatch = new StopWatch();

stopWatch.start();

ConfigurableApplicationContext context = null;

Collection exceptionReporters = new ArrayList();

this.configureHeadlessProperty();

// 第一步:获取并启动监听器

SpringApplicationRunListeners listeners = this.getRunListeners(args);

listeners.starting();

Collection exceptionReporters;

try {

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

// 第二步:根据SpringApplicationRunListeners以及参数来准备环境

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

this.configureIgnoreBeanInfo(environment);

// 准备Banner打印器 - 就是启动Spring Boot的时候打印在console上的ASCII艺术字体

Banner printedBanner = this.printBanner(environment);

// 第三步:创建Spring容器

context = this.createApplicationContext();

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

// 第四步:Spring容器前置处理

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

// 第五步:刷新容器

this.refreshContext(context);

// 第六步:Spring容器后置处理

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 {

// 第八步:执行Runners

listeners.running(context);

// 返回容器

return context;

} catch (Throwable var9) {

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

throw new IllegalStateException(var9);

}

}

第一步:获取并启动监听器

第二步:根据SpringApplicationRunListeners以及参数来准备环境

第三步:创建Spring容器

第四步:Spring容器前置处理

第五步:刷新容器

第六步:Spring容器后置处理

第七步:发出结束执行的事件

第八步:执行Runners

这里从创建Spring容器说起:

context = createApplicationContext();

继续跟进该方法:

protected ConfigurableApplicationContext createApplicationContext() {

Class> contextClass = this.applicationContextClass;

if (contextClass == null) {

try {

switch (this.webApplicationType) {

case SERVLET:

contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);

break;

case REACTIVE:

contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);

break;

default:

contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);

}

}

catch (ClassNotFoundException ex) {

throw new IllegalStateException(

"Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass",

ex);

}

}

return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);

}

这里创建容器的类型 还是根据webApplicationType进行判断的,该类型为SERVLET类型,所以会通过反射装载对应的字节码,也就是AnnotationConfigServletWebServerApplicationContext

第四步:Spring容器前置处理

这一步主要是在容器刷新之前的准备动作。包含一个非常关键的操作:将启动类注入容器,为后续开启自动化配置奠定基础。

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

继续跟进该方法:

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,

SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {

//设置容器环境,包括各种变量

context.setEnvironment(environment);

//执行容器后置处理

postProcessApplicationContext(context);

//执行容器中的ApplicationContextInitializer(包括 spring.factories和自定义的实例)

applyInitializers(context);

//发送容器已经准备好的事件,通知各监听器

listeners.contextPrepared(context);

if (this.logStartupInfo) {

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

logStartupProfileInfo(context);

}

// Add boot specific singleton beans

//注册启动参数bean,这里将容器指定的参数封装成bean,注入容器

ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

beanFactory.registerSingleton("springApplicationArguments", applicationArguments);

//设置banner

if (printedBanner != null) {

beanFactory.registerSingleton("springBootBanner", printedBanner);

}

if (beanFactory instanceof DefaultListableBeanFactory) {

((DefaultListableBeanFactory) beanFactory)

.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);

}

// Load the sources

//获取我们的启动类指定的参数,可以是多个

Set sources = getAllSources();

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

//加载我们的启动类,将启动类注入容器

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

//发布容器已加载事件。

listeners.contextLoaded(context);

}

调用初始化器:

protected void applyInitializers(ConfigurableApplicationContext context) {

// 1. 从SpringApplication类中的initializers集合获取所有的ApplicationContextInitializer

for (ApplicationContextInitializer initializer : getInitializers()) {

// 2. 循环调用ApplicationContextInitializer中的initialize方法

Class> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),

ApplicationContextInitializer.class);

Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");

initializer.initialize(context);

}

}

这里终于用到了在创建SpringApplication实例时设置的初始化器了,依次对它们进行遍历,并调用initialize方法。我们也可以自定义初始化器,并实现initialize方法,然后放入META-INF/spring.factories配置文件中Key为:org.springframework.context.ApplicationContextInitializer的value中,这里我们自定义的初始化器就会被调用,是我们项目初始化的一种方式

加载启动指定类(重点)

大家先回到文章最开始看看,在创建SpringApplication实例时,先将HelloWorldMainApplication.class存储在this.primarySources属性中,现在就是用到这个属性的时候了,我们来看看getAllSources()

public Set getAllSources() {

Set allSources = new LinkedHashSet<>();

if (!CollectionUtils.isEmpty(this.primarySources)) {

//获取primarySources属性,也就是之前存储的HelloWorldMainApplication.class

allSources.addAll(this.primarySources);

}

if (!CollectionUtils.isEmpty(this.sources)) {

allSources.addAll(this.sources);

}

return Collections.unmodifiableSet(allSources);

}

很明显,获取了this.primarySources属性,也就是我们的启动类HelloWorldMainApplication.class,我们接着看load(context, sources.toArray(new Object[0]));

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

if (logger.isDebugEnabled()) {

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

}

BeanDefinitionLoader loader = createBeanDefinitionLoader(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();

}

private int load(Class> source) {

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

// Any GroovyLoaders added in beans{} DSL can contribute beans here

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

load(loader);

}

if (isComponent(source)) {

//以注解的方式,将启动类bean信息存入beanDefinitionMap,也就是将Application.class存入了beanDefinitionMap

this.annotatedReader.register(source);

return 1;

}

return 0;

}

启动类Application.class被加载到 beanDefinitionMap中,后续该启动类将作为开启自动化配置的入口,后面一篇文章我会详细的分析,启动类是如何加载,以及自动化配置开启的详细流程。

通知监听器,容器已准备就绪

listeners.contextLoaded(context);

主还是针对一些日志等监听器的响应处理。

第五步:刷新容器

refresh()方法刷新容器的步骤:

执行到这里,springBoot相关的处理工作已经结束,接下的工作就交给了spring。我们来看看refreshContext(context);

protected void refresh(ApplicationContext applicationContext) {

Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);

//调用创建的容器applicationContext中的refresh()方法

((AbstractApplicationContext) applicationContext).refresh();

}

public abstract class AbstractApplicationContext extends DefaultResourceLoader

implements ConfigurableApplicationContext {

@Override

public void refresh() throws BeansException, IllegalStateException {

synchronized (this.startupShutdownMonitor) {

// Prepare this context for refreshing.

/**

* 刷新上下文环境

* 容器状态设置

* 初始化属性设置

* 检查必备属性是否存在

*/

prepareRefresh();

// Tell the subclass to refresh the internal bean factory.

/**

* 设置beanFactory序列化id

* 获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的

*/

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.

/**

* //BeanFactory的预准备工作

* BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等

* 设置忽略的自动装配接口,以及注册一些组件

*/

prepareBeanFactory(beanFactory);

try {

// Allows post-processing of the bean factory in context subclasses.

/**

* 提供子类覆盖的额外处理,即子类处理自定义的BeanFactoryPostProcess

*/

postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.

/**

* 激活各种BeanFactory处理器,包括BeanDefinitionRegistryBeanFactoryPostProcessor和普通的BeanFactoryPostProcessor

* 执行对应的postProcessBeanDefinitionRegistry方法 和 postProcessBeanFactory方法

* 调用BeanDefinitionRegistryBeanFactoryPostProcessor实现向容器内添加bean的定义

* 调用BeanFactoryPostProcessor实现向容器内bean的定义添加属性

*/

invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.

/**

* 注册拦截Bean创建的Bean处理器,即注册BeanPostProcessor,不是BeanFactoryPostProcessor,注意两者的区别

* 注意,这里仅仅是排序后注册,并不会执行对应的方法,将在bean的实例化时执行对应的方法

*/

registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.

/**

* 初始化MessageSource组件(做国际化功能;消息绑定,消息解析);

*/

initMessageSource();

// Initialize event multicaster for this context.

/**

* 初始化上下文事件广播器,并放入applicatioEventMulticaster,如ApplicationEventPublisher

*/

initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.

/**

* 子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器

*/

onRefresh();

// Check for listener beans and register them.

/**

* 注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,

* 这些监听器是注册到ApplicationEventMulticaster中的

*/

registerListeners();

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

/**

* 初始化所有剩下的非懒加载的单例bean

*/

finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.

/**

* 完成context的刷新,初始化生命周期处理器,调用LifecycleProcessor的onRefresh()方法,

* 并且发布事件(ContextRefreshedEvent)

*/

finishRefresh();

}

catch (BeansException ex) {

if (logger.isWarnEnabled()) {

logger.warn("Exception encountered during context initialization - " +

"cancelling refresh attempt: " + ex);

}

// Destroy already created singletons to avoid dangling resources.

destroyBeans();

// Reset 'active' flag.

cancelRefresh(ex);

// Propagate exception to caller.

throw ex;

}

finally {

// Reset common introspection caches in Spring's core, since we

// might not ever need metadata for singleton beans anymore...

resetCommonCaches();

}

}

}

}

refresh方法在spring整个源码体系中举足轻重,是实现 ioc 和 aop的关键。

第六步:Spring容器后置处理

protected void afterRefresh(ConfigurableApplicationContext context,

ApplicationArguments args) {

}

扩展接口,设计模式中的模板方法,默认为空实现。如果有自定义需求,可以重写该方法。比如打印一些启动结束log,或者一些其它后置处理。

第七步:发出结束执行的事件

public void started(ConfigurableApplicationContext context) {

for (SpringApplicationRunListener listener : this.listeners) {

//执行EventPublishingRunListener的started方法

listener.started(context);

}

}

@Override

public void started(ConfigurableApplicationContext context) {

//创建ApplicationStartedEvent事件,并且发布事件

//我们看到是执行的ConfigurableApplicationContext这个容器的publishEvent方法,和前面的starting是不同的

context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));

}

获取EventPublishingRunListener监听器,并执行其started方法,并且将创建的Spring容器传进去了,创建一个ApplicationStartedEvent事件,并执行ConfigurableApplicationContext 的publishEvent方法,也就是说这里是在Spring容器中发布事件,并不是在SpringApplication中发布事件,和前面的starting是不同的,前面的starting是直接向SpringApplication中的11个监听器发布启动事件。

第八步:执行Runners

我们再来看看最后一步callRunners(context, applicationArguments);

private void callRunners(ApplicationContext context, ApplicationArguments args) {

List runners = new ArrayList<>();

//获取容器中所有的ApplicationRunner的Bean实例

runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());

//获取容器中所有的CommandLineRunner的Bean实例

runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());

AnnotationAwareOrderComparator.sort(runners);

for (Object runner : new LinkedHashSet<>(runners)) {

if (runner instanceof ApplicationRunner) {

//执行ApplicationRunner的run方法

callRunner((ApplicationRunner) runner, args);

}

if (runner instanceof CommandLineRunner) {

//执行CommandLineRunner的run方法

callRunner((CommandLineRunner) runner, args);

}

}

}

如果是ApplicationRunner的话,则执行如下代码:

private void callRunner(ApplicationRunner runner, ApplicationArguments args) {

try {

(runner).run(args);

}

catch (Exception ex) {

throw new IllegalStateException("Failed to execute ApplicationRunner", ex);

}

}

如果是CommandLineRunner的话,则执行如下代码:

private void callRunner(CommandLineRunner runner, ApplicationArguments args) {

try {

(runner).run(args.getSourceArgs());

}

catch (Exception ex) {

throw new IllegalStateException("Failed to execute CommandLineRunner", ex);

}

}

我们也可以自定义一些ApplicationRunner或者CommandLineRunner,实现其run方法,并注入到Spring容器中,在SpringBoot启动完成后,会执行所有的runner的run方法

至此,SpringApplication大概分析了一遍。

bean实例化解析

finishBeanFactoryInitialization(beanFactory)方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

跟踪到AbstractApplicationContext.refresh()方法,找到代码finishBeanFactoryInitialization(beanFactory)查看实现。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

// Initialize conversion service for this context.

// 1.初始化此上下文的转换服务

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.

// 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析

if (!beanFactory.hasEmbeddedValueResolver()) {

beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));

}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.

// 3.初始化LoadTimeWeaverAware Bean实例对象

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.

// 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了

beanFactory.freezeConfiguration();

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

// 5.实例化所有剩余(非懒加载)单例对象

beanFactory.preInstantiateSingletons();

}

继续跟踪到DefaultListableBeanFactory#preInstantiateSingletons

@Override

public void preInstantiateSingletons() throws BeansException {

if (logger.isTraceEnabled()) {

logger.trace("Pre-instantiating singletons in " + this);

}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.

// While this may not be part of the regular factory bootstrap, it does otherwise work fine.

List beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...

//遍历beanNames,触发所有非懒加载单例bean的初始化

for (String beanName : beanNames) {

RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

//Bean实例:不是抽象类 && 是单例 && 不是懒加载

if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

//判断beanName对应的bean是否为FactoryBean

if (isFactoryBean(beanName)) {

//通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例

Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);

if (bean instanceof FactoryBean) {

final FactoryBean> factory = (FactoryBean>) bean;

//判断这个FactoryBean是否希望急切的初始化

boolean isEagerInit;

if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {

isEagerInit = AccessController.doPrivileged((PrivilegedAction)

((SmartFactoryBean>) factory)::isEagerInit,

getAccessControlContext());

}

else {

isEagerInit = (factory instanceof SmartFactoryBean &&

((SmartFactoryBean>) factory).isEagerInit());

}

if (isEagerInit) {

//如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例

getBean(beanName);

}

}

}

else {

getBean(beanName);

}

}

}

// Trigger post-initialization callback for all applicable beans...

for (String beanName : beanNames) {

Object singletonInstance = getSingleton(beanName);

if (singletonInstance instanceof SmartInitializingSingleton) {

final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;

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

AccessController.doPrivileged((PrivilegedAction) () -> {

smartSingleton.afterSingletonsInstantiated();

return null;

}, getAccessControlContext());

}

else {

smartSingleton.afterSingletonsInstantiated();

}

}

}

}

要理解FactoryBean和Bean的区别

一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化 bean。而FactoryBean 是一种特殊的 bean,它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了FactoryBean 接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject() 方法。

注:很多中间件都利用 FactoryBean 来进行扩展。

引入了几个重要的缓存:

mergedBeanDefinitions 缓存:beanName -> 合并的 bean 定义。

beanDefinitionMap 缓存:beanName -> BeanDefinition。

singletonObjects 缓存:beanName -> 单例 bean 对象。

earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。

singletonFactories 缓存:beanName -> ObjectFactory。

singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。

继续跟踪到AbstractBeanFactory#doGetBean创建bean

protected T doGetBean(final String name, @Nullable final Class requiredType,

@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

//解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”

final String beanName = transformedBeanName(name);

Object bean;

// Eagerly check singleton cache for manually registered singletons.

//尝试从缓存中获取beanName对应的实例,通过缓存解决循环依赖问题

Object sharedInstance = getSingleton(beanName);

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 + "'");

}

}

//返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

}

else {

// Fail if we're already creating this bean instance:

// We're assumably within a circular reference.

// scope为prototype非单例的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。

// 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖

if (isPrototypeCurrentlyInCreation(beanName)) {

throw new BeanCurrentlyInCreationException(beanName);

}

// Check if bean definition exists in this factory.

BeanFactory parentBeanFactory = getParentBeanFactory();

//如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例

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

//如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存

markBeanAsCreated(beanName);

}

try {

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.

//拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean,如使用@DependsOn

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

//scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法,在里面创建bean

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;

}

});

//返回beanName对应的实例对象

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

}

//其它非单例的情况,暂不分析

......

}

catch (BeansException ex) {

cleanupAfterBeanCreationFailure(beanName);

throw ex;

}

}

return (T) bean;

}

查看DefaultSingletonBeanRegistry#getSingleton

public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {

Assert.notNull(beanName, "Bean name must not be null");

synchronized (this.singletonObjects) {

//首先检查beanName对应的bean实例是否在缓存中存在,如果已经存在,则直接返回

Object singletonObject = this.singletonObjects.get(beanName);

if (singletonObject == null) {

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放入正准备创建的一个Set中singletonsCurrentlyInCreation,如果重复会报异常

//如果存在构造器循环依赖的时候(A(B b),B(C c),C(A a)),会在这点报出异常

beforeSingletonCreation(beanName);

boolean newSingleton = false;

boolean recordSuppressedExceptions = (this.suppressedExceptions == null);

if (recordSuppressedExceptions) {

this.suppressedExceptions = new LinkedHashSet<>();

}

try {

//执行singletonFactory的getObject方法获取bean实例,就是执行传入方法createBean

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;

}

//创建单例后的操作,在singletonsCurrentlyInCreation中移除

afterSingletonCreation(beanName);

}

if (newSingleton) {

addSingleton(beanName, singletonObject);

}

}

return singletonObject;

}

}

继承跟踪AbstractAutowireCapableBeanFactory#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.

Class> resolvedClass = resolveBeanClass(mbd, beanName);

if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {

mbdToUse = new RootBeanDefinition(mbd);

mbdToUse.setBeanClass(resolvedClass);

}

// Prepare method overrides.

try {

//验证及准备覆盖的方法(对override属性进行标记及验证)

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.

//实例化前的处理,如果有实现InstantiationAwareBeanPostProcessor的BeanPostProcessor可以直接返回真正的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 {

//创建Bean实例(一般真正创建Bean的方法)

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

if (logger.isTraceEnabled()) {

logger.trace("Finished creating instance of bean '" + beanName + "'");

}

return beanInstance;

}

catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {

// A previously detected exception with proper bean creation context already,

// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.

throw ex;

}

catch (Throwable ex) {

throw new BeanCreationException(

mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);

}

}

实例化前的处理,给 InstantiationAwareBeanPostProcessor 一个机会返回代理对象来替代真正的 bean 实例,从而跳过 Spring 默认的实例化过程,达到“短路”效果。会执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。

查看AbstractAutowireCapableBeanFactory#doCreateBean,这个方法非常重要

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)

throws BeanCreationException {

// Instantiate the bean.

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

}

if (instanceWrapper == null) {

//根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrappe

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

// 这里获取出来的对象是原生对象!!!!!

final Object bean = instanceWrapper.getWrappedInstance();

Class> beanType = instanceWrapper.getWrappedClass();

if (beanType != NullBean.class) {

mbd.resolvedTargetType = beanType;

}

// Allow post-processors to modify the merged bean definition.

synchronized (mbd.postProcessingLock) {

if (!mbd.postProcessed) {

try {

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

}

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.

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

}

//注意这点,曝光beanName的ObjectFactory,用于解决循环引用。 在开始通过doGetBean取值的时候调用了getSingleton就调用到这个工厂来了

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

}

// Initialize the bean instance.

Object exposedObject = bean;

try {

//对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例

//设置属性,非常重要,比如使用@Autowired注入的值等

populateBean(beanName, mbd, instanceWrapper);

//经过AOP处理,原生对象转换成了代理对象,跟进去

//执行后置处理器,aop就是在这里完成的处理

exposedObject = initializeBean(beanName, exposedObject, mbd);

}

......

return exposedObject;

}

实例化对象createBeanInstance,就是选出一个策略来实例化一个对象, 那有什么策略呢? 这就看程序员是怎么配置的了, 程序员可以配置工厂方法,指定构造方法,或者是程序员没有做出任何干涉,让Spring按自己的方式去实例化

BeanDefinition介绍

一个对象在Spring中的描述,RootBeanDefinition是其常见实现

通过操作BeanDefinition来完成bean实例化和属性注入

BeanDefinition类图

自定义创建Bean

实例化流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值