之前我们知道了spring ioc的加载过程, 具体如下图. 下面我们就来对照下图, 看看ioc加载的源代码.

下面在用装修类比, 看看个个组件都是怎么工作的.

接下来是源码分析的整体结构图. 对照上面的思路梳理出来的

一、源码分析的入口

通常,我们的入口都是从main方法进入. 这里我们也来定义一个main方法

public class MainStarter {
public static void main(String[] args) {
// 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
context.scan("package name");
Car car = (Car) context.getBean("car");
System.out.println(car.getName());
context.close();
}
}

顺便再来看看还有哪些相关的类

/**
* 这是一个配置类,
* 在配置类里面定义了扫描的包路径com.lxl.www.iocbeanlifecicle
* 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
*/
@Configuration
@ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
public class MainConfig {
}

这个类有一个注解@Configuration, 这样这个类会被扫描成bean

还有一个注解@ComponentScan(backPackage = {"com.lxl.www.iocbeanlifecicle"}) 他表示, 请扫描com.lxl.www.iocbeanlifecicle包下所有的类.

com.lxl.www.iocbeanlifecicle 这个包下还有哪些类呢? 我们来看看项目结构

这是这个包下完整的项目结构.

下面会逐渐说明, 每个类的用途

二. 最重要的类BeanFactory

我们知道在将一个class加载为bean的过程中BeanFactory是最最重要的, 那么他是何时被加载的呢?

我们来跟踪一下带有一个参数的构造方法AnnotationConfigApplicationContext

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 进入构造函数, 首先调用自身的构造方法this();
// 调用自身的构造方法之前, 要先调用父类的构造方法
this();
// retister配置注册类
register(componentClasses);
// ioc容器shua新接口--非常重要
refresh();
}

这就是AnnotationConfigApplicationContext初始化的时候做的三件事

第一件事:  this();  //调用自身的无参构造方法. 同时调用父类的构造方法

第二件事: register(componentClasses); // 调用注册器, 这里会加载两个BeanDefinitionReader和BeanDefinitionScanner. 这两位的角色是什么呢? 可以回忆一下之前的框架图

第三件事: refresh();  // 这是ioc容器刷新, 非常重要. 无论是spring boot还是spring mvc都有这个方法. 这个方法包含了整个spring ioc加载的全生命流程. 也是我们要重点学习的方法

下面来看看BeanFactory是何时被加载进来的呢?

在初始化方法的时候调用了自身的无参构造函数, 在调用自身无参构造函数的时候, 同时会调用父类的无参构造函数.

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
  ......
}

父类是GenericApplicationContext, 其无参构造函数就做了一件事

   public GenericApplicationContext() {
// 构造了一个BeanFactory.
// 在调用GenericApplicationContext父类构造函数, 为ApplicationContext spring上下文对象初始化beanFactory
// 为什么初始化的是DefaultListableBeanFactory呢?
// 我们在看BeanFactory接口的时候发现DefaultListableBeanFactory是最底层的实现, 功能是最全的.
// 查看
this.beanFactory = new DefaultListableBeanFactory();
}

初始化DefaultListableBeanFactory.

问题: BeanFactory有很多, 为什么初始化的时候选择DefaultListableBeanFactory呢?

我们来看看DefaultListableBeanFactory的结构. 快捷键option + command + u --> Java Class Diagrams

通过观察, 我们发现, DefaultListableBeanFactory实现了各种各样的BeanFactory接口, 同时还是先了BeanDefinitionRegistry接口.

也就是说, DefaultListableBeanFactory不仅仅有BeanFactory的能力, 同时还有BeanDefinitionRegistry的能力. 它的功能是最全的.

所以, 我们使用的是一个功能非常强大的类Bean工厂类.

AnnotationConfigApplicationContext继承了GenericApplicationContext,

而 GenericApplicationContext 实现了AnnotationConfigRegistry接口.

所以AnnotationConfigApplicationContext有AnnotationConfigRegistry的能力.

三. bean定义读取器AnnotatedBeanDefinitionReader

