首先本次分析是基于注解形式的,想来xml格式的原理都是类似的。

首先说一下什么是Bean定义(beandefinition):bean定义并不是实例化的bean,而是bean对象的一些信息,根据这些定义的信息最后来初始化bean。比方说就是一些类的信息,还有我们配置的该实例的信息(是否懒加载,单例还是多例,作用域等等信息)。

进入正题:

AnnotationConfigApplicationContext构造方法传入一个主配置类,那么就从该构造方法进去。

一、我们先来看在容器刷新(refresh())之前,都干了什么

1.this()首先会调用无参构造,进而调用父类的无参构造,初始化beanFactory(DefaultListableBeanFactory),再者初始化注解模式下的bean定义读取器,classPath类型的bean定义扫描器;

2.register(annotatedClasses),基于上面初始化的bean定义读取器去解析注册我们自己的配置类信息到容器中。

具体的流程图如下:

完成了这些准备工作。refresh()里面就会实例化具体的bean了。

二、两个个扩展点

1. BeanDefinitionRegistryPostProcessor

Bean定义处理器,在注册bean定义的时候调用,可以自己注册新的bean定义

先直接通过上下文对象获取一个student,会报错,没有对应的bean定义

实现自己的Bean定义处理器

MyBeanDefinitionRegistryPostProcessor
package com.nijunyang.spring;

import com.nijunyang.spring.model.Student;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component; /**
* @author: create by nijunyang
* @date:2019/10/6
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
//bean定义注册处理器,在注册bean定义的时候调用,可以自己注册新的bean定义,比如Student
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("bean定义的数据量:"+registry.getBeanDefinitionCount());
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Student.class);
//注册一个名为student的bean定义进去
registry.registerBeanDefinition("student", rootBeanDefinition);
System.out.println("bean定义的数据量:"+registry.getBeanDefinitionCount());
} @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { }
}

注意需要加上@Component,并且主配置指定扫描的包将自己定义的类加载进去

MainConfig
package com.nijunyang.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
* @author: create by nijunyang
* @date:2019/10/6
*/
@Configuration
@ComponentScan(basePackages = "com.nijunyang.spring")
public class MainConfig {
}

正常获取bean。

2.BeanFactoryPostProcessor

BeanFactory后置处理器,注册了bean定义之后调用,可以修改bean定义,比如实现一个自己的BeanFactory后置处理器,把某个bean设置成懒加载。

断点运行1步骤中的代码,发现student不是懒加载的

实现自己的BeanFactory后置处理器,将student设置成懒加载

MyBeanFactoryPostProcessor
package com.nijunyang.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component; /**
* @author: create by nijunyang
* @date:2019/10/6
*/
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
//注册了bean定义之后调用,可以修改bean定义,比如把student设置成懒加载
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for(String name : beanFactory.getBeanDefinitionNames()) {
if("student".equals(name)) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
beanDefinition.setLazyInit(true);
} }
}
}

同样断点运行,发现student不会马上被初始化了

Spring IOC(1)----容器刷新(refresh())之前的更多相关文章

  1. 【Spring】容器刷新(refresh)流程解析

    一.概述 二.prepareRefresh() 三.obtainFreshBeanFactory() 四.prepareBeanFactory(beanFactory); 五.postProcessB ...

  2. [转]Spring IOC父子容器简介

    通过HierarchicalBeanFactory接口,Spring的IoC容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的Bean,但父容器不能访问子容器的Bean.在容器内,Bean的 ...

  3. Spring IOC之容器扩展点

    一般来说,一个应用开发者不需要继承ApplicationContext实现类.取而代之的是,Spring IoC容器可以通过插入特殊的整合接口的实现来进行扩展.下面的几点将要讲述这些整合的接口. 1. ...

  4. Spring IOC之容器概述

    1.SpringIOC容器和beans介绍 IOC的依赖注入是这样的,对象定义他们的依赖也就是他们需要在一起起作用的对象是通过构造器参数以及工厂方法的参数或者是当他们被构建或者是从工厂中返回时设置在对 ...

  5. Spring IOC 低级容器解析

    1.IOC是什么 IOC-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不 ...

  6. Spring IOC 一——容器装配Bean的简单使用

    下文:SpringIOC 二-- 容器 和 Bean的深入理解 写在前面 这篇文章去年写的,缘起于去年某段时间被领导临时"抓壮丁"般的叫过去做java开发,然后在网上找了一个 Sp ...

  7. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  8. Spring(2)——Spring IoC 详解

    Spring IoC 概述 IoC:Inverse of Control(控制反转) 读作"反转控制",更好理解,不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控 ...

  9. Spring IoC 详解(四)

    Spring IoC 概述 IoC:Inverse of Control(控制反转) 为了更好的理解用可以这样通俗易懂的这样讲:IOC主要是说是new一个类来使用,方式分为:开发这手动创建和Sprin ...

  10. Spring IOC 相关的面试题

    Spring最基础的部分就是IOC,对IOC的理解程度从某个方面代表着你对Spring  的理解程度,看了网上的一些面试题,针对Spring IOC相关的重点是下面几个: 1.Spring中Bean ...

随机推荐

  1. Fire Balls 05——子弹的命中及后续效果

    版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...

  2. WebApi使用OAuth2认证

    本篇文章实现了四种认证方式中的客户端模式和密码模式,未实现token持久化 未介绍OAuth2的相关概念,全部是干货,可自己在网上搜索OAuth2相关知识,在这不做过多阐述 一.引用OAuth2所需的 ...

  3. 【JavaScript】吃饱了撑的系列之JavaScript模拟多线程并发

    前言 最近,明学是一个火热的话题,而我,却也想当那么一回明学家,那就是,把JavaScript和多线程并发这两个八竿子打不找的东西,给硬凑了起来,还写了一个并发库concurrent-thread-j ...

  4. android CTS 命令

    > h //help Host:  help: show this message  help all: show the complete tradefed help  exit: grace ...

  5. 文档打印 js print调用打印dom内容

    1.首先按目前研究 print可以打印dom 2.被设置overflow:hidden 的模块,打印时会被截掉. 3.被设置成 display:none 的dom 打印不会有样式 边框等. 4.如果需 ...

  6. Python---列表的学习(二)

    列表的第二部分 (1)列表的排序 1)使用方法sort()可对列表进行永久性排序 food = ['apple','orange','pear','grape'] food.sort() print( ...

  7. 【Offer】[21] 【调整数组顺序使奇数位于偶数前面】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,(偶数之间和奇数 ...

  8. MD5字符串加密

    MD5字符串加密 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 132 ...

  9. Maven学习归纳(二)——几个常用命令解析

    Maven的常用命令 第一次执行命令的时候,因为需要下载执行命令的基础环境,所以会从远程仓库下载该环境到本地仓库中 运行mvn命令,必须在pom.xml文件所在的目录 一. JavaProject的p ...

  10. java架构之路-(11)JVM的对象和堆

    上次博客,我们说了jvm运行时的内存模型,堆,栈,程序计数器,元空间和本地方法栈.我们主要说了堆和栈,栈的流程大致也说了一遍,同时我们知道堆是用来存对象的,分别年轻代和老年代.但是具体的堆是怎么来存放 ...