Spring原理学习系列之五:IOC原理之Bean加载

abd.setScope(scopeMetadata.getScopeName());

//生成bean配置类beanName

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

//通用注解解析到abd结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解

AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

// @Qualifier特殊限定符处理

if (qualifiers != null) {

for (Class<? extends Annotation> qualifier : qualifiers) {

if (Primary.class == qualifier) {

// 如果配置@Primary注解,则设置当前Bean为自动装配autowire时首选bean

abd.setPrimary(true);

}

else if (Lazy.class == qualifier) {

//设置当前bean为延迟加载

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

//按照名称将对应的bean注册到IOC容器中(在下一篇文章中进行介绍)

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

}

3、refresh():作用为刷新Spring的应用上下文;

刷新上下文的操作实际上是在AbstractApplicationContext中完成的。

public abstract class AbstractApplicationContext extends DefaultResourceLoader

implements ConfigurableApplicationContext {

@Override

public void refresh() throws BeansException, IllegalStateException {

synchronized (this.startupShutdownMonitor) {

// 准备上下文环境

prepareRefresh();

// 创建并初始化BeanFactory(这部分可以继续追踪,创建BeanFactory的过程)

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 填充BeanFactory功能

prepareBeanFactory(beanFactory);

try {

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

postProcessBeanFactory(beanFactory);

// 激活各种BeanFactory处理器

invokeBeanFactoryPostProcessors(beanFactory);

// 注册拦截Bean创建的Bean处理器,即注册 BeanPostProcessor

registerBeanPostProcessors(beanFactory);

// 初始化上下文中的资源文件,如国际化文件的处理等

initMessageSource();

// 初始化上下文事件广播器

initApplicationEventMulticaster();

// 给子类扩展初始化其他Bean

onRefresh();

// 在所有bean中查找listener bean,然后注册到广播器中

registerListeners();

// 初始化剩下的单例Bean(非延迟加载的)

finishBeanFactoryInitialization(beanFactory);

// 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人

finishRefresh();

}

catch (BeansException ex) {

if (logger.isWarnEnabled()) {

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

"cancelling refresh attempt: " + ex);

}

//销毁已经创建的Bean

destroyBeans();

//重置容器激活标签

cancelRefresh(ex);

// 异常抛出

throw ex;

}

finally {

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

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

resetCommonCaches();

}

}

}

在这里插入图片描述

二、Bean加载


在这里插入图片描述

(图片来自于网络)

AnnotationConfigApplicationContext继承了AbstractApplicationContext

ublic abstract class AbstractApplicationContext extends DefaultResourceLoader

implements ConfigurableApplicationContext {

@Override

public Object getBean(String name) throws BeansException {

assertBeanFactoryActive();

return getBeanFactory().getBean(name);

}

}

BeanFactory接口主要的实现是在AbstractBeanFactory中完成,doGetBean接收以下四个参数:

(1)name:准备获取 bean 的名字

(2)requiredType:准备获取 bean 的类型

(3)args:创建 bean 时传递的参数。这个参数仅限于创建 bean 时使用

(4)typeCheckOnly:是否为类型检查

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

@Override

public Object getBean(String name) throws BeansException {

return doGetBean(name, null, null, false);

}

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

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

//转换Bean名称

final String beanName = transformedBeanName(name);

Object bean;

// 从缓存中或者实例工厂中获取 bean

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

}

}

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

}

else {

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

// We’re assumably within a circular reference.

if (isPrototypeCurrentlyInCreation(beanName)) {

throw new BeanCurrentlyInCreationException(beanName);

}

// 如果容器中没有找到,则从父类容器中加载

BeanFactory parentBeanFactory = getParentBeanFactory();

if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

// Not found -> check parent.

String nameToLookup = originalBeanName(name);

if (parentBeanFactory instanceof AbstractBeanFactory) {

return ((AbstractBeanFactory) parentBeanFactory).doGetBean(

nameToLookup, requiredType, args, typeCheckOnly);

}

else if (args != null) {

// Delegation to parent with explicit args.

return (T) parentBeanFactory.getBean(nameToLookup, args);

}

else if (requiredType != null) {

// No args -> delegate to standard getBean method.

return parentBeanFactory.getBean(nameToLookup, requiredType);

}

else {

return (T) parentBeanFactory.getBean(nameToLookup);

}

}

if (!typeCheckOnly) {

markBeanAsCreated(beanName);

}

try {

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

checkMergedBeanDefinition(mbd, beanName, args);

// 获取依赖的 Bean

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

}

}

}

// 开始创建 Bean 实例,如果是单例的,那么会创建一个单例的匿名工厂,如果是原型模式的,则不需要创建单例的工厂的,其他的如 request、session 作用域的,则根据自身的需要

if (mbd.isSingleton()) {

sharedInstance = getSingleton(beanName, () -> {

try {

return createBean(beanName, mbd, args);

}

catch (BeansException ex) {

// Explicitly remove instance from singleton cache: It might have been put there

// eagerly by the creation process, to allow for circular reference resolution.

// Also remove any beans that received a temporary reference to the bean.

destroySingleton(beanName);

throw ex;

}

});

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

}

else if (mbd.isPrototype()) {

// It’s a prototype -> create a new instance.

Object prototypeInstance = null;

最后

面试题文档来啦,内容很多,485页!

由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。

1111道Java工程师必问面试题

MyBatis 27题 + ZooKeeper 25题 + Dubbo 30题:

Elasticsearch 24 题 +Memcached + Redis 40题:

Spring 26 题+ 微服务 27题+ Linux 45题:

Java面试题合集:

ect prototypeInstance = null;

最后

面试题文档来啦,内容很多,485页!

由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。

1111道Java工程师必问面试题

[外链图片转存中…(img-tAA8mJv2-1714503402787)]

MyBatis 27题 + ZooKeeper 25题 + Dubbo 30题:

[外链图片转存中…(img-rGxI0vF3-1714503402788)]

Elasticsearch 24 题 +Memcached + Redis 40题:

[外链图片转存中…(img-xMBNI0YD-1714503402789)]

Spring 26 题+ 微服务 27题+ Linux 45题:

[外链图片转存中…(img-UqU2iPYN-1714503402789)]

Java面试题合集:

[外链图片转存中…(img-nC9Gn9xl-1714503402790)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值