接着上面, 第一步调用的是this(). 也就是AnnotationConfigApplicationContext的无参构造函数. 在这个无参构造函数里一共做了两件事情

    public AnnotationConfigApplicationContext() {
/**
* 创建了一个Bean定义的读取器.
* 完成了spring内部BeanDefinition的注册(主要是后置处理器)
* 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
*/
this.reader = new AnnotatedBeanDefinitionReader(this); /**
* 创建BeanDefinition扫描器
* 可以用来扫描包或者类, 进而转换为bd
*
* Spring默认的扫描包不是这个scanner对象
* 而是自己new的一个ClassPathBeanDefinitionScanner
* Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
*
* 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
* 通过调用context.scan("package name");扫描处理配置类
* 扫描
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

1. 初始化AnnotatedBeanDefinitionReader.

2. 初始化ClassPathBeanDefinitionScanner

我们先来看看AnnotatedBeanDefinitionReader

在这里的描述中, 我们知道BeanDefinitionReader是要去扫描配置或者注解, 如果理解为销售的话, 就是扫描楼盘. 这里面就有我们的潜在用户. 也就是我们需要将其转换为bean的对象.

那么初始化的时候,AnnotatedBeanDefinitionReader做了什么呢?

重点看这句

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
     // 注册注解类型配置的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

注册注解类型配置的处理器

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

   /**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) { // 获取到beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
/**
* 判断beanFactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
* 没有则添加
*/

if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
} // BeanDefinitionHolder: 为BeanDefinition设置名字和别名
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); // 1. 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器, 就添加一个
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// 构建BeanDefinitionHolder, 并添加到beanDefs
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
} // 2. 如果rigistry中, 没有AutowiredAnnotationBeanPostProcessor Autowired注解bean的后置处理器, 则添加一个
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
// 构建BeanDefinitionHolder, 并添加到beanDefs
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
} // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
// 3. 检查对JSR-250的支持, 如果rigistry中没有CommonAnnotationBeanPostProcessor通用注解后置处理器, 则添加一个

if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
// 构建BeanDefinitionHolder, 并添加到beanDefs
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
} // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
// 4. 检查对jpa的支持, 如果不包含internalPersistenceAnnotationProcessor, 持久化注解处理器, 就添加一个

if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
} // 5. 检查对事件监听的支持, 如果不包含事件监听处理器internalEventListenerProcessor, 就添加一个
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
} // 6. 如果不包含事件监听工厂处理器internalEventListenerFactory , 就添加一个
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
} return beanDefs;
}

在这里注册了6个后置处理器.

四. bean定义扫描器ClassPathBeanDefinitionScanner

  public AnnotationConfigApplicationContext() {
/**
* 创建了一个Bean定义的读取器.
* 完成了spring内部BeanDefinition的注册(主要是后置处理器)
* 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
*/
this.reader = new AnnotatedBeanDefinitionReader(this); /**
* 创建BeanDefinition扫描器
* 可以用来扫描包或者类, 进而转换为bd
*
* Spring默认的扫描包不是这个scanner对象
* 而是自己new的一个ClassPathBeanDefinitionScanner
* Spring在执行工程后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner
*
* 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
* 通过调用context.scan("package name");扫描处理配置类
* 扫描
*/
this.scanner = new ClassPathBeanDefinitionScanner(this
);
}

主要看加粗的部分. 这部分初始化了BeanDefinition扫描器. 这里的这个scanner不是spring默认的扫描包. Spring默认的扫描包不是这个scanner对象, 而是自己new的一个ClassPathBeanDefinitionScanner, Spring在执行后置处理器ConfigurationClassPostProcessor时, 去扫描包时会new一个ClassPathBeanDefinitionScanner, 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法, 通过调用context.scan("package name");扫描处理配置类

比如,我们可以这样使用

    public static void main(String[] args) {
// 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
context.scan("package name");
Car car = (Car) context.getBean("car");
System.out.println(car.getName());
context.close();
}

首先调用了ClassPathBeanDefinitionScanner(this) 构造方法, 然后调用registerDefaultFilter注册摩尔恩的过滤器, 这里面默认的过滤器有两种: javax.annotation.ManagedBean 和 javax.inject.Named. 同时隐含的会注册所有带有@Component @Repository @Controller关键字的注解

    @SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}

在ClassPathBeanDefinitionScanner中, 有一个非常重要的方法, 就是doScan(String ....beanPackages). 用来扫描传入的配置文件.

五.  注册配置方法

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 进入构造函数, 首先调用自身的构造方法this();
// 调用自身的构造方法之前, 要先调用父类的构造方法
this();
// register配置注册类
register(componentClasses);
// ioc容器shua新接口--非常重要
refresh();
}

这是AnnotationConfigApplicationContext方法的构造函数, 里面第二步调用了register()方法.

  private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) { // 将入参beanClass构建成AnnotatedGenericBeanDefinition对象
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
} 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);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
} BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);用来加载bean元数据中的注解

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);用来注册bean定义. 经过一些列的教研, 没有问题, 然后将其让入到this.beanDefinitionMap.put(beanName, beanDefinition);中
具体做了哪些工作, 可以看看上面的结构图

 六. Refresh() -- spring ioc容器刷新方法

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 进入构造函数, 首先调用自身的构造方法this();
// 调用自身的构造方法之前, 要先调用父类的构造方法
this();
// register配置注册类
register(componentClasses);
// ioc容器shua新接口--非常重要
refresh();
}

