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();
}
}
}
…
(图片来自于网络)
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)]