Spring源码分析(一)

目录

IOC概念

回顾

如何获取bean

如何统一交给beanFactory

beanDefinition里面参数

BeanDefinitionRegistry注册bean定义

​编辑

BeanDefinitionReader负责读取哪些文件

BeanDefiinitionScanner扫描哪些真正需要加载的类

过程

ApplicationContext和BeanFactory有什么区别

Bean的声明周期


IOC概念

IOC容器中存放很多JavaBean

回顾

回顾一下我们从刚开始用spring的时候,如何获取一个类的实例的

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Car car = context.getBean("car",Car.class);
System.out.println(car.getName());

通过配置类MainConfig.class构造了一个容器,然后获取car的实例,打印实例的属性值

我们看下最最重要的方法getBean()

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
   this.assertBeanFactoryActive();
   return this.getBeanFactory().getBean(name, requiredType);
}

如何获取bean

这里面先获取了BeanFactory,上下文不生产bean,通知beanFactory生产bea(门面模式),这个getBean(),可以获取bean也可以生产bean

BeanFactory,spring顶级核心接口,使用了简单工厂模式,负责生产bean

如何统一交给beanFactory

我们知道,有很多种配置方式来获取bean的实例,比如说注解,或者xml配置,那么到底如何从不同地方读取到的东西统一成一个东西交给beanFactory呢

那就是beanDefinition,bean定义

beanDefinition里面参数

bean的生产方式全都封装在bean定义里面

BeanDefinitionRegistry注册bean定义

BeanDefinitionReader负责读取哪些文件

对配置类或者xml

BeanDefiinitionScanner扫描哪些真正需要加载的类

过程

首先通过BeanDefinitionReader去读取xml文件,比如去扫描哪个包,然后通过BeanDefinitionScanner去扫描那些真正需要加载的类,比如@Component所标注的类,然后找到这些类之后,通过BeanDefinitionRegistry加这些类加载成BeanDefinition,放到beanDefinitionMap里面,beanDefinitionMap交给BeanFactory,然后通过不断地循环,去获取beanDefinition,经过bean的生命周期,将key(beanName)-value(实例)放入到map中

ApplicationContext和BeanFactory有什么区别

ApplicationContext是BeanFactory下面的子类,肯定都有生产bean的能力

BeanFactory只有一个职责就是生产bean,只能进行bean定义,但是ApplicationContext实现了很多类,具备很多功能,可以指定具体扫哪个配置类,管理bean的整个声明周期,事件,国际化,读取资源文件,都为了更好服务类,将类注册成beanDefinition,只有ApplicationContext有read、scanner、registry这个能力

Bean的声明周期

BeanDefinition里面定义了类,通过反射实例化,这个时候是没有属性的,通过@Autowired @value填充属性,然后再初始化,这个时候bean基本成形,然后放到map里面,key为beanName,value是bean的实例,这个map俗称单例池,或者一级缓存

填充属性时,产生循环依赖

循环依赖产生的原因,两个bean对象,互相包含需要注入对方bean对象的属性,这样互相依赖导致循环依赖,当加载a的时候,里面包含b属性,这个时候需要加载b这个实例,加载b的时候,发现需要加载a这个对象,这样就产生了循环依赖

如何解决:spring已经解决了,通过三级缓存(就是三个map)解决的,大体是你创建a的时候,依赖b的属性,开始创建b,创建b的时候,发现依赖a的属性,开始创建a,发现a已经正在创建了就直接出去

实例化

主要有两种方式:反射和工厂,工厂就是new对象然后属性赋值 

反射,示例就是用注解生成示例,而工厂,示例就是通过@Bean注解,在方法里面进行属性赋值生成实例 

修改beanDefinition

BeanFactoryPostProcessor,实现这个接口的类,可以对bean定义进行修改,大概逻辑就是通过获取beanDefinition,对里面属性进行修改

注册bean定义

每注册一个bean定义就是创建一个bean对象,BeanDefinitionRegistryPostProcessor 总结:

先将类加载成bean定义,先通过BeanDefinitinoReader读取配置类,然后BeanDefinitionScanner扫描符合的类,然后注册成bean定义,然后ApplicationContext可以调用BeanFactoryPostProcessor修改bean定义,还可以调用BeanDefinitionRegistryPostProcessor去注册bean定义,然后通过beanFactory去getBean,getBean可以去创建以及获取bean对象,创建这个过程中包括实例化,填充属性,初始化,中间穿插BeanPostProcessor和各种Aware,然后创建完成之后,放到map里面

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值