refresh()方法, spring有很多衍生品, 比如spring mvc ,spring boot, 都有这个方法. refresh()里面定义了spring ioc中bean加载的全过程.

    @Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新上下文环境
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
//2. 获取告诉子类初始化bean工厂, 不同工厂不同实现
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
//3. 对bean工厂进行填充属性
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
// 4. 留个子类去实现该接口
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
/*
* 调用bean工厂的后置处理器
* 1. 会再次class扫描成BeanDefinition
*/
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
// 注册bean后置处理器
registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
// 初始化国际化资源处理器
initMessageSource(); // Initialize event multicaster for this context.
// 创建事件多播放器
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
// 这个方法通用也是留个子类实现的, spring boot也是从这个方法进行启动
onRefresh(); // Check for listener beans and register them.
// 将事件监听器注册到多播放器上
registerListeners(); // Instantiate all remaining (non-lazy-init) singletons.
// 实例化剩余的单实例bean
/**
* 这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean
*/
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
//最后容器刷新 发布刷新时间(spring cloud是从这里启动的 )
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()的源码, 在refresh()中做了很多很多事情, 我们这次主要看和ioc中beanFactory创建bean有关的部分.

一个是: invokeBeanFactoryPostProcessors(beanFactory);

另一个是: finishBeanFactoryInitialization(beanFactory);

6.1 invokeBeanFactoryPostProcessors(beanFactory) 调用BeanFactory的后置处理器

AnnotatedBeanDefinitionReader这里扫描了所有后置处理器, 将其解析到beanDefinitionMap, 在这里调用后置处理器

6.2 finishBeanFactoryInitialization 实例化剩余的单实例bean

这个方法就是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean

这里第一个是: 冻结配置类, 意思是说, 我马上就要开始制造bean了, bean配置文件不能再修改了, 所以被冻结

原理是有一个变量标记, 设为true标记冻结.

    @Override
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}

第二个是实例化创建bean

Override
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.
// 确保此时的bean已经被解析了
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
} // Prepare method overrides.
try {
/**
* 验证和准备覆盖方法(近在xml方式中)
* lookup-method 和 replace-method
* 这两个配置存放在BeanDefinition中的methodOverrides(仅在XML方式中)
* 在XML方式中, bean实例化的过程中如果检测到存在methodOverrides
* 则会动态的为当前bean生成代理并使用对应的拦截器为bean做增强处理
* 具体的实现我们后续分析. 现在先看mbdtoUse.prepareMethodOverrides()代码块
*/
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.
/**
* 初始化之前的解析
* 第一次调用bean后置处理器
* 铜鼓bean的后置处理器来进行后置处理生成代理对象, 一般情况下在此处不会生成代理对象
* 为什么不能生成代理对象? 不管是我们的JDK还是cglib代理都不会在此处进行代理, 因为我们的真实对象没有生成,
* 所以在这里不会生成代理对象
* 这一步是aop和事务的关键, 因为在这解析我们的aop切面信息进行缓存.
*/
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的三个步骤
* 1. 实例化
* 2. 填充属性, @Autowired @Value
* 3. 初始化 初始化initMethod方法和初始化destroy方法
*/
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);
}
}

创建bean的三个步骤

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) {
/**
* 第一步: 实例化
* 这里面的调用链非常深, 后面再看
* bean实例化有两种方式
* 1. 使用反射: 使用反射也有两种方式,
* a. 通过无参构造函数 (默认的方式)
* 从beanDefinition中可以得到beanClass,
* ClassName = BeanDefinition.beanclass
* Class clazz = Class.forName(ClassName);
* clazz.newInstance();
* 这样就可以实例化bean了
*
* b. 通过有参函数.
* ClassName = BeanDefinition.beanclass
* Class clazz = Class.forName(ClassName);
* Constractor con = class.getConstractor(args....)
* con.newInstance();
*
* 2. 使用工厂
* 我们使用@Bean的方式, 就是使用的工厂模式, 自己控制实例化过程
*
*/
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.
// 允许后置处理器修改已经合并的beanDefinition
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");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} // Initialize the bean instance.
Object exposedObject = bean;
try {
// 第二步:填充属性, 给属性赋值(调用set方法) 这里也是调用的后置处理器
populateBean(beanName, mbd, instanceWrapper);
// 第三步: 初始化.
exposedObject =
initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
} if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
} // Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
} return exposedObject;
}

具体结构如下:

as

2.2 spring5源码 -- ioc加载的整体流程的更多相关文章

  1. 深入理解 spring 容器,源码分析加载过程

    Spring框架提供了构建Web应用程序的全功能MVC模块,叫Spring MVC,通过Spring Core+Spring MVC即可搭建一套稳定的Java Web项目.本文通过Spring MVC ...

  2. spring5源码 -- IOC容器设计理念和核心注解的作用

    一. spring源码整体脉络介绍及源码编译 二. Spring IOC的源码深入学习 2.1 ioc容器的加载过程(重要) 2.2 bean的生命周期源码深度剖析 2.3 循环依赖总结讲解 2.4 ...

  3. jquery源码 DOM加载

    jQuery版本:2.0.3 DOM加载有关的扩展 isReady:DOM是否加载完(内部使用) readyWait:等待多少文件的计数器(内部使用) holdReady():推迟DOM触发 read ...

  4. Spring 源码学习——加载 Bean

    继上次注册 bean 之后好久没更新,这两天有空查了查资料也自己看了看 spring BeanFactory 的 getBean(beanName); 这个方法.因时间有限不能像之前那样复制代码并一行 ...

  5. Okhttp3源码解析(3)-Call分析(整体流程)

    ### 前言 前面我们讲了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析]( ...

  6. spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理

    @Configuration注解提供了全新的bean创建方式.最初spring通过xml配置文件初始化bean并完成依赖注入工作.从spring3.0开始,在spring framework模块中提供 ...

  7. Spring5源码分析(1)设计思想与结构

    1 源码地址(带有中文注解)git@github.com:yakax/spring-framework-5.0.2.RELEASE--.git Spring 的设计初衷其实就是为了简化我们的开发 基于 ...

  8. 5.2 Spring5源码--Spring AOP源码分析二

    目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...

  9. 5.2 spring5源码--spring AOP源码分析二--切面的配置方式

    目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...

随机推荐

  1. 虚拟化技术之kvm虚拟机创建工具qemu-kvm

    在前边的博客中我们介绍了如何创建kvm虚拟机,以及一些常用的工具的介绍和使用,今天我们来了解下kvm原始工具qemu-kvm:为什么说qemu-kvm是一个原始的工具呢,如果你用kvm虚拟机,心细的你 ...

  2. 解决使用git,ssh每次都要输入密码

    建议:生成ssh 公钥私钥的时候,不要输入密码. 解决方案: 1.修改密码:使用命令 ssh-keygen -p 然后修改密码的时候直接回车,也就是把密码置空. 2.重新生成ssh key, 用 ss ...

  3. Java数据结构——2-3树

    定义2-3树是平衡的3路查找树,其中2(2-node)是指拥有两个分支的节点,3(3-node)是指拥有三个分支的节点.B-树是一种平衡的多路查找树,2-3树属于b-树,其也同样具有B-树的性质,如m ...

  4. 一台主机的最大TCP连接数是多少?

    在没接触过这个问题之前,自然会想到服务器端连接数是由服务器端口号限制的.但这其实是一个很严重的误解,要解决这个问题,必须理解socket的连接过程. 以python为例,tcp服务端socket需要经 ...

  5. Node.js的基础知识点

    一,语言 和 环境(平台) 之间的关系 1,浏览器环境 中的 Javascript 浏览器中 Javascript 的组成部分 ECMAScript核心 + DOM + BOM 2,Node环境 中的 ...

  6. 报错:ER_NO_DEFAULT_FOR_FIELD: Field 'status' doesn't have a default value

    小白入门级错误,数据库插入数据时报错;ER_NO_DEFAULT_FOR_FIELD: Field 'status' doesn't have a default value  百度说是my.ini文 ...

  7. [PyTorch 学习笔记] 4.3 优化器

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson4/optimizer_methods.py https: ...

  8. Mac系统下php.ini的位置

    http://blog.csdn.net/meegomeego/article/details/25704645 /private/etc/php.ini /usr/local/etc/php/5.5 ...

  9. 解决warning MSB8012:问题

    问题描述: C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(990,5): warning M ...

  10. Shader 语义

    在书写HLSL shader程序时,输入和输出变量需要拥有他们 含义来表明语义.这在HLSL shader中是一个标准的做法. Vertex shader 输入语义 主顶点着色器函数(被指令 #pra